如何围绕3D轴(Y)旋转2D UI元素?

4

我有一个包含图片和文本的Grid,我想在3D空间中沿y轴旋转它 - 实现一种动画倾斜效果。

是否有一种简单的方法,类似于Rotate3DTransform,可以直接应用于Grid


1
我有一些关于这种转换的经验。在回答你的问题之前,我想看看你期望的输出是什么。 - pushpraj
它看起来有点像透视失真的打开的门 - 就像这样的页面倾斜效果:http://www.simpleviewer.net/tiltviewer/,尽管我不需要任意轴。要倾斜的页面将包含一些UIElement(包含其他元素)。对我来说,3D模型不是问题,而是如何将任何2D内容放置在其中。类似于Josh Smith的ContentControl3D,但它会翻转180度。同时我找到了“WPF Tilt Shader Effect”,这在某种程度上有所帮助,但问题是是否可能在3D中旋转2D UIElements。 - JeffRSon
1个回答

8

使用Viewport3D

3D旋转

如果你想使用3D模型和旋转,下面是我为你准备的样例代码,我尽力复制了期望的效果,但可能不是非常精确。

    <Viewport3D>
        <Viewport3D.Resources>
            <Style TargetType="Image">
                <Setter Property="Width"
                        Value="20" />
                <Setter Property="Margin"
                        Value="4" />
                <Setter Property="Source"
                        Value="desert.jpg" />
                <Setter Property="Effect">
                    <Setter.Value>
                        <DropShadowEffect BlurRadius="4"
                                          Direction="0"
                                          ShadowDepth="0" />
                    </Setter.Value>
                </Setter>
            </Style>
        </Viewport3D.Resources>
        <Viewport3D.Camera>
            <PerspectiveCamera Position="0, 0, 4" />
        </Viewport3D.Camera>
        <Viewport2DVisual3D>
            <Viewport2DVisual3D.Transform>
                <RotateTransform3D>
                    <RotateTransform3D.Rotation>
                        <QuaternionRotation3D x:Name="rotate"
                                              Quaternion="0, 0, 0, 0.5" />
                    </RotateTransform3D.Rotation>
                </RotateTransform3D>
            </Viewport2DVisual3D.Transform>
            <Viewport2DVisual3D.Geometry>
                <MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0"
                                TextureCoordinates="0,0 0,1 1,1 1,0"
                                TriangleIndices="0 1 2 0 2 3" />
            </Viewport2DVisual3D.Geometry>
            <Viewport2DVisual3D.Material>
                <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" />
            </Viewport2DVisual3D.Material>
            <UniformGrid Columns="3"> <!--host your content here-->
                <Image />
                <Image />
                <Image />
                <Image />
                <Image />
                <Image />
                <Image />
                <Image />
                <Image />
            </UniformGrid>
        </Viewport2DVisual3D>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <DirectionalLight Color="#FFFFFFFF"
                                  Direction="0,0,-1" />
            </ModelVisual3D.Content>
        </ModelVisual3D>
        <Viewport3D.Triggers>
            <EventTrigger RoutedEvent="Viewport3D.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <QuaternionAnimation Storyboard.TargetName="rotate"
                                             Storyboard.TargetProperty="Quaternion"
                                             To="-0.25, 0.25, 0.15, 0.65"
                                             Duration="0:0:10"
                                             RepeatBehavior="Forever">
                            <QuaternionAnimation.EasingFunction>
                                <ElasticEase />
                            </QuaternionAnimation.EasingFunction>
                        </QuaternionAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Viewport3D.Triggers>
    </Viewport3D>

现在你可以旋转UI主机上托管图像瓷砖网络的模型。
另外,你可以将其转换为ContentControl的样式和模板,并使用附加属性进行旋转和重用。
使用2D变换,以下是一个示例,使得网格的正常变换呈现3D效果。
关键是将3D变换转换为2D并直接应用于网格,避免了复杂的3D处理(此示例没有任何转换),它仅演示了一个具有3D外观的网格变换供参考。
    <Grid Width="100" Height="100" >
        <Grid.Background>
            <ImageBrush Opacity=".5" ImageSource="Desert.jpg"/>
        </Grid.Background>
        <Button Content="Some Text" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Grid.RenderTransform>
            <SkewTransform x:Name="skew" CenterX="50" CenterY="50"/>
        </Grid.RenderTransform>
        <Grid.Triggers>
            <EventTrigger RoutedEvent="Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="skew" Duration="0:0:25" Storyboard.TargetProperty="AngleX" From="0" To="60" RepeatBehavior="Forever">
                            <DoubleAnimation.EasingFunction>
                                <ElasticEase/>
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="skew" Duration="0:0:20" Storyboard.TargetProperty="AngleY" From="0" To="50" RepeatBehavior="Forever">
                            <DoubleAnimation.EasingFunction>
                                <ElasticEase/>
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Grid.Triggers>
    </Grid>

是的,我开始使用SkewTransformation,但我无法确定性地将其更改为看起来更像倾斜页面的样子。 - JeffRSon
既然您想要使用3D,我已经更新了我的答案。现在,您将可以通过Viewport3D完全控制旋转。 - pushpraj
是的,这是您在3D空间中的用户界面元素的托管程序。 - pushpraj

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