gpt4 book ai didi

c# - 当缩放中心因捏合(缩放)或 metro 风格应用程序中的其他手势而发生变化时,如何在 Canvas 上缩放时避免出现 "jump"

转载 作者:行者123 更新时间:2023-11-30 12:31:16 25 4
gpt4 key购买 nike

当缩放中心因捏合(缩放)或 metro 风格应用中的其他手势而发生变化时,如何避免在 Canvas 对象上缩放时出现“跳跃”

我尝试存档的行为类似于预装 win8 map 应用程序的缩放行为。如果您执行捏合手势(放大或缩小),则缩放中心设置在手指之间的中间位置。如果你抬起其中一根手指,放在另一个点上,你可以立即执行另一个缩放操作,缩放中心正确改变,没有任何跳跃( Canvas 中对象的UI坐标的跳跃)。

我正在尝试使用复合转换在大型 Canvas 对象(在 C# WinRT 应用程序中)上实现类似的行为。我想允许平移和缩放,而不是旋转(现在,也许我稍后会添加它):

我这样初始化,将缩放中心放在屏幕中心:

this.compositeTransform = new CompositeTransform();
this.compositeTransform.CenterX = this.mainPage.Width / 2.0;
this.compositeTransform.CenterY = this.mainPage.Height / 2.0;

this.innerCanvas.RenderTransform = compositeTransform;

然后我将使用操作增量事件来获取输入数据

private void InnerCanvas_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
this.compositeTransform.ScaleX *= e.Delta.Scale;
this.compositeTransform.ScaleY *= e.Delta.Scale;

this.compositeTransform.CenterX = e.Position.X;
this.compositeTransform.CenterY = e.Position.Y;

this.compositeTransform.TranslateX += e.Delta.Translation.X;
this.compositeTransform.TranslateY += e.Delta.Translation.Y;
}

只要我执行相同的手势,它就可以正常工作。当我执行捏合手势时,新中心计算正确。但是,更改缩放中心会导致突然跳跃,例如在捏合手势后抬起其中一根手指时。当然,我可以只为捏手势改变中心,但跳跃的问题仍然存在。这当然是合乎逻辑的,因为缩放适用于新的缩放中心。我还没有想出办法,如何避免跳跃。由于比例值本身保持不变,因此一定有可能具有相同的外观(坐标不变)但中心已更改。

我目前的推理是,我必须以某种方式更改 TranslateX 和 TranslateY 坐标,以便以某种方式平衡新的中心点,即 ui 元素的当前屏幕坐标保持不变。像这样(scaleTransform 是一个 ScaleTransform,它只获取缩放数据)...

Point reverseScaleTransform =
this.scaleTransform.Inverse.TransformPoint(new Point(e.Position.X,e.Position.Y));

this.compositeTransform.TranslateX += reverseScaleTransform.X - e.Position.X;
this.compositeTransform.TranslateY += reverseScaleTransform.Y - e.Position.Y;

但这也行不通。整个事情似乎是平板电脑上的标准问题,但是尽管搜索了很多,但我仍未找到解决方案,也许我使用了错误的关键字。

最佳答案

我终于想通了,如何通过手动转换来解决问题,而不是使用 ScrollViewer。

    TranslateTransform tmpTranslate = new TranslateTransform();

private void InnerCanvas_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
//Transform world space into local space (origin: Scale center from the last manipulation event)

this.tmpTranslate.X = this.compositeTransform.CenterX;
this.tmpTranslate.Y = this.compositeTransform.CenterY;

Point center = this.compositeTransform.Inverse.TransformPoint(e.Position);

Point localPoint = tmpTranslate.Inverse.TransformPoint(center);

//Now scale the point in local space

localPoint.X *= this.compositeTransform.ScaleX;
localPoint.Y *= this.compositeTransform.ScaleY;

//Transform local space into world space again
Point worldPoint = tmpTranslate.TransformPoint(localPoint);

//Take the actual scaling...
Point distance = new Point(
worldPoint.X - center.X,
worldPoint.Y - center.Y);

//...amd balance the jump of the changed scaling origin by changing the translation

this.compositeTransform.TranslateX += distance.X;
this.compositeTransform.TranslateY += distance.Y;

//Also set the scaling values themselves, especially set the new scale center...

this.compositeTransform.ScaleX *= e.Delta.Scale;
this.compositeTransform.ScaleY *= e.Delta.Scale;

this.compositeTransform.CenterX = center.X;
this.compositeTransform.CenterY = center.Y;

//And consider a translational shift

this.compositeTransform.TranslateX += e.Delta.Translation.X;
this.compositeTransform.TranslateY += e.Delta.Translation.Y;
}

关于c# - 当缩放中心因捏合(缩放)或 metro 风格应用程序中的其他手势而发生变化时,如何在 Canvas 上缩放时避免出现 "jump",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14011895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com