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

微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言

如果对您有所帮助:欢迎赞赏

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

内容目录

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

1.实现效果

时钟实时展示系统本机时间

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 的微信公众号,本站会及时推送最新技术文章


C# WPF 时钟动画(2/2)的更多相关文章

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

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF 时钟动画(1/2) 内容目录 实现效果 业务场景 编码实现 本文参考 源码下载 ...

  2. WPF利用动画实现圆形进度条

    原文:WPF利用动画实现圆形进度条 这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到 ...

  3. WPF弹性模拟动画

    原文:WPF弹性模拟动画 我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的. 胡克定律:F=-kd F代表弹性 ...

  4. WPF控制动画开始、停止、暂停和恢复

    1.闲言 好久也没更新一博客了,自己有点发懒,同时确实这几个月来也有点忙.风机监测软件,项目中,有这样一个小需求:正常风机在旋转的时候,上位机软要做一个风机的图片,让它不停地旋转,一但检测到下面风机停 ...

  5. 使用Canvas制作时钟动画

    复习Javascript到Canvas的知识点,看到一个使用Canvas绘制的静态时钟例子,便想将其变成动态显示系统时间的时钟动画.另外再配上数字显示的时钟,一个小的时钟模块的诞生了!目前的界面还比较 ...

  6. 15个超强悍的CSS3圆盘时钟动画赏析

    在网页上,特别是个人博客中经常会用到时钟插件,一款个性化的时钟插件不仅可以让页面显得美观,而且可以让访客看到当前的日期和时间.今天我们给大家收集了15个超强悍的圆盘时钟动画,很多都是基于CSS3,也有 ...

  7. Wpf(Storyboard)动画简单实例

    原文:Wpf(Storyboard)动画简单实例 动画的三种变换方式 RotateTransform:旋转变换变化值:CenterX围绕转的圆心横坐标 CenterY纵坐标 Angle旋转角度(角度正 ...

  8. iOS中的时钟动画

    iOS 动画效果非常多,我们在开发中可能会遇到很多动画特效,我们就会用到核心动画框架CoreAnimation,核心动画里面的动画效果有很多,都是在QuartzCore.framework框架里面,今 ...

  9. 14款超时尚的HTML5时钟动画

    时钟动画在网页应用中也非常广泛,在一些个人博客中,我们经常会看到一些相当个性化的HTML5时钟动画.今天我们向大家分享了14款形态各异的超时尚HTML5时钟动画,其中有圆盘时钟.3D时钟.个性化时钟等 ...

随机推荐

  1. window nginx 中文路径, 文件名乱码问题解决

    window nginx 中文路径, 文件名乱码, error, not found 此问题是由于windows系统编码与nginx编码设置不一致导致的,因此我们要统一二者的编码 nginx编码设置 ...

  2. Exception:Request processing failed; nested exception is org.apache.ibatis.binding.BindingException

    异常 在测试Spring MVC+Mybatis整合时,运行 Maven build -> tomcat7:Run 遇到如下异常 从异常信息上看,是找不到mapper对应的xml文件,于是我到t ...

  3. SASS用法入门

    本文参考了 阮一峰 老师对 SASS 用法的讲解. 学过 CSS 的人都知道,它不是一种编程语言,在日常的开发中,经常要写大量的 css 代码,有很多的重复代码,效率很低.Sass 是一个 CSS 的 ...

  4. Hadoop-3.1.2安装步骤

    Hadoop-3.1.2 安装步骤 第一步  准备 服务器配置 1.  在VMware中安装把Centos7安装成功后,需要把界面设置为命令行启动,因为默认的启动方式是图形界面启动 systemctl ...

  5. 使用alpine制作最小化的JDK基础镜像

    注意:这里使用的是oracle的JRE,版本是1.8. 1.解压jre包,删除根目录下文本文件,然后删除其他不必要文件. #解压 tar xvcf jre-8u161-linux-x64.tar.gz ...

  6. 链表基本操作与排序(c语言)

    本设计程序用C编写,完成单链表的生成,任意位置的插入.删除,以及确定某一元素在单链表中的位置.实现三种排序算法-冒泡排序.快速排序.合并排序.产生四个长度为100,1000,10000,50000的随 ...

  7. The current test process

    样机测试 测试前: 工作内容: 1.需求分析.编写.评审: 项目开工会由项目负责人参加,参加会议时做好笔记,对项目的功能类似,功能模块,测试时间点有个大致的了解. 原始需求进行需求文档细化:按照模块进 ...

  8. pyspark 记录

    import os import sys spark_name = os.environ.get('SPARK_HOME',None) if not spark_name: raise ValueEr ...

  9. HDU_2510_打表

    http://acm.hdu.edu.cn/showproblem.php?pid=2510 dfs打表. #include<iostream> #include<cstdio> ...

  10. SpringBoot配置文件的加载优先级顺序

    application.properties加载 Spring Boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring Boot ...