3D shuttle effect? You can also do it with UWP

3D shuttle effect? You can also do it with UWP

When I went home for dinner at night, I played Empire Age 4, and suddenly remembered that I hadn't favored UWP for a long time. A sense of pride emerged spontaneously that "I have General UWP, which can handle the 3D shuttle effect".

最后更新 2/21/2022 2:31 PM
dino.c
预计阅读 6 分钟
分类
.NET
标签
.NET C# UWP

Yesterday, ChokCoco boss created a 3D shuttle effect. You can see here:

3D 穿梭效果?使用 CSS 轻松搞定

This effect is so amazing that he even asked me if I could use WPF to get it, because I had never used WPF 3D at all, and my first reaction was "This is too difficult for me."

When I went home for dinner at night, I played Empire Age 4, and suddenly remembered that I hadn't favored UWP for a long time. A sense of pride emerged spontaneously that "I have General UWP, which can handle the 3D shuttle effect".

So this animation effect was created.

In general, the principle of achieving 3D shuttle is to create perspective effects by changing the perspective in CSS. Perspective specifies the distance of the observer from the z=0 plane, allowing elements with three-dimensional positional transformations to produce perspective effects. The lower its value, the deeper the viewing angle.

The specific usage of perspective can be found in this document:

perspective - CSS(层叠样式表) _ MDN

Correspondingly, the PerspectiveTransform3D class is provided in UWP, and its Depth attribute has a similar effect. When the Depth is smaller, the deeper the vision, the more deformed the objects that intersect the plane are:

Start immediately after you understand the principles. First, set the case of the Grid to 300 in Xaml, and then set the Depth of PerspectiveTransform3D to very small:

<Grid Height="300" Width="300">
  <Grid.Transform3D>
    <media3D:PerspectiveTransform3D Depth="2" />
  </Grid.Transform3D>
</Grid>

Then I got a starry sky picture from ChokCoco boss and put it in the Grid:

Then set the RotationY of CompositeTransform3D to-90, and the picture becomes distorted:

<media3D:CompositeTransform3D RotationY="-90" />

Then set TranslateZ="100" to stretch the image outward:

<media3D:CompositeTransform3D RotationY="-90" TranslateZ="100" />

After settling one direction, all directions are operated roughly like this. Just changing Rotation, Translate and the center point, a static 3D shuttle diagram is completed:

<media3D:CompositeTransform3D
  x:Name="TransformLeft"
  x:Key="TransformLeft"
  RotationY="-90"
  TranslateZ="100"
/>
<media3D:CompositeTransform3D
  x:Name="TransformUp"
  x:Key="TransformUp"
  RotationX="90"
  TranslateZ="50"
/>
<media3D:CompositeTransform3D
  x:Name="TransformRight"
  x:Key="TransformRight"
  RotationY="90"
  CenterX="300"
  TranslateZ="50"
/>
<media3D:CompositeTransform3D
  x:Name="TransformDown"
  x:Key="TransformDown"
  RotationX="-90"
  CenterY="300"
  TranslateZ="50"
/>

<Grid
  Background="{StaticResource ImageBackground}"
  Transform3D="{StaticResource TransformLeft}"
/>
<Grid
  Background="{StaticResource ImageBackground}"
  Transform3D="{StaticResource TransformUp}"
/>
<Grid
  Background="{StaticResource ImageBackground}"
  Transform3D="{StaticResource TransformRight}"
/>
<Grid
  Background="{StaticResource ImageBackground}"
  Transform3D="{StaticResource TransformDown}"
/>

The next step is to make these four pictures move. It's simple, using the most basic DoubleAnimation operation to change TranslateZ from 10 to 200:

