在Expression Blend中,滚动鼠标滚轮时,屏幕上的元素会放大/缩小,聚焦在鼠标所在的位置。
我正在尝试在我自己的项目中实现相同的缩放,但是我在缩放,移动鼠标然后再次缩放时遇到问题。
到目前为止,我正在使用带有ScaleTransform的RenderTransform,使用鼠标坐标作为ScaleTransform的centerX和centerY。
有人知道他们是如何在Expression Blend中完成的吗?
这是我到目前为止所做的:
private void ScrollCanvasMouseWheel(object sender, MouseWheelEventArgs e)
{
double zoomAmnt = e.Delta > 0 ? 0.2 : -0.2;
_scaleTransformAmount += zoomAmnt;
if (_scaleTransformAmount < 0.5)
_scaleTransformAmount = 0.5;
Point position = e.GetPosition(ScrollCanvas);
var scaleTransform = ScrollCanvas.RenderTransform as ScaleTransform;
if (scaleTransform == null) throw new ArgumentNullException("scaleTransform");
scaleTransform.ScaleX = _scaleTransformAmount;
scaleTransform.ScaleY = _scaleTransformAmount;
scaleTransform.CenterX = position.X;
scaleTransform.CenterY = position.Y;
}
答案 0 :(得分:2)
这种缩放很好,所以我试图实现它一次,它的数学有点奇怪,我花了大约两天的时间来找出有用的东西,但这可能是相当难看的代码(变量带{ {1}}是缩放控件上的字段:
_
变换的顺序当然很重要:
Point cursorPos = e.GetPosition(this);
Point newCenter = _scaleT.Inverse.Transform(_translateT.Inverse.Transform(cursorPos));
Point oldCenter = new Point(_scaleT.CenterX, _scaleT.CenterY);
Vector oldToNewCenter = newCenter - oldCenter;
_scaleT.CenterX = newCenter.X;
_scaleT.CenterY = newCenter.Y;
_translateT.X += oldToNewCenter.X * (_scaleT.ScaleX - 1.0);
_translateT.Y += oldToNewCenter.Y * (_scaleT.ScaleY - 1.0);
_scalingAnimation.From = _scaleT.ScaleX;
if (e.Delta > 0)
{
_scalingAnimation.To = _scaleT.ScaleX * ZoomScaleChangeFactor;
}
else
{
_scalingAnimation.To = _scaleT.ScaleX / ZoomScaleChangeFactor;
}
_scaleT.BeginAnimation(ScaleTransform.ScaleXProperty, _scalingAnimation);
_scaleT.BeginAnimation(ScaleTransform.ScaleYProperty, _scalingAnimation);
this.ReleaseMouseCapture();