Example #1
0
        private static void PrepareAnimations(FrameworkElement element, bool useSecondaryAnimation = false)
        {
            if (element == null)
            {
                return;
            }

            // Make sure to not start an animation when an element is not visible
            if (element.Visibility != Visibility.Visible)
            {
                return;
            }

            // Make sure to stop any running animations
            if (_actives.IsElementAnimating(GetElementGuid(element)))
            {
                foreach (var active in _actives.GetAllNonIteratingActiveTimelines(GetElementGuid(element)))
                {
                    active.Timeline.Stop();
                }
            }

            var animationSettings = element.GetSettings(
                useSecondaryAnimation ? SettingsTarget.Secondary : SettingsTarget.Primary,
                getPrimaryFunc: GetPrimary,
                getSecondaryFunc: GetSecondary);

            // Settings can be null if a Trigger is set before the associated element is loaded
            if (animationSettings == null)
            {
                return;
            }

            var settingsList      = animationSettings.ToSettingsList();
            var startFirst        = true;
            var iterationBehavior = GetIterationBehavior(element);
            var iterationCount    = GetIterationCount(element);
            var sequenceCounter   = 0;

            foreach (var settings in settingsList)
            {
                var isSequence = settingsList.Count > 1;

                // The "first" animation must always run immediately
                if (startFirst)
                {
                    RunAnimation(element, settings, isSequence);

                    startFirst = false;
                }
                else
                {
                    _actives.Add(null, settings, element, AnimationState.Idle, iterationBehavior, iterationCount, isSequence, sequenceOrder: sequenceCounter);
                }

                sequenceCounter++;
            }
        }
Example #2
0
        // This can be called from the three main entry-points (Primary, Secondary, and StartWith)
        private static void InitializeElement(FrameworkElement element)
        {
            if (GetIsInitialized(element))
            {
                return;
            }

            // Set IsInitialized to true to only run this code once per element
            SetIsInitialized(element, true);

#if __UWP__
            // The new way of handling translate animations (see Translation property section):
            // https://blogs.windows.com/buildingapps/2017/06/22/sweet-ui-made-possible-easy-windows-ui-windows-10-creators-update/
            ElementCompositionPreview.SetIsTranslationEnabled(element, true);
#endif

            element
            .Events()
            .LoadedUntilUnloaded
            .Take(1)
            .Subscribe(
                args =>
            {
                // Perform validations on element's attached properties
                Validate(element);

                var startSettings = element.GetSettings(SettingsTarget.StartWith, getStartWithFunc: GetStartWith);

                // If any StartWith settings were specified, apply them
                if (startSettings != null)
                {
                    element.ApplyInitialSettings((AnimationSettings)startSettings);
                }
            },
                ex => Logger.ErrorException($"Error on subscription to the {nameof(FrameworkElement.Loaded)} event of {nameof(FrameworkElement)}", ex)
                );

            element
            .Observe(UIElement.VisibilityProperty)
            .TakeUntil(element.Events().UnloadedMaterialized)
            .Subscribe(
                _ =>
            {
                var isVisible   = element.Visibility == Visibility.Visible;
                var elementGuid = GetElementGuid(element);

                if (isVisible && _actives.GetNextIdleActiveTimeline(elementGuid)?.Timeline is Timeline idle)
                {
                    RunNextAnimation(idle, element);
                }
            },
                ex => Logger.ErrorException($"Error on subscription to the {nameof(FrameworkElement.Visibility)} changes of {nameof(FrameworkElement)}", ex)
                );

#if __UWP__
            element
            .Events()
            .SizeChanged
            .TakeUntil(element.Events().UnloadedMaterialized)
            .Subscribe(
                args =>
            {
                // If the element child is a SpriteVisual, maintain its size so update any effects applied
                if (args.Sender is FrameworkElement elem &&
                    ElementCompositionPreview.GetElementChildVisual(elem) is SpriteVisual sprite)
                {
                    sprite.Size = new Vector2((float)elem.ActualWidth, (float)elem.ActualHeight);
                }
            },
                ex => Logger.ErrorException($"Error on subscription to the {nameof(FrameworkElement.SizeChanged)} event of {nameof(FrameworkElement)}", ex)
                );
#endif
        }