<Storyboard x:Name="Move" x:Key="Move" RepeatBehavior="Forever">
  <DoubleAnimation
    Storyboard.TargetName="TransformLeft"
    Storyboard.TargetProperty="TranslateZ"
    From="10"
    To="200"
    Duration="0:0:8"
  />
  <DoubleAnimation
    Storyboard.TargetName="TransformUp"
    Storyboard.TargetProperty="TranslateZ"
    From="10"
    To="200"
    Duration="0:0:8"
  />
  <DoubleAnimation
    Storyboard.TargetName="TransformRight"
    Storyboard.TargetProperty="TranslateZ"
    From="10"
    To="200"
    Duration="0:0:8"
  />
  <DoubleAnimation
    Storyboard.TargetName="TransformDown"
    Storyboard.TargetProperty="TranslateZ"
    From="10"
    To="200"
    Duration="0:0:8"
  />
</Storyboard>

At this time, the basic animation has been implemented, but there is no way to connect it end to end, so first package the previous results into a control:

Then animate it with changes in transparency:

<Storyboard x:Name="Fade" RepeatBehavior="Forever">
  <DoubleAnimationUsingKeyFrames
    Storyboard.TargetName="Root"
    Storyboard.TargetProperty="Opacity"
    Duration="0:0:8"
  >
    <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0" />
    <LinearDoubleKeyFrame KeyTime="0:0:2" Value="1" />
    <LinearDoubleKeyFrame KeyTime="0:0:4.8" Value="1" />
    <LinearDoubleKeyFrame KeyTime="0:0:8" Value="0" />
  </DoubleAnimationUsingKeyFrames>
</Storyboard>

By superimposing two GalaxyShuttleControls and controlling the start time of their animations, they cover up each other's problem of not connecting the beginning and end animations:

public TimeSpan Delay { get; set; }

private async void GalaxyShettleControl_Loaded(object sender, RoutedEventArgs e)
{
    await Task.Delay(Delay);
    Move.Begin();
    Fade.Begin();
}
<galaxyshuttles:GalaxyShuttleControl Delay="0:0:4" />
<galaxyshuttles:GalaxyShuttleControl/>

In this way, the 3D shuttle effect is realized.

最后还差一点,ChokCoco 大佬的动画里加上了 hueRotate ,让颜色一直变化。UWP 里也可以使用 HueRotationEffect 实现这点,不过它的 Angle 的值范围是 0 到 2 * Math.Pi。要实现它的动画可以试试 Windows Community Toolkit 里的 PipelineVisualFactoryAnimationSet,这两个工具可以用来处理很复杂的效果和动画,用在这里反而大材小用:

<media:UIElementExtensions.VisualFactory>
    <media:PipelineVisualFactory>
        <media:HueRotationEffect x:Name="HueRotationEffect" IsAnimatable="True"/>
    </media:PipelineVisualFactory>
</media:UIElementExtensions.VisualFactory>
<animations:Explicit.Animations>
    <animations:AnimationSet x:Name="HueAnimation" >
        <animations:AnimationScope>
            <animations:HueRotationEffectAnimation From="0" To="6.28318530718" Target="{Binding ElementName=HueRotationEffect}"  Repeat="Forever" Duration="0:0:28"/>
        </animations:AnimationScope>
    </animations:AnimationSet>
</animations:Explicit.Animations>

The final effect is as follows:

After satisfying your curiosity, the next step (generating your own pictures) is to stop playing. It is not difficult to implement 3D shuttle animation. The most difficult part is the creativity provided by ChokCoco. I hope that ChokCoco will have another animation for me to copy and play next time.

Finally, although it should be possible to do it with MAIU or WinUI3, and these two technologies sound more fashionable, unfortunately, they have not been released yet, so I'd better spend more time with UWP.

Source code: https://github.com/DinoChan/uwp_design_and_animation_lab

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 4/22/2026

Support for. NET by operating system versions (250707 update)

Use virtual machines and test machines to test the support of each version of the operating system for. NET. After installing the operating system, it is passed by measuring the corresponding running time of the installation and being able to run the Stardust Agent.

继续阅读
同分类 / 同标签 2/7/2026

Summary of experience in using AOT

From the very beginning of project creation, you should develop a good habit of conducting AOT release testing in a timely manner whenever new features are added or newer syntax is used.

继续阅读