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

  • 相关阅读:
    POJ 2752 Seek the Name, Seek the Fame
    POJ 2406 Power Strings
    KMP 算法总结
    SGU 275 To xor or not to xor
    hihocoder 1196 高斯消元.二
    hihoCoder 1195 高斯消元.一
    UvaLive 5026 Building Roads
    HDU 2196 computer
    Notions of Flow Networks and Flows
    C/C++代码中的笔误
  • 原文地址:https://www.cnblogs.com/Dotnet9-com/p/12166918.html
Copyright © 2011-2022 走看看