因此,我目前正在使用 Windows 组合 API 来创建“淡入”动画,将缩放动画和不透明动画结合到我的自定义控件中,效果非常好。然而,最近我尝试添加一些灯光效果,但由于某种原因,不透明动画不再起作用。
如您所见,您可以在没有灯光效果的“淡入”动画期间看到图像。但是一旦你添加了灯光效果,在“淡入”动画完成之前你是看不到它的。一定是合成动画的一些机制,但我只是以错误的方式使用它们。
您可以在此处重现代码
MainPage.xaml(使用您自己的图像):
<Grid x:Name="rootPanel" Background="LightGray" Loaded="rootPanel_Loaded">
<Image x:Name="panel" Source="Assets/aaa.jpg" Loaded="panel_Loaded" />
MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
private Compositor _compositor;
private const float lightDepth = 300f;
private const int animationDelay = 600;
private const int animationDuration = 70;
private CompositionEffectFactory _effectFactory;
private Random _random = new Random();
private PointLight _pointLight;
private Visual _root;
private ImplicitAnimationCollection _implicitAnimations1st;
public MainPage()
{
this.InitializeComponent();
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_implicitAnimations1st = _compositor.CreateImplicitAnimationCollection();
var _firstWaveAnimationGroup = _compositor.CreateAnimationGroup();
var OpacityAnimation1st = _compositor.CreateScalarKeyFrameAnimation();
OpacityAnimationSetting(OpacityAnimation1st, (double)0);
var scaleAnimation1st = _compositor.CreateVector3KeyFrameAnimation();
ScaleAnimationSetting(scaleAnimation1st, (double)0);
_firstWaveAnimationGroup.Add(OpacityAnimation1st);
_firstWaveAnimationGroup.Add(scaleAnimation1st);
_implicitAnimations1st["Offset"] = _firstWaveAnimationGroup;
}
private void ScaleAnimationSetting(Vector3KeyFrameAnimation animation, double delay)
{
animation.InsertKeyFrame(0.0f, new Vector3(0.7f, 0.7f, -.5f));
animation.InsertKeyFrame(1.0f, new Vector3(1, 1, 0), _compositor.CreateLinearEasingFunction());
animation.Duration = TimeSpan.FromMilliseconds(800);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
animation.DelayBehavior = AnimationDelayBehavior.SetInitialValueAfterDelay;
animation.Target = "Scale";
}
private void OpacityAnimationSetting(ScalarKeyFrameAnimation animation, double delay)
{
animation.InsertKeyFrame(0.0f, 0.0f);
animation.InsertKeyFrame(1.0f, 1.0f, _compositor.CreateLinearEasingFunction());
animation.Duration = TimeSpan.FromMilliseconds(800);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
animation.DelayBehavior = AnimationDelayBehavior.SetInitialValueAfterDelay;
animation.Target = "Opacity";
}
private void panel_Loaded(object sender, RoutedEventArgs e)
{
var visual = ElementCompositionPreview.GetElementVisual(panel);
visual.Opacity = 0f;
visual.ImplicitAnimations = _implicitAnimations1st;
visual.CenterPoint = new Vector3((float)(panel.DesiredSize.Width / 2), (float)(panel.DesiredSize.Height / 2), 0);
visual.Offset = new Vector3((float)-panel.DesiredSize.Width, (float)-panel.DesiredSize.Height, 0);
}
private void rootPanel_Loaded(object sender, RoutedEventArgs e)
{
_root = ElementCompositionPreview.GetElementVisual(rootPanel);
_pointLight = _compositor.CreatePointLight();
_pointLight.Offset = new Vector3(-2500f, -2500f, 300f);
_pointLight.Intensity = 1.3f;
IGraphicsEffect graphicsEffect = new CompositeEffect()
{
Mode = CanvasComposite.DestinationIn,
Sources =
{
new CompositeEffect()
{
Mode = CanvasComposite.Add,
Sources =
{
new CompositionEffectSourceParameter("ImageSource"),
new SceneLightingEffect()
{
AmbientAmount = 0,
DiffuseAmount = .5f,
SpecularAmount = 0,
NormalMapSource = new CompositionEffectSourceParameter("NormalMap"),
}
}
},
new CompositionEffectSourceParameter("NormalMap"),
}
};
_effectFactory = _compositor.CreateEffectFactory(graphicsEffect);
//Comment Out the rest of the two lines can remove light effect
_pointLight.CoordinateSpace = _root;
_pointLight.Targets.Add(_root);
#region First light animation
Vector3KeyFrameAnimation lightPositionAnimation;
lightPositionAnimation = _compositor.CreateVector3KeyFrameAnimation();
lightPositionAnimation.InsertKeyFrame(.0f, new Vector3(200f, 700f, lightDepth), _compositor.CreateLinearEasingFunction());
lightPositionAnimation.InsertKeyFrame(1f, new Vector3(200f, 700f, lightDepth), _compositor.CreateLinearEasingFunction());
lightPositionAnimation.DelayTime = TimeSpan.FromMilliseconds(animationDelay);
lightPositionAnimation.Duration = TimeSpan.FromSeconds(animationDuration);
lightPositionAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
_pointLight.StartAnimation("Offset", lightPositionAnimation);
#endregion
}
}
我该如何解决?