我正在尝试在ScrollViewer
中实现MiddleClickScrolling并且效果很好。
问题是当移动指针时Storyboard
将重新启动以更新速度,但是当我们移动指针时会发生抖动。我附加了一个gif,但你可能不会注意到这个gif中的抖动。
由于这是一个大课程,我不能把所有代码放在这里。您可以在GitHub 上看到完整代码<(strong>注意:如果要克隆,请选择SmoothScroll分支)。重现此问题的一种简单方法是快速将指针向上和向下移动一小段距离。
这是我的故事板动画代码
_verticalDoubleAnimation = new DoubleAnimation()
{
EnableDependentAnimation = true,
Duration = new TimeSpan(0, 0, 1)
};
//Different function
var offsetX = _currentPosition.X - _startPosition.X;
var offsetY = _currentPosition.Y - _startPosition.Y;
SetCursorType(offsetX, offsetY);
if (CanScrollVertical())
{
if (Math.Abs(offsetY) > _threshold)
{
RunInUIThread(() =>
{
_verticalDoubleAnimation.From = _scrollViewer.VerticalOffset;
_verticalDoubleAnimation.To = _scrollViewer.VerticalOffset + (offsetY > 0 ? _scrollViewer.ScrollableHeight : -_scrollViewer.ScrollableHeight);
if ((_scrollViewer.ScrollableHeight / (Math.Abs(offsetY) * _factor)) == double.NaN)
{
return;
}
_verticalDoubleAnimation.Duration = TimeSpan.FromSeconds(_scrollViewer.ScrollableHeight / (Math.Abs(offsetY) * _factor));
_verticalStoryboard.Begin();
});
}
else
{
RunInUIThread(() =>
{
_verticalStoryboard.Stop();
_sliderVertical.Value = _scrollViewer.VerticalOffset;
});
}
}
答案 0 :(得分:0)
使用ScrollViewer.ChangeView()方法,使用计时器或while循环动态更新位置,而不是动画。确保间隔小于16.6ms,以实现平滑的60fps运动。另外,请确保将ChangeView的最终参数设置为false,以便禁用其内置动画。
所以在你第一次提交时,改变一下:
timer = new Timer(ScrollAsync, null, 50, 50);
对此:
timer = new Timer(ScrollAsync, null, 0, 5);
定时器在1毫秒甚至10毫秒内不能提供精确度。通过每1-5ms更新过度补偿应该弥补这一点,所以它可能很好,这就是我在自定义滚动控件中使用的。 Stopwatch非常精确,但却是一个巨大的CPU占用。另一种选择:这是一项额外的工作,但是如果你想要精确的计时和最大的性能以及最少的电池使用,你可以使用Win2D的CanvasAnimatedControl,它可以用来每60秒运行一次代码。