背水一戰 Windows 10 (70) - 控件(控件基類): UIElement - Transform3D(3D變換), Projection(3D投影)
作者:webabcd
介紹
背水一戰 Windows 10 之 控件(控件基類 - UIElement)
- Transform3D(3D變換)
- Projection(3D投影)
示例
1、演示 UIElement 的 3D 變換的應用
Controls/BaseControl/UIElementDemo/Transform3DDemo.xaml
<Page x:Class="Windows10.Controls.BaseControl.UIElementDemo.Transform3DDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <!-- UIElement - UIElement Transform3D - 3D 變換(通過 CompositeTransform3D 結合 PerspectiveTransform3D 來完成 3D 變換) --> <Grid.Transform3D> <!-- PerspectiveTransform3D - 讓指定的空間內的元素支持通過 CompositeTransform3D 來實現 3D 變換 OffsetX - 透視原點相對於元素中心的 x 方向的偏移量 OffsetY - 透視原點相對於元素中心的 y 方向的偏移量 Depth - 到 z=0 的平面的距離,必須大於 0,默認值為 1000 --> <PerspectiveTransform3D OffsetX="{x:Bind sliderOX.Value, Mode=OneWay}" OffsetY="{x:Bind sliderOY.Value, Mode=OneWay}" Depth="{x:Bind sliderD.Value, Mode=OneWay}"> </PerspectiveTransform3D> </Grid.Transform3D> <StackPanel HorizontalAlignment="Center"> <Image Source="/Assets/hololens.jpg" Width="200" Height="200" Name="image" Margin="5"> <Image.Transform3D> <!-- CompositeTransform3D - 為 UIElement 實現 3D 變換(此 UIElement 的祖輩必須要設置了 PerspectiveTransform3D) CenterX, CenterY, CenterZ - 3D 變換的中心點位置(單位:像素) RotationX, RotationY, RotationZ - 3D 變換的旋轉角度(單位:度) ScaleX, ScaleY, ScaleZ - 3D 變換的縮放比例 TranslateX, TranslateY, TranslateZ - 3D 變換的位移距離(單位:像素) 注意:x 坐標向右為正,y 坐標向下為正,z 坐標向你為正(左手坐標系) --> <CompositeTransform3D CenterX="{x:Bind sliderCX.Value, Mode=OneWay}" CenterY="{x:Bind sliderCY.Value, Mode=OneWay}" CenterZ="{x:Bind sliderCZ.Value, Mode=OneWay}" RotationX="{x:Bind sliderRX.Value, Mode=OneWay}" RotationY="{x:Bind sliderRY.Value, Mode=OneWay}" RotationZ="{x:Bind sliderRZ.Value, Mode=OneWay}" ScaleX="{x:Bind sliderSX.Value, Mode=OneWay}" ScaleY="{x:Bind sliderSY.Value, Mode=OneWay}" ScaleZ="{x:Bind sliderSZ.Value, Mode=OneWay}" TranslateX="{x:Bind sliderTX.Value, Mode=OneWay}" TranslateY="{x:Bind sliderTY.Value, Mode=OneWay}" TranslateZ="{x:Bind sliderTZ.Value, Mode=OneWay}"> </CompositeTransform3D> </Image.Transform3D> </Image> <StackPanel Orientation="Horizontal" Margin="5"> <Slider Name="sliderOX" Minimum="-100" Maximum="100" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="OffsetX: "/> <TextBlock Text="{x:Bind sliderOX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderOY" Minimum="-100" Maximum="100" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="OffsetY: "/> <TextBlock Text="{x:Bind sliderOY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderD" Minimum="100" Maximum="5000" Value="1000" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="Depth: "/> <TextBlock Text="{x:Bind sliderD.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5"> <Slider Name="sliderCX" Minimum="-300" Maximum="300" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterX: "/> <TextBlock Text="{x:Bind sliderCX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderCY" Minimum="-300" Maximum="300" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterY: "/> <TextBlock Text="{x:Bind sliderCY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderCZ" Minimum="-300" Maximum="300" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterZ: "/> <TextBlock Text="{x:Bind sliderCZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5"> <Slider Name="sliderRX" Minimum="0" Maximum="360" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationX: "/> <TextBlock Text="{x:Bind sliderRX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderRY" Minimum="0" Maximum="360" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationY: "/> <TextBlock Text="{x:Bind sliderRY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderRZ" Minimum="0" Maximum="360" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationZ: "/> <TextBlock Text="{x:Bind sliderRZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5"> <Slider Name="sliderSX" Minimum="0.1" Maximum="10" StepFrequency="0.1" Value="1" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="ScaleX: "/> <TextBlock Text="{x:Bind sliderSX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderSY" Minimum="0.1" Maximum="10" StepFrequency="0.1" Value="1" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="ScaleY: "/> <TextBlock Text="{x:Bind sliderSY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderSZ" Minimum="0.1" Maximum="10" StepFrequency="0.1" Value="1" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="ScaleZ: "/> <TextBlock Text="{x:Bind sliderSZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5"> <Slider Name="sliderTX" Minimum="-100" Maximum="100" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="TranslateX: "/> <TextBlock Text="{x:Bind sliderTX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderTY" Minimum="-100" Maximum="100" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="TranslateY: "/> <TextBlock Text="{x:Bind sliderTY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderTZ" Minimum="-100" Maximum="100" Width="200" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="TranslateZ: "/> <TextBlock Text="{x:Bind sliderTZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> </StackPanel> </Grid> </Page>
Controls/BaseControl/UIElementDemo/Transform3DDemo.xaml.cs
/* * UIElement - UIElement(繼承自 DependencyObject, 請參見 /Controls/BaseControl/DependencyObjectDemo/) * Transform3D - 3D 變換 * * * 本例用於演示 UIElement 的 3D 變換的應用 */ using Windows.UI.Xaml.Controls; namespace Windows10.Controls.BaseControl.UIElementDemo { public sealed partial class Transform3DDemo : Page { public Transform3DDemo() { this.InitializeComponent(); } } }
2、演示 UIElement 的投影(模擬 3D 效果)的應用
Controls/BaseControl/UIElementDemo/ProjectionDemo.xaml
<Page x:Class="Windows10.Controls.BaseControl.UIElementDemo.ProjectionDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10" HorizontalAlignment="Center"> <!-- Projection - 投影(模擬 3D 效果,可用類型有 PlaneProjection 和 Matrix3DProjection) PlaneProjection - 將對象投影到平面(通過 x,y,z 方向的旋轉和位移控制投影),用於模擬出 UIElement 的 3D 效果 RotationX, RotationY, RotationZ - 繞 X軸, Y軸, Z軸 旋轉的角度 CenterOfRotationX, CenterOfRotationY, CenterOfRotationZ - X軸, Y軸, Z軸 旋轉中心點的位置 CenterOfRotationX - 相對值,默認值為 0.5 即中心,0 代表 UIElement 的最左端,1 代表 UIElement 的最右端,可以小於 0 也可以大於 1 CenterOfRotationY - 相對值,默認值為 0.5 即中心,0 代表 UIElement 的最頂端,1 代表 UIElement 的最底端,可以小於 0 也可以大於 1 CenterOfRotationZ - 像素值,默認值為 0,靠向你的方向為正,遠離你的方向為負(即左手坐標系) GlobalOffsetX, GlobalOffsetY, GlobalOffsetZ - 沿 X軸, Y軸, Z軸 的偏移量,此 3 個方向與屏幕的 3 個方向相同 LocalOffsetX, LocalOffsetY, LocalOffsetZ - 沿 X軸, Y軸, Z軸 的偏移量,此 3 個方向與相關的 UIElement 當前的 3 個方向相同 ProjectionMatrix - 獲取當前投影的 Matrix3D 投影矩陣 Matrix3DProjection - 將對象投影到平面(通過 Matrix3D 矩陣控制投影),用於模擬出 UIElement 的 3D 效果 ProjectionMatrix - 獲取或設置當前投影的 Matrix3D 投影矩陣 --> <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 20 0 0"> <Rectangle Width="200" Height="100" StrokeDashArray="3,1" Stroke="Blue" StrokeThickness="3" /> <Rectangle Width="200" Height="100" Fill="Yellow" Stroke="Red" StrokeThickness="3" Opacity="0.3"> <Rectangle.Projection> <PlaneProjection x:Name="planeProjection" CenterOfRotationX="{x:Bind sliderCRX.Value, Mode=OneWay}" CenterOfRotationY="{x:Bind sliderCRY.Value, Mode=OneWay}" CenterOfRotationZ="{x:Bind sliderCRZ.Value, Mode=OneWay}" RotationX="{x:Bind sliderRX.Value, Mode=OneWay}" RotationY="{x:Bind sliderRY.Value, Mode=OneWay}" RotationZ="{x:Bind sliderRZ.Value, Mode=OneWay}" LocalOffsetX="{x:Bind sliderLOX.Value, Mode=OneWay}" LocalOffsetY="{x:Bind sliderLOY.Value, Mode=OneWay}" LocalOffsetZ="{x:Bind sliderLOZ.Value, Mode=OneWay}" GlobalOffsetX="{x:Bind sliderGOX.Value, Mode=OneWay}" GlobalOffsetY="{x:Bind sliderGOY.Value, Mode=OneWay}" GlobalOffsetZ="{x:Bind sliderGOZ.Value, Mode=OneWay}"> </PlaneProjection> </Rectangle.Projection> </Rectangle> </Grid> <StackPanel Orientation="Horizontal" Margin="0 30 0 0"> <Slider Name="sliderCRX" Minimum="-1" Maximum="2" StepFrequency="0.1" Value="0.5" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterOfRotationX: "/> <TextBlock Text="{x:Bind sliderCRX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderCRY" Minimum="-1" Maximum="2" StepFrequency="0.1" Value="0.5" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterOfRotationY: "/> <TextBlock Text="{x:Bind sliderCRY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderCRZ" Minimum="-100" Maximum="100" Value="0" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="CenterOfRotationZ: "/> <TextBlock Text="{x:Bind sliderCRZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal"> <Slider Name="sliderRX" Minimum="0" Maximum="360" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationX: "/> <TextBlock Text="{x:Bind sliderRX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderRY" Minimum="0" Maximum="360" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationY: "/> <TextBlock Text="{x:Bind sliderRY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderRZ" Minimum="0" Maximum="360" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="RotationZ: "/> <TextBlock Text="{x:Bind sliderRZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal"> <Slider Name="sliderLOX" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="LocalOffsetX: "/> <TextBlock Text="{x:Bind sliderLOX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderLOY" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="LocalOffsetY: "/> <TextBlock Text="{x:Bind sliderLOY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderLOZ" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="LocalOffsetZ: "/> <TextBlock Text="{x:Bind sliderLOZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> <StackPanel Orientation="Horizontal"> <Slider Name="sliderGOX" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="GlobalOffsetX: "/> <TextBlock Text="{x:Bind sliderGOX.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderGOY" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="GlobalOffsetY: "/> <TextBlock Text="{x:Bind sliderGOY.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> <Slider Name="sliderGOZ" Minimum="-150" Maximum="150" Width="200" HorizontalAlignment="Left" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" Margin="10"> <Slider.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="GlobalOffsetZ: "/> <TextBlock Text="{x:Bind sliderGOZ.Value, Mode=OneWay}" /> </StackPanel> </Slider.Header> </Slider> </StackPanel> </StackPanel> </Grid> </Page>
Controls/BaseControl/UIElementDemo/ProjectionDemo.xaml.cs
/* * UIElement - UIElement(繼承自 DependencyObject, 請參見 /Controls/BaseControl/DependencyObjectDemo/) * Projection - 投影(模擬 3D 效果) * PlaneProjection - 將對象投影到平面(通過 x,y,z 方向的旋轉和位移控制投影) * Matrix3DProjection - 將對象投影到平面(通過 Matrix3D 矩陣控制投影) * * * 本例用於演示 UIElement 的投影(模擬 3D 效果)的應用 */ using Windows.UI.Xaml.Controls; namespace Windows10.Controls.BaseControl.UIElementDemo { public sealed partial class ProjectionDemo : Page { public ProjectionDemo() { this.InitializeComponent(); } } }
OK
[源碼下載]
