以下は、WPF での小さなグラフィック デモです。次のようになります。
実行中にウィンドウのメイン領域でマウスを動かすと、アニメーションの速度が低下します (少なくとも私のシステムでは)。マウス ポインターをウィンドウの外に完全に移動すると、アニメーションが元の速度に戻ります。
マウスの動きがアニメーションの速度に干渉するのを防ぐ方法について何か提案はありますか?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
namespace WPF_Golden_Section
{
class DrawingVisualElement : FrameworkElement
{
public DrawingVisual visual;
public DrawingVisualElement() { visual = new DrawingVisual(); }
protected override int VisualChildrenCount { get { return 1; } }
protected override Visual GetVisualChild(int index) { return visual; }
}
public static class CanvasUtils
{
public static Canvas SetCoordinateSystem(this Canvas canvas, Double xMin, Double xMax, Double yMin, Double yMax)
{
var width = xMax - xMin;
var height = yMax - yMin;
var translateX = -xMin;
var translateY = height + yMin;
var group = new TransformGroup();
group.Children.Add(new TranslateTransform(translateX, -translateY));
group.Children.Add(new ScaleTransform(canvas.ActualWidth / width, canvas.ActualHeight / -height));
canvas.RenderTransform = group;
return canvas;
}
}
public static class ColorUtils
{
public static Color Write(this Color color)
{
Console.Write("Color[{0} {1} {2} {3}]", color.A, color.R, color.G, color.B);
return color;
}
static byte ColorComponentToByte(double n)
{
return
(byte)
Math.Round(Math.Min(Math.Max(n, 0), 1) * 255);
}
public static Color Rgb(double r, double g, double b)
{
return
Color.FromRgb(
ColorComponentToByte(r),
ColorComponentToByte(g),
ColorComponentToByte(b));
}
public static Color SetArgb(this Color color, double a, double r, double g, double b)
{
color.A = ColorComponentToByte(a);
color.R = ColorComponentToByte(r);
color.G = ColorComponentToByte(g);
color.B = ColorComponentToByte(b);
return color;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Width = 600;
Height = 600;
var dockPanel = new DockPanel();
Content = dockPanel;
var slider =
new Slider()
{
Minimum = 0.1,
Maximum = 10,
LargeChange = 0.001,
Value = 1
};
dockPanel.Children.Add(slider);
DockPanel.SetDock(slider, Dock.Top);
var incrementSlider =
new Slider()
{
Maximum = 0.001,
Minimum = 0.00001,
Value = 0.0001
};
dockPanel.Children.Add(incrementSlider);
DockPanel.SetDock(incrementSlider, Dock.Top);
var pauseButton = new Button() { Content = "Pause" };
dockPanel.Children.Add(pauseButton);
DockPanel.SetDock(pauseButton, Dock.Top);
var canvas = new Canvas();
dockPanel.Children.Add(canvas);
DockPanel.SetDock(canvas, Dock.Top);
SizeChanged += (s, e) => canvas.SetCoordinateSystem(-400, 400, -400, 400);
var element = new DrawingVisualElement();
Action draw = () =>
{
canvas.Children.Clear();
// var element = new DrawingVisualElement();
using (var dc = element.visual.RenderOpen())
{
for (var i = 0.0; i < 720.0; i += slider.Value)
{
var radius = Math.Sin(i / 720.0 * Math.PI) * 30;
var phi = (1 + Math.Sqrt(5)) / 2;
var omega = 2 * Math.PI * (phi - 1) * i;
var x = Math.Cos(omega) * 0.5 * i;
var y = Math.Sin(omega) * 0.5 * i;
dc.DrawEllipse(
new SolidColorBrush(ColorUtils.Rgb(i / 360.0, i / 360.0, 0.25)),
new Pen(Brushes.Black, Math.Max(radius / 6, 1)),
new Point(x, y),
radius / 2,
radius / 2);
}
}
canvas.Children.Add(element);
};
slider.ValueChanged += (s, e) =>
{
Title = slider.Value.ToString() + " " + incrementSlider.Value;
draw();
};
var timer = new DispatcherTimer();
timer.Tick += (s, e) =>
{
if (slider.Value < 10.0)
slider.Value += incrementSlider.Value;
};
timer.Start();
pauseButton.Click += (s, e) =>
{
if (timer.IsEnabled)
timer.Stop();
else
timer.Start();
};
slider.Value = 3.5;
incrementSlider.Value = 0.00001;
}
}
}