T CacheAndInitializeKeyframeAnimation <T>(KeyFrameAnimation_ source, T target) where T : KeyFrameAnimation_ { CacheAndInitializeAnimation(source, target); target.Duration = source.Duration; return(target); }
public static void WithKeyFrame( TranslationContext context, CompositionObject compObject, string target, KeyFrameAnimation_ animation, double scale = 1, double offset = 0) { Debug.Assert(offset >= 0, "Precondition"); Debug.Assert(scale <= 1, "Precondition"); Debug.Assert(animation.KeyFrameCount > 0, "Precondition"); var state = context.GetStateCache <StateCache>(); // Start the animation ... compObject.StartAnimation(target, animation); // ... but pause it immediately so that it doesn't react to time. Instead, bind // its progress to the progress of the composition. var controller = compObject.TryGetAnimationController(target); controller !.Pause(); // Bind it to the root visual's Progress property, scaling and offsetting if necessary. var key = new ScaleAndOffset(scale, offset); if (!state.ProgressBindingAnimations.TryGetValue(key, out var bindingAnimation)) { bindingAnimation = context.ObjectFactory.CreateExpressionAnimation(ExpressionFactory.ScaledAndOffsetRootProgress(scale, offset)); bindingAnimation.SetReferenceParameter(ExpressionFactory.RootName, context.RootVisual !); if (context.AddDescriptions) { // Give the animation a nice readable name in codegen. var name = key.Offset != 0 || key.Scale != 1 ? "RootProgressRemapped" : "RootProgress"; bindingAnimation.SetName(name); } state.ProgressBindingAnimations.Add(key, bindingAnimation); } // Bind the controller's Progress with a single Progress property on the scene root. // The Progress property provides the time reference for the animation. controller.StartAnimation("Progress", bindingAnimation); }