Win2D UWP:保持步长1与TargetElapsedTime=16时提升线条动画速度
Absolutely! You can boost the line animation speed while keeping the _Offset step at 1 and leaving TargetElapsedTime set to 16ms. Here are two straightforward, effective approaches to do this:
Approach 1: Multi-Step Updates Per Frame
The core idea here is to update _Offset multiple times (each time by 1) within a single frame. This increases the total distance the line moves per frame without changing the individual step size.
Modified C# Code
private bool _adding = true; private int _Offset = 0; // Adjust this multiplier to control speed (higher values = faster animation) private int _speedMultiplier = 5; private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args) { CanvasDrawingSession ds = args.DrawingSession; double height = sender.Size.Height; double width = sender.Size.Width; var point1 = new Vector2((float)(width / 2), (float)height); var point2 = new Vector2((float)(width / 2), (float)height - (float)_Offset); CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green); ds.DrawLine(point1, point2, brush, (float)10); // Update Offset multiple times per frame (each step is 1) for (int i = 0; i < _speedMultiplier; i++) { if (_adding) { _Offset++; } else { _Offset--; } // Reverse direction when hitting boundary limits if (_Offset == 0 || _Offset == 300) { _adding = !_adding; } } }
How It Works
- We add a
_speedMultipliervariable to control how many times we update_Offseteach frame. For example, setting it to 5 makes the animation 5x faster than the original. - Each iteration of the loop changes
_Offsetby exactly 1, so you maintain the step size requirement. - Boundary checks run after each step, ensuring the direction reverses correctly even if
_Offsethits 0 or 300 mid-frame.
Approach 2: Time-Based Animation (Smoother, More Consistent)
If you want more precise speed control and smoother animation (especially if frame rates fluctuate), use a time-based approach. This calculates movement based on elapsed time rather than frame count, while still ensuring _Offset changes in steps of 1.
Modified C# Code
private bool _adding = true; private float _totalOffset = 0f; // This derived property ensures _Offset is always an integer (step size 1) private int _Offset => (int)Math.Round(_totalOffset); // Adjust speed in pixels per second (higher values = faster animation) private float _speed = 200f; private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args) { CanvasDrawingSession ds = args.DrawingSession; double height = sender.Size.Height; double width = sender.Size.Width; var point1 = new Vector2((float)(width / 2), (float)height); var point2 = new Vector2((float)(width / 2), (float)height - _Offset); CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green); ds.DrawLine(point1, point2, brush, (float)10); // Calculate how much to move based on time since last frame float delta = (float)args.Timing.ElapsedTime.TotalSeconds * _speed; if (!_adding) { delta = -delta; } _totalOffset += delta; // Clamp to boundaries and reverse direction if (_totalOffset <= 0) { _totalOffset = 0; _adding = true; } else if (_totalOffset >= 300) { _totalOffset = 300; _adding = false; } }
How It Works
- We use a floating-point
_totalOffsetto track the exact position over time, then round it to an integer for_Offset(ensuring each visible change is a step of 1). - The
_speedvariable lets you set movement in pixels per second, making the animation speed consistent regardless of frame rate. - Boundary checks clamp
_totalOffsetto 0 and 300, then reverse direction to keep the animation looping correctly.
Both approaches maintain your requirements: _Offset changes in steps of 1, TargetElapsedTime stays at 16ms, and the animation runs faster. Pick the one that best fits your needs!
内容的提问来源于stack exchange,提问作者Sogis

