1

因此,我目前正在使用 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

}
}

我该如何解决?

4

1 回答 1

0

在 Windows UI 的 github repo 上发布问题后等待几天,其中一位 Windows UI 开发人员提供了解决此类问题的解决方案。

来自该开发商的报价:

动画时当前没有被点光源瞄准或被点光源照亮的项目将显示为黑色。要以自然的方式照亮灯光未瞄准的周围视觉效果,请将环境光与其他灯光结合使用。

_ambientLight = _compositor.CreateAmbientLight();

_ambientLight.Targets.Add(_root);

在我的项目中添加这样的代码后,它确实解决了问题。

于 2018-04-03T23:48:21.037 回答