zoukankan      html  css  js  c++  java
  • C# WPF 时钟动画(2/2)

    模拟实现时钟效果,学习WPF动画好例子,本文承接上文 C# WPF 时钟动画(1/2)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言
    如果对您有所帮助:欢迎赞赏

    C# WPF 时钟动画(2/2)

    内容目录

    1. 实现效果
    2. 业务场景
    3. 编码实现
    4. 本文参考
    5. 源码下载

    1.实现效果

    时钟实时展示系统本机时间
    C# WPF时钟

    2.业务场景

    模拟时钟

    3.编码实现

    使用 .Net Core 3.1 创建名为 “Clock” 的WPF解决方案,解决方案中需要添加时钟背景图片,图片如下:https://github.com/Abel13/Clock/blob/master/Clock/Assets/clock.png

    3.1 主窗体 MainWindow.xaml

    使用3个Border布局时钟的时针、分针、秒针,并给3个指针添加动画,动画说明如下:

    1. 时针每12个小时循环一圈(360°),每个小时旋转30°(30°*12=360°);
    2. 分针每60分钟循环一圈(360°),每分钟旋转6°(6°*60=360°);
    3. 秒针每60秒循环一圈(360°),每秒钟旋转6°(6°*60=360°),并且秒针旋转6°有个轻微的摆动动画。
    <Window x:Class="Clock.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Clock"
            mc:Ignorable="d"
            AllowsTransparency="True" WindowStyle="None" ResizeMode="NoResize"
            Height="520" Width="520" WindowStartupLocation="CenterScreen" Background="{x:Null}">
        <Window.Resources>
            <Storyboard x:Key="sbseconds" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="second" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
                    <EasingDoubleKeyFrame KeyTime="0" Value="-90">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:1" Value="-84">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:2" Value="-78">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:3" Value="-72">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:4" Value="-66">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:5" Value="-60">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:6" Value="-54">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:7" Value="-48">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:8" Value="-42">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:9" Value="-36">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:10" Value="-30">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:11" Value="-24">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:12" Value="-18">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:13" Value="-12">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:14" Value="-6">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:15" Value="0">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:16" Value="6">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:17" Value="12">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:18" Value="18">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:19" Value="24">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:20" Value="30">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:21" Value="36">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:22" Value="42">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:23" Value="48">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:24" Value="54">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:25" Value="60">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:26" Value="66">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:27" Value="72">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:28" Value="78">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:29" Value="84">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="00:00:30" Value="90">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.4"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard Storyboard="{StaticResource sbseconds}"/>
            </EventTrigger>
        </Window.Triggers>
        <Grid>
            <Border BorderThickness="10" BorderBrush="Black" CornerRadius="300" Width="520" Height="520">
                <Grid Height="500" Width="500" HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Border CornerRadius="350">
                        <Border.Background>
                            <ImageBrush ImageSource="Assets/clock.png"/>
                        </Border.Background>
                    </Border>
    
                    <Border CornerRadius="350" Background="#778889BB"/>
    
                    <Border x:Name="hour" CornerRadius="0 15 15 0" Height="10" Width="130" BorderThickness="3" BorderBrush="#FF66B01C" Margin="0,245,120,245" HorizontalAlignment="Right" RenderTransformOrigin="0,0.5">
                        <Border.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform Angle="-90"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </Border.RenderTransform>
                    </Border>
                    <Border x:Name="minute" CornerRadius="0 15 15 0" Height="5" Width="160" BorderThickness="3" BorderBrush="#FFD15209" Margin="250.5,247,0,248" HorizontalAlignment="Left" RenderTransformOrigin="0,0.5">
                        <Border.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform Angle="-90"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </Border.RenderTransform>
                    </Border>
                    <Border x:Name="second" CornerRadius="0 15 15 0" Height="3" Width="220" Background="Red" Margin="0,248,30,248" HorizontalAlignment="Right" RenderTransformOrigin="0,0.5">
                        <Border.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform Angle="-90"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </Border.RenderTransform>
                    </Border>
                    <Ellipse Fill="Black" Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </Border>
        </Grid>
    </Window>
    

    3.2 MainWindow.xaml.cs

    后台代码开启三个指针动画,并设置各指针动画起始位置

    using System;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media.Animation;
    
    namespace Clock
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                int now_hours = DateTime.Now.Hour > 12 ? (DateTime.Now.Hour - 12) : DateTime.Now.Hour;
                int now_minutes = DateTime.Now.Minute;
                int now_seconds = DateTime.Now.Second;
    
                Storyboard seconds = (Storyboard)second.FindResource("sbseconds");
                seconds.Begin();
                seconds.Seek(new TimeSpan(0, 0, 0, now_seconds, 0));
    
                Storyboard minutes = (Storyboard)minute.FindResource("sbminutes");
                minutes.Begin();
                minutes.Seek(new TimeSpan(0, 0, now_minutes, now_seconds, 0));
    
                Storyboard hours = (Storyboard)hour.FindResource("sbhours");
                hours.Begin();
                hours.Seek(new TimeSpan(0, now_hours, now_minutes, now_seconds, 0));
            }
    
            private void Window_MouseDown(object sender, MouseButtonEventArgs e)
            {
                DragMove();
            }
        }
    }
    

    4.本文参考

    Design com WPF 大神的学习视频:

    1/2 - Creating a clock with Animations

    2/2 - Creating a clock with Animations

    5.代码下载

    源码中实现了全部效果,大伙可以直接下载编译运行;建议看大神视频手敲一遍,加深学习印象;视频中使用Blend布局时钟、设置动画,类似PS(PhotoShop),设计界面很是方便的。

    Github源码下载:Clock

    除非注明,文章均由 Dotnet9 整理发布,欢迎转载。

    转载请注明本文地址:https://dotnet9.com/6858.html

    欢迎扫描下方二维码关注 Dotnet9 的微信公众号,本站会及时推送最新技术文章

    Dotnet9

  • 相关阅读:
    洛谷P2516 [HAOI2010]最长公共子序列 动态规划 容斥原理
    [LeetCode]235. Lowest Common Ancestor of a Binary Search Tree
    [LeetCode]144. Binary Tree Preorder Traversal二叉树前序遍历
    [LeetCode]129. Sum Root to Leaf Numbers路径数字求和
    [leetcode]645. Set Mismatch
    [leetcode]110BalancedBinaryTree平衡二叉树
    [leetcode]199. Binary Tree Right Side View
    [LeetCode]116. Populating Next Right Pointers in Each Node
    [leetcode]720. Longest Word in Dictionary字典中最长的单词
    [LeetCode]690. Employee Importance员工重要信息
  • 原文地址:https://www.cnblogs.com/Dotnet9-com/p/12166918.html
Copyright © 2011-2022 走看看