Windows Phone 8中的“捏合缩放”功能

6
从这篇文章中,我了解到有一些平台改进可以实现捏合和缩放功能。通过使用这种新方法(ManipulationDeltaEventArgs.PinchManipulation),我如何在Windows Phone上实现捏合缩放功能?
此外,我还需要为图像控件实现滚动功能。在我的当前实现中,我使用Toolkit(gesture listener)来实现捏合缩放功能以及滚动查看器,现在似乎滚动和捏合事件重叠,因此产生了不良的用户体验。
请问有人能帮我解决这个问题吗?我正在寻找一些代码示例来帮助我实现功能。
我不希望得到多点触摸行为(codeplex)作为答案。在项目中使用的程序集非常旧,我听说其中许多程序集仅因此而面临市场提交问题。
3个回答

28

如我在我的之前的回答中所说,如果你正在构建一款仅限于WP8的应用程序,你可以使用新的ManipulationDeltaEventArgs.PinchManipulation实现捏合和缩放效果。以下是如何使用ManipulationDeltaEventArgs.PinchManipulation数据来缩放、移动和旋转图像的基本示例。

首先,我们将创建一个基本的图像,悬停在网格中间:

<Grid x:Name="ContentPanel">
    <Image Source="Assets\Headset.png" 
           Width="200" Height="150"
           ManipulationDelta="Image_ManipulationDelta"
           x:Name="img"
           >
        <Image.RenderTransform>
            <CompositeTransform CenterX="100" CenterY="75" />
        </Image.RenderTransform>
    </Image>
</Grid>

接下来,我们将处理ManipulationDelta事件,检查它是否是Pinch操作,并在UIElement上应用正确的Silverlight转换。

private void Image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
    if (e.PinchManipulation != null)
    {
        var transform = (CompositeTransform)img.RenderTransform;

        // Scale Manipulation
        transform.ScaleX = e.PinchManipulation.CumulativeScale;
        transform.ScaleY = e.PinchManipulation.CumulativeScale;

        // Translate manipulation
        var originalCenter = e.PinchManipulation.Original.Center;
        var newCenter = e.PinchManipulation.Current.Center;
        transform.TranslateX = newCenter.X - originalCenter.X;
        transform.TranslateY = newCenter.Y - originalCenter.Y;

        // Rotation manipulation
        transform.Rotation = angleBetween2Lines(
            e.PinchManipulation.Current, 
            e.PinchManipulation.Original);

        // end 
        e.Handled = true;
    }
}

// copied from http://www.developer.nokia.com/Community/Wiki/Real-time_rotation_of_the_Windows_Phone_8_Map_Control
public static double angleBetween2Lines(PinchContactPoints line1, PinchContactPoints line2)
{
    if (line1 != null && line2 != null)
    {
        double angle1 = Math.Atan2(line1.PrimaryContact.Y - line1.SecondaryContact.Y,
                                   line1.PrimaryContact.X - line1.SecondaryContact.X);
        double angle2 = Math.Atan2(line2.PrimaryContact.Y - line2.SecondaryContact.Y,
                                   line2.PrimaryContact.X - line2.SecondaryContact.X);
        return (angle1 - angle2) * 180 / Math.PI;
    }
    else { return 0.0; }
}

我们的做法如下:

  • 缩放: PinchManipulation会跟踪缩放,因此我们只需要将PinchManipulation.CumulativeScale应用于缩放因子即可。
  • 转换: PinchManipulation跟踪原始中心点和新中心点(在两个触摸点之间计算而来)。通过将新中心点减去旧中心点,我们可以知道UIElement需要移动多少并将其应用于平移转换。注意,在这里更好的解决方案也会考虑跟踪累积的原始中心点,但这段代码没有实现。
  • 旋转: 我们计算出两个触摸点之间的角度,并将其作为旋转变换应用。有关详细信息,请参阅Nokia维基文章:在Windows Phone 8地图控件上实时旋转

以下是一些打印屏幕截图,显示此代码可以正常运行:

未触摸图像 旋转、转换和缩放图像 旋转、转换和缩放图像


谢谢Justin,回答详细又整洁.. :) - StezPet
2
嗨,Justin,我尝试了你的实现,我认为用户体验不是很好。你能解释一下实现类似wp8本地照片查看器的过程吗?就像一个支持捏合缩放、滚动等功能的照片查看器。我用scrollviewer尝试了你的代码,但是我没有得到滚动的体验。即使添加了scrollviewer,捏合和缩放也不起作用。 - Nitha Paul
@Justin,确实很棒,而且非常易于使用,但我无法在模拟器上测试它,有没有办法在模拟器上测试? - Mohit
嗨,Justin,你应该如何更改此设置,以使图像不会覆盖页面名称(第三张图片),并且如何在没有父全景控件滑动到第二个面板的情况下完成此操作? - JP Hellemons

4

-2

我正在寻找新的WP8功能实现。我认为Gesture listener现在已经过时了。我也尝试了Telerik,但我认为仅通过Teleric控件实现此功能是不可行的,而且Telerik控件中也没有滚动功能。 - StezPet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接