c# - WPF - 旋转后平移时的触摸操作问题
问题描述
我对通过操纵事件(更准确地说是矩阵)进行对象转换有疑问。
问题:在我的对象(顺便说一句:一个矩形)的第一次成功旋转/缩放/平移之后,第二次操作(在这种情况下为平移)将在其新角度的方向上移动对象。例如,如果在第一次旋转(新角度为 45°)之后我从右到左触摸屏幕,则对象将遵循 45° 对角线路径而不是我绘制的路径。
期望:我希望我的对象完全按照我在屏幕上创建的路径,而不管它的旋转。
情况:我通过代码在画布中放置一个矩形,这个矩形有“IsManipulationEnabled = true”和“RenderTransformOrigin = new Point(.5, .5)”和“mySuperRectangle.ManipulationDelta += Container_ManipulationDelta;”
这是我使用的代码:
private void Container_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
try
{
if (e.OriginalSource != null)
{
Rectangle image = e.OriginalSource as Rectangle;
Point center = new Point(image.ActualWidth / 2.0, image.ActualHeight / 2.0);
Matrix imageMatrix = ((MatrixTransform)image.RenderTransform).Matrix;
center = imageMatrix.Transform(center);
// Move the Rectangle.
imageMatrix.Translate(e.DeltaManipulation.Translation.X,
e.DeltaManipulation.Translation.Y);
// Rotate the Rectangle.
imageMatrix.RotateAt(e.DeltaManipulation.Rotation,
center.X,
center.Y);
// Resize the Rectangle. Keep it square
// so use only the X value of Scale.
imageMatrix.ScaleAt(e.DeltaManipulation.Scale.X,
e.DeltaManipulation.Scale.X,
center.X,
center.Y);
// Apply changes
image.RenderTransform = new MatrixTransform(imageMatrix);
Rect containingRect =
new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
Rect shapeBounds =
image.RenderTransform.TransformBounds(
new Rect(image.RenderSize));
// Check if the rectangle is completely in the window.
// If it is not and intertia is occuring, stop the manipulation.
if (e.IsInertial && !containingRect.Contains(shapeBounds))
{
e.Complete();
}
e.Handled = true;
}
}
catch (Exception)
{
throw;
}
}
有任何想法吗 ?
非常感谢。
解决方案
您应该在 Canvas 上处理操作事件,因为操作的原点应该相对于固定的 Canvas,而不是移动的 Rectangle。
<Canvas IsManipulationEnabled="True"
ManipulationDelta="CanvasManipulationDelta">
<Rectangle x:Name="rectangle" Width="200" Height="200" Fill="Red">
<Rectangle.RenderTransform>
<MatrixTransform/>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
事件处理程序将像这样工作:
private void CanvasManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
var transform = (MatrixTransform)rectangle.RenderTransform;
var matrix = transform.Matrix;
var center = e.ManipulationOrigin;
var scale = (e.DeltaManipulation.Scale.X + e.DeltaManipulation.Scale.Y) / 2;
matrix.ScaleAt(scale, scale, center.X, center.Y);
matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);
matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
transform.Matrix = matrix;
}
推荐阅读
- python - Flask RestPlus/RestX:如何在命名空间之间共享 API 模型?
- r - 变长df二次采样函数r
- wordpress - 从同一网络中的移动设备访问本地安装的 Wordpress
- python - 如何从 npz 加载 Chainer 训练检查点?
- javascript - react应用程序中avform提交事件的stopPropagation
- java - 如何在 SQL 中获取记录删除日期?
- javascript - JavaScript 中解构赋值的顺序是否有保证?
- javascript - 单击链接时Angular会创建滚动条,但它不应该吗?
- java - 多对一中的Spring未解决的前向引用
- mysql - 在 SQL 中选择部分匹配输入的行