WPFのアニメーション機能を使い針を滑らかに動かすアナログ時計を作成する
はじめに
「WPFのDispatcherTimerクラスを使い簡易アナログ時計を作成する」でDispatcherTimerを使った簡易アナログ時計のサンプルコードを掲載しましたが、こちらは、WPFのアニメーション機能を使った簡易アナログ時計のサンプルです。
実行例
画像ではわかりませんが、秒針が滑らかに動きます。
処理の概要
概要は以下のとおり。
- 秒針、分針、時針の3つをLineオブジェクトとして表す。
- 3つのLineオブジェクトの、RenderTransformプロパティには、RotateTransformを設定する。
- 秒針、分針、時針に対応する Storyboard を定義する。
- Storyboardでは、上記RotateTransformの回転角度を変化させることでそれぞれの針を動かす。
- WindowのLoad時に、3つの針の角度を初期化し、アニメーションを開始する。
XAML
XAMLを示します。
Storyboardを3つ定義しているので、XAMLの行数が多めですが、ひとつひとつの要素はそれほど複雑ではありません。
<Window x:Class="WpfAnalogClock2.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:WpfAnalogClock2"
mc:Ignorable="d"
Title="Clock" Height="260" Width="260"
Loaded="Window_Loaded" >
<Window.Resources>
<Storyboard x:Key="SecondHand" x:Name="SecondHand" RepeatBehavior="Forever" >
<DoubleAnimation
Duration="0:1:0" From="0" To="360"
Storyboard.TargetName="SecondLine"
Storyboard.TargetProperty="(Line.RenderTransform).(RotateTransform.Angle)"
/>
</Storyboard>
<Storyboard x:Key="MinuteHand" x:Name="MinuteHand" RepeatBehavior="Forever">
<DoubleAnimation
Duration="1:0:0" From="0" To="360"
Storyboard.TargetName="MinuteLine"
Storyboard.TargetProperty="(Line.RenderTransform).(RotateTransform.Angle)"
/>
</Storyboard>
<Storyboard x:Key="HourHand" x:Name="HourHand" RepeatBehavior="Forever">
<DoubleAnimation
Duration="12:0:0" From="0" To="360"
Storyboard.TargetName="HourLine"
Storyboard.TargetProperty="(Line.RenderTransform).(RotateTransform.Angle)"
/>
</Storyboard>
</Window.Resources>
<Canvas Width="200" Height="200">
<Line x:Name="HourLine" Stroke="Black" Fill="Black"
X1="100" Y1="100" X2="100" Y2="35"
StrokeThickness="3" >
<Line.RenderTransform>
<RotateTransform x:Name="AngleHour" Angle="0"
CenterX="100" CenterY="100"/>
</Line.RenderTransform>
</Line>
<Line x:Name="MinuteLine" Stroke="Black" Fill="Black"
X1="100" Y1="100" X2="100" Y2="15"
StrokeThickness="2" >
<Line.RenderTransform>
<RotateTransform x:Name="AngleMinute" Angle="0"
CenterX="100" CenterY="100"/>
</Line.RenderTransform>
</Line>
<Line x:Name="SecondLine" Stroke="Black" Fill="LightGray"
X1="100" Y1="120" X2="100" Y2="10" >
<Line.RenderTransform>
<RotateTransform x:Name="AngleSecond" Angle="0"
CenterX="100" CenterY="100"/>
</Line.RenderTransform>
</Line>
<Ellipse Fill="Black" Width="6" Height="6" HorizontalAlignment="Center"
VerticalAlignment="Center"
Canvas.Top="97" Canvas.Left="97"/>
</Canvas>
</Window>
C#のコード
C#側もいたって簡単なコードです。
現在の時刻に合せて、それぞれの針の初期の角度を設定し、これをFromの角度とし、Toはそれに360度を加えた角度とします。Durationは、XAMLで設定した値を使います。これでアニメーションをスタートさせています。
たったこっれだけで秒針が滑らかに動くアナログ時計が実現できるのはちょっとした驚きです。
using System;
using System.Windows;
using System.Windows.Media.Animation;
namespace WpfAnalogClock2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeAngle();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
StartAnimation("HourHand", this.AngleHour.Angle);
StartAnimation("MinuteHand", this.AngleMinute.Angle);
StartAnimation("SecondHand", this.AngleSecond.Angle);
}
void InitializeAngle()
{
DateTime dt = DateTime.Now;
this.AngleSecond.Angle = dt.Second * 360.0 / 60.0;
this.AngleMinute.Angle = (dt.Minute + dt.Second / 60.0) * 360.0 / 60.0;
this.AngleHour.Angle = (dt.Hour + dt.Minute / 60.0) * 360.0 / 12;
}
private void StartAnimation(string name, double angle)
{
var sb = this.Resources[name] as Storyboard;
var da = sb.Children[0] as DoubleAnimation;
da.From = angle;
da.To = da.From + 360.0;
sb.Begin();
}
}
}
ソースコードは、GitHubでも公開しています。
Author And Source
この問題について(WPFのアニメーション機能を使い針を滑らかに動かすアナログ時計を作成する), 我々は、より多くの情報をここで見つけました https://qiita.com/gushwell/items/60ce3d37befccea634b2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .