C# WPF 时钟动画(2/2)
程序员文章站
2022-04-06 10:51:05
模拟实现时钟效果,学习WPF动画好例子,本文承接上文 "C WPF 时钟动画(1/2)" 。 微信公众号: "Dotnet9" ,网站: "Dotnet9" ,问题或建议: "请网站留言" , 如果对您有所帮助: "欢迎赞赏" 。 C WPF 时钟动画(2/2) 内容目录 1. 实现效果 2. 业务 ......
模拟实现时钟效果,学习wpf动画好例子,本文承接上文 c# wpf 时钟动画(1/2)。
c# wpf 时钟动画(2/2)
内容目录
- 实现效果
- 业务场景
- 编码实现
- 本文参考
- 源码下载
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个指针添加动画,动画说明如下:
- 时针每12个小时循环一圈(360°),每个小时旋转30°(30°*12=360°);
- 分针每60分钟循环一圈(360°),每分钟旋转6°(6°*60=360°);
- 秒针每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 整理发布,欢迎转载。
转载请注明本文地址:
欢迎扫描下方二维码关注 dotnet9 的微信公众号,本站会及时推送最新技术文章