我正在使用合成API来制作各种动画和效果。我也在尝试合并
3D perspective effect
在相同的元素上。不幸的是,使用合成API重新创建3D透视效果的唯一方法是使用Visual.TransformMatrix财产
can't be animated AFAIK
然后我意识到这种坏行为只会发生在埃莱姆身上ntCompositionPreview.GetElementVisual已对UIElement调用。即使我不改变任何视觉效果的属性或者对它做任何事情,简单地调用它,就不可能使用目标为的故事板动画UIElement.平面投影如果你不想让它在完成后重置。
复制和粘贴下面的代码在一个新的UWP项目目标1809或1803将提供一个完整的复制项目。
主页.xaml
<Page
x:Class="PlaneProjectionStoryboardBugRepro.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="Transparent">
<Grid x:Name="LayoutRoot">
<TextBlock x:Name="StandardText" Visibility="Visible" Foreground="DarkGreen" HorizontalAlignment="Center" TextAlignment="Center" VerticalAlignment="Top" Margin="100" FontSize="24">
Press the rotate button several times<LineBreak/>
Notice Storyboard that is rotating the plane projection about Y axis is working properly.<LineBreak/>
Now try it after pressing the second button.
</TextBlock>
<TextBlock x:Name="WarningText" Visibility="Collapsed" Foreground="DarkRed" HorizontalAlignment="Center" TextAlignment="Center" VerticalAlignment="Top" Margin="100" FontSize="24">
Composition API has been invoked.<LineBreak/>
Notice that now the rotation Storyboard animation's FillBehavior is broken.<LineBreak/>
Simply from calling 'ElementCompositionPreview.GetElementVisual'
</TextBlock>
<Image x:Name="Logo" Source="Assets\StoreLogo.png" Height="500" Width="500" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="30">
<Button Content="Rotate Logo" Margin="12" HorizontalAlignment="Center" Click="Button_Click"/>
<Button Content="Call 'GetElementVisual' On Logo" Margin="12" HorizontalAlignment="Center" Click="Button_Click_2"/>
<Button Content="Reset" HorizontalAlignment="Center" Margin="12" Click="Button_Click_3"/>
</StackPanel>
</Grid>
</Page>
主页.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Hosting;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
namespace PlaneProjectionStoryboardBugRepro
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.Loaded += MainPage_Loaded;
this.InitializeComponent();
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var pp = new PlaneProjection();
Logo.Projection = pp;
}
double EndAngle = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
EndAngle = (EndAngle == 0) ? 45 : 0;
var storyboard = new Storyboard();
var animation = new DoubleAnimation();
animation.Duration = TimeSpan.FromMilliseconds(500);
animation.To = EndAngle;
Storyboard.SetTarget(animation, Logo);
Storyboard.SetTargetProperty(animation, "(UIElement.Projection).(PlaneProjection.RotationY)");
storyboard.Children.Add(animation);
storyboard.Begin();
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
// Simply instantiating a Visual object of the UIElement breaks the Storyboard.
var visual = ElementCompositionPreview.GetElementVisual(Logo);
StandardText.Visibility = Visibility.Collapsed;
WarningText.Visibility = Visibility.Visible;
}
async void Button_Click_3(object sender, RoutedEventArgs e)
{
await CoreApplication.RequestRestartAsync("");
}
}
}