ここでは、同じようなアニメーションを、DispatcherTimer を使って実現しています。
DispatcherTimer の Tick イベントの処理で直接 UIスレッドにアクセスできるので、「飛び跳ねるボール」で使ったような座標通知用のメッセージクラス(Location クラス)は必要ありません。
15ミリ秒ごとに処理される timer_Tickメソッドで、3つの円の中心座標、EllipseGeometry.Center を書き換えています。
MainWindow.xaml
<Window x:Class="BouncingBall.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="300"
SizeChanged="Window_SizeChanged" Loaded="Window_Loaded">
<Canvas Name="canvas1">
<Canvas.Resources>
<Style TargetType="Path">
<Setter Property="Fill" Value="WhiteSmoke"/>
<Setter Property="Stroke" Value="Black"/>
</Style>
</Canvas.Resources>
<Path>
<Path.Data>
<EllipseGeometry x:Name="ellipse1" RadiusX="5" RadiusY="5" />
</Path.Data>
</Path>
<Path Opacity=".5">
<Path.Data>
<EllipseGeometry x:Name="ellipse2" RadiusX="5" RadiusY="5" />
</Path.Data>
</Path>
<Path Opacity=".2">
<Path.Data>
<EllipseGeometry x:Name="ellipse3" RadiusX="5" RadiusY="5" />
</Path.Data>
</Path>
</Canvas>
</Window>
MainWindow.xaml.cs
using System;using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;
namespace BouncingBall
{
public partial class MainWindow : Window
{
private int rateY = 1200;
private int rateX = 1000;
private double rateY2;
private int harfRateY;
private double rateX2;
private int harfRateX;
private Stopwatch sw = new Stopwatch();
public MainWindow()
{
InitializeComponent();
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
rateY2 = rateY / Math.Sqrt(this.canvas1.ActualHeight) * 0.52;
harfRateY = rateY / 2;
rateX2 = rateX / this.canvas1.ActualWidth * 0.55;
harfRateX = rateX / 2;
sw.Restart();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 0, 0, 15);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
if (!sw.IsRunning)
{
return;
}
long milliseconds = sw.ElapsedMilliseconds;
this.ellipse1.Center = GetPoint(milliseconds);
this.ellipse2.Center = GetPoint(milliseconds - 50);
this.ellipse3.Center = GetPoint(milliseconds - 100);
}
private Point GetPoint(long milliseconds)
{
if (milliseconds < 0)
{
milliseconds = 0;
}
long fractionY = milliseconds % rateY;
if (fractionY >= harfRateY)
{
fractionY = rateY - fractionY;
}
double sqrtY = fractionY / rateY2;
double y = sqrtY * sqrtY;
long fractionX = milliseconds % rateX;
if (fractionX >= harfRateX)
{
fractionX = rateX - fractionX;
}
double x = fractionX / rateX2;
return new Point(x, y);
}
}
}
0 件のコメント:
コメントを投稿