Странное непрозрачное поведение анимации после добавления эффекта Composition Light
Так что в настоящее время я использую композицию Windows Apis для создания "постепенной" анимации, комбинирующей масштабную анимацию и анимацию непрозрачности, с моим пользовательским элементом управления, который работал отлично. Однако недавно я попытался добавить некоторый эффект освещения, но по какой-то причине анимация непрозрачности больше не работает.
Как вы можете видеть, вы можете видеть изображение во время "постепенного" анимации без светового эффекта. Но как только вы добавите световой эффект, вы не сможете увидеть его, пока не закончится анимация "постепенного появления". Должно быть, это какая-то механика композиционной анимации, но я просто использовал их неправильно.
Вы можете воспроизвести код здесь
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
}
}
Как мне это исправить?
1 ответ
Через несколько дней после публикации проблемы в качестве репозитория на github-репозитории интерфейса пользователя Windows один из разработчиков интерфейса Windows предложил решение для устранения такого вопроса.
Цитата от этого разработчика:
Элементы, которые в данный момент не нацелены или не освещены точечным источником света при анимации, будут выглядеть черными. Для освещения окружающего изображения, на которое не распространяется естественный свет, используйте окружающий свет в сочетании с другими источниками света.
_ambientLight = _compositor.CreateAmbientLight ();
_ambientLight.Targets.Add (_root);
После добавления такого кода в мой проект это действительно решило проблему.