实现效果:此方框实现每帧改变一次颜色canvas
private readonly Random _rand = new Random(); public SimpleExample() { CompositionTarget.Rendering += UpdateColor; } private void UpdateColor(object sender, EventArgs e) { // Set a random color animatedBrush.Color = Color.FromRgb((byte) _rand.Next(255), (byte) _rand.Next(255), (byte) _rand.Next(255)); }
在Page每帧呈现的方法中获取当前方框的坐标与当前鼠标坐标差量值,设置每帧方框往鼠标点移动一点点距离。造成方框慢慢跟随到鼠标的效果。缓存
public partial class FollowExample : Page
{dom
private Point _lastMousePosition = new Point(0, 0); private Vector _rectangleVelocity = new Vector(0, 0); public FollowExample() { CompositionTarget.Rendering += UpdateRectangle; PreviewMouseMove += UpdateLastMousePosition; } private void UpdateRectangle(object sender, EventArgs e) { var location = new Point(Canvas.GetLeft(followRectangle), Canvas.GetTop(followRectangle)); //find vector toward mouse location var toMouse = _lastMousePosition - location; //add a force toward the mouse to the rectangles velocity var followForce = 0.01; _rectangleVelocity += toMouse*followForce; //dampen the velocity to add stability var drag = 0.8; _rectangleVelocity *= drag; //update the new location from the velocity location += _rectangleVelocity; //set new position Canvas.SetLeft(followRectangle, location.X); Canvas.SetTop(followRectangle, location.Y); } private void UpdateLastMousePosition(object sender, MouseEventArgs e) { _lastMousePosition = e.GetPosition(containerCanvas); }
}动画
实现效果:this
代码此处增长一个字段:时间间隔值TimeSpan _lastRender,目的是获取帧间隔时间值。其余同上spa
public partial class FrameIndependentFollowExample : Page { private Point _lastMousePosition = new Point(0, 0); //timing variables private TimeSpan _lastRender; private Vector _rectangleVelocity = new Vector(0, 0); public FrameIndependentFollowExample() { InitializeComponent(); _lastRender = TimeSpan.FromTicks(DateTime.Now.Ticks); CompositionTarget.Rendering += UpdateRectangle; PreviewMouseMove += UpdateLastMousePosition; } private void UpdateLastMousePosition(object sender, MouseEventArgs e) { _lastMousePosition = e.GetPosition(containerCanvas); }
此处与上例变化主要是帧间位移差量的计算,主要与参数(帧间时间值)有关。线程
private void UpdateRectangle(object sender, EventArgs e) { var location = new Point(Canvas.GetLeft(followRectangle), Canvas.GetTop(followRectangle)); //find vector toward mouse location var toMouse = _lastMousePosition - location; //add a force toward the mouse to the rectangles velocity var followForce = 0.01; _rectangleVelocity += toMouse*followForce; //dampen the velocity to add stability var drag = 0.8; _rectangleVelocity *= drag; //update the new location from the velocity location += _rectangleVelocity; //set new position Canvas.SetLeft(followRectangle, location.X); Canvas.SetTop(followRectangle, location.Y); }
实现效果:
1.跟随鼠标方框为3个,这些都继承同一个Canvas,都是先摇摆跟随功能效果。
xaml代码:3d
<Canvas Background="transparent"> <perFrameAnimation:FollowMouseCanvas Canvas.Left="0" Canvas.Top="0" Background="red" Width="50" Height="50"> <!-- could put more content that will also follow mouse here--> </perFrameAnimation:FollowMouseCanvas> <perFrameAnimation:FollowMouseCanvas Canvas.Left="300" Canvas.Top="0" Background="green" Width="50" Height="50"> <!-- could put more content that will also follow mouse here--> </perFrameAnimation:FollowMouseCanvas> <perFrameAnimation:FollowMouseCanvas Canvas.Left="0" Canvas.Top="300" Background="blue" Width="50" Height="50"> <!-- could put more content that will also follow mouse here--> </perFrameAnimation:FollowMouseCanvas> </Canvas>
继承Canvas,实现摇摆跟随功能:code
public class FollowMouseCanvas : Canvas { private TimeSpan _lastRender; private Canvas _parentCanvas; private Point _parentLastMousePosition = new Point(0, 0); private Vector _velocity = new Vector(0, 0); public FollowMouseCanvas() { //_lastRender = TimeSpan.FromTicks(DateTime.Now.Ticks);//注释掉是由于初始值太大,最后location差值过大而一开始不会显示绿色与蓝色方框。 CompositionTarget.Rendering += UpdatePosition; } private void UpdatePosition(object sender, EventArgs e) { var renderingArgs = (RenderingEventArgs) e; var deltaTime = (renderingArgs.RenderingTime - _lastRender).TotalSeconds; _lastRender = renderingArgs.RenderingTime; if (_parentCanvas == null) { _parentCanvas = VisualTreeHelper.GetParent(this) as Canvas; if (_parentCanvas == null) { //parent isnt canvas so just abort trying to follow mouse CompositionTarget.Rendering -= UpdatePosition; } else { //parent is canvas, so track mouse position and time _parentCanvas.PreviewMouseMove += UpdateLastMousePosition; } } //get location var location = new Point(GetLeft(this), GetTop(this)); //check for NaN's and replace with 0,0 if (double.IsNaN(location.X) || double.IsNaN(location.Y)) location = new Point(0, 0); //find vector toward mouse location var toMouse = _parentLastMousePosition - location; //add a force toward the mouse to the rectangles velocity var followForce = 1.0; _velocity += toMouse*followForce; //dampen the velocity to add stability var drag = 0.95; _velocity *= drag; //update the new location from the velocity location += _velocity*deltaTime; //set new position SetLeft(this, location.X); SetTop(this, location.Y); } private void UpdateLastMousePosition(object sender, MouseEventArgs e) { if (_parentCanvas == null) return; if (this.Background==Brushes.Blue) { _parentLastMousePosition.X = e.GetPosition(_parentCanvas).X+100; _parentLastMousePosition.Y = e.GetPosition(_parentCanvas).Y; } else if (this.Background== Brushes.Green) { _parentLastMousePosition.X = e.GetPosition(_parentCanvas).X - 100; _parentLastMousePosition.Y = e.GetPosition(_parentCanvas).Y; } else { _parentLastMousePosition = e.GetPosition(_parentCanvas); } } }
见第2章对象
扩展:
CompositionTarget类:表示您的应用程序的显示图面。
HwndTarget 类:表示到支持可视化撰写的窗口句柄的绑定。
VisualTarget 类:提供用于跨越线程边界将一个可视化树链接到另外一个可视化树的功能。
RenderingEventArgs 类:Rendering 事件的必需参数。