c# - 如何平滑地旋转 uwp 用户控件?
问题描述
我创建了一个包含一些文本框、图像等的用户控件。现在我想用鼠标旋转该用户控件。我已经成功旋转,但是在旋转过程中它倒转,我在哪里做错了?下面是我的 xaml 和代码:
<UserControl...
<Grid x:Name="ContainerGrid"
Width="300" Height="400" RenderTransformOrigin="0.5,0.5"
ManipulationMode="TranslateX,TranslateY,Rotate"
ManipulationStarted="Manipulator_OnManipulationStarted"
ManipulationDelta="Manipulator_OnManipulationDelta">
<Grid.RenderTransform>
<RotateTransform x:Name="RotateGrid" Angle="0"/>
</Grid.RenderTransform>
<!-- some elements -->
<Rectangle x:Name="RotateRectangle"
IsHitTestVisible="False"
Width="16" Height="16"
Fill="Red"
VerticalAlignment="Top"
HorizontalAlignment="Right" />
</Grid>
private void Manipulator_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
if (e.Position.X > ContainerGrid.Width - RotateRectangle.Width &&
e.Position.Y < ContainerGrid.Height - RotateRectangle.Height)
{
_isRotating = true;
lastPosition = e.Position;
return;
}
_isRotating = false;
}
private void Manipulator_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (_isRotating)
{
Point currentLocation = e.Position;
double radians = Math.Atan2((currentLocation.Y - lastPosition.Y), (currentLocation.X - lastPosition.X));
var angle = radians * 180 / Math.PI;
RotateGrid.Angle = angle;
lastPosition = currentLocation;
}
}
解决方案
您的问题令人困惑……您想在屏幕平面上旋转 2D 对象,对吗?(这就是我从你的转换中假设的。)那么你为什么同时使用 x 和 y 鼠标位置?您的旋转是一个标量值,因此您应该只使用鼠标移动的 1 轴。
如果您想通过让鼠标抓住对象周围的假想环并旋转它来旋转对象...那么您应该保持对相对于对象中心的起始位置或鼠标相对起始角度的引用到物体的中心。可能是这样的:
private void Manipulator_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
if (e.Position.X > ContainerGrid.Width - RotateRectangle.Width &&
e.Position.Y < ContainerGrid.Height - RotateRectangle.Height)
{
_isRotating = true;
var startingRadians = Math.Atan2((currentLocation.Y - objectCenter.Y), (currentLocation.X - objectCenter.X));
startingAngle = startingRadians * 180 / Math.PI;
return;
}
_isRotating = false;
}
private void Manipulator_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (_isRotating)
{
Point currentLocation = e.Position;
double radians = Math.Atan2((currentLocation.Y - objectCenter.Y), (currentLocation.X - objectCenter.X));
var angle = radians * 180 / Math.PI;
RotateGrid.Angle = angle-startingAngle;
}
}
推荐阅读
- python - Selenium 单击 SharePoint 列表中的“导出”CSV 按钮
- javascript - 未捕获的错误:操作必须是普通对象(React/Redux)
- web - 两个使用 google openid 连接的应用程序,我们可以使用 iframe 将一个应用程序放入另一个应用程序吗?
- java - 使用注解转换器禁用 @Test
- ios - Flutter (iOS) Firebase Auth Sign in With Phone Number: 在 Podfile 中添加 'pod'Firebase/Auth' 后出错
- mapbox - Mapbox 覆盖不跨越本初子午线
- reactjs - mern 堆栈中如何处理路由?
- slurm - 如何在后台运行 slurm?
- c# - 如何在 IIS 上使用 ASP.NET Core Web API 配置 SPA 应用程序
- c# - 如何在运行时将通过反射获取的属性转换为正确的泛型类型