void OnButton3Clicked(object sender, EventArgs args)
        {
            Button button = (Button)sender;

            // Create parent animation object.
            Animation parentAnimation = new Animation();

            // Create "up" animation and add to parent.
            Animation upAnimation = new Animation(
                v => button.Scale = v,
                1, 5, Easing.SpringIn,
                () => Debug.WriteLine("up finished"));

            parentAnimation.Add(0, 0.5, upAnimation);

            // Create "down" animation and add to parent.
            Animation downAnimation = new Animation(
                v => button.Scale = v,
                5, 1, Easing.SpringOut,
                () => Debug.WriteLine("down finished"));

            parentAnimation.Insert(0.5, 1, downAnimation);

            // Commit parent animation
            parentAnimation.Commit(
                this, "Animation3", 16, 5000, null,
                (v, c) => Debug.WriteLine("parent finished: {0} {1}", v, c));
        }
Example #2
0
        private void AnimateHeart(Label heart, string heartRedColor, string heartGrayColor, Ellipse ellipse)
        {
            var          parentAnimation = new Animation();
            const double startScale      = 1.0;
            const double endScale        = 1.5;

            var colorHeartScaleUpAnimation = new Animation(d => { heart.Scale = d; }, startScale, endScale,
                                                           Easing.SpringOut, () =>
            {
                heart.TextColor = (Color.FromHex(heartRedColor) == heart.TextColor)
                        ? Color.FromHex(heartGrayColor)
                        : Color.FromHex(heartRedColor);
            });
            var colorHeartScaleDownAnimation =
                new Animation(d => { heart.Scale = d; }, endScale, startScale, Easing.SpringOut);


            var ellipseFadeIn = new Animation(d => { ellipse.Opacity = d; }, 0, 0.5, Easing.SpringOut);

            var ellipseFadeOut = new Animation(d => { ellipse.Opacity = d; }, 0.5, 0, Easing.SpringOut);

            parentAnimation.Add(0.0, 0.3, ellipseFadeIn);
            parentAnimation.Add(0.3, 0.5, ellipseFadeOut);
            parentAnimation.Add(0.0, 0.5, colorHeartScaleUpAnimation);
            parentAnimation.Add(0.5, 1.0, colorHeartScaleDownAnimation);

            parentAnimation.Commit(this, nameof(AnimateHeart), FrameRate, 900, Easing.SpringOut,
                                   (d, b) =>
            {
                //do nothing
            });
        }
        private void Button_Clicked_4(object sender, EventArgs e)
        {
            var width = Application.Current.MainPage.Width;

            var storyboard = new Animation();
            var rotation   = new Animation(callback: d => a2.Rotation = d,
                                           start: a2.Rotation,
                                           end: a2.Rotation + 360,
                                           easing: Easing.SpringOut);


            var exitRight = new Animation(callback: d => a2.TranslationX = d,
                                          start: 0,
                                          end: width,
                                          easing: Easing.SpringIn);

            var enterLeft = new Animation(callback: d => a2.TranslationX = d,
                                          start: -width,
                                          end: 0,
                                          easing: Easing.BounceOut);

            storyboard.Add(0, 1, rotation);
            storyboard.Add(0, 0.5, exitRight);
            storyboard.Add(0.5, 1, enterLeft);

            storyboard.Commit(a2, "Loop", length: 1400);
        }
        public async Task OnPhoneHangedUp(bool isOnThePhone)
        {
            Animation animation = new Animation();

            animation.Add(0.4, 1, new Animation(v => imageGrid.Opacity = v, 1, 0));

            if (isOnThePhone)
            {
                animation.Add(0.5, 1, new Animation(v => topLabel.TranslationX = v, topLabel.TranslationX, -topLabel.Width));
            }
            else
            {
                animation.Add(0, 0.8, new Animation(v => centerLabel.Opacity = v, 1, 0));
                animation.Add(0, 1, new Animation(v => imageGrid.Scale       = v, imageGrid.Scale, 0, easing: Easing.SpringIn));
            }

            animation.Commit(this, "HangedUpAnimation", length: 700);

            await Task.Delay(700);

            imageGrid.TranslationX = 0;
            imageGrid.TranslationY = 0;

            topLabel.Opacity = 0;
            IsVisible        = true;
        }
Example #5
0
        /// <summary>
        /// Create closing animations for modal background and popup
        /// </summary>
        private Animation CreateClosingAnimation()
        {
            Animation animationGroup = new Animation();

            if (ClosingAnimation != null)
            {
                if (ClosingAnimation is IAnimation popupAnimation)
                {
                    animationGroup.Add(0, 1, popupAnimation.Create(_popupRootLayout));
                }
                else
                {
                    animationGroup.Add(0, 1, ClosingAnimation.Create(_popupRootLayout));
                }

                Animation modalAnim = PopupLayout.CreateModalBackgroundAnimation(false);
                if (ClosingAnimation.Duration > 0 && modalAnim != null && HasModalBackground)
                {
                    animationGroup.Add(0, 1, modalAnim);
                }
            }

            if (animationGroup.HasSubAnimations())
            {
                return(animationGroup);
            }
            else
            {
                return(null);
            }
        }
Example #6
0
        public SplashPage()
        {
            Button button = new Button();

            button.Clicked += (sender, args) =>
            {
                var width = Application.Current.MainPage.Width;

                var playingaround = new Animation();
                //rotates the button image once pressed
                var rotation = new Animation(callback: d => button.Rotation = d,
                                             start: button.Rotation,
                                             end: button.Rotation + 360,
                                             easing: Easing.SpringOut);

                //the image exits to the right
                var exitRight = new Animation(callback: d => button.TranslationX = d,
                                              start: 0,
                                              end: width,
                                              easing: Easing.SpringIn);

                //the image returns from the left
                var enterLeft = new Animation(callback: d => button.TranslationX = d,
                                              start: -width,
                                              end: 0,
                                              easing: Easing.BounceOut);

                playingaround.Add(0, 1, rotation);
                playingaround.Add(0, 0.5, exitRight);
                playingaround.Add(0.5, 1, enterLeft);

                playingaround.Commit(button, "Loop", length: 1400);
            };

            //Layout of the Home page(PrincipalPage.cs)
            Title = "Loading Screen";
            Icon  = new FileImageSource()
            {
                File = "robot.png"
            };
            NavigationPage.SetBackButtonTitle(this, "go back");
            //this is the type of layout the grids will be specified in
            var stackLayout = new StackLayout
            {
                //Orientation = StackOrientation.Vertical,
                BackgroundColor = Color.Teal,
                Spacing         = 10,
                Padding         = 1,
                Children        =
                {
                    button,
                    new Label()
                    {
                        Text = "click to see what happens",BackgroundColor                                  = Color.Gray
                    }
                }
            };

            this.Content = stackLayout;
        }
        private void buttonListAnimation_Click(object sender, EventArgs e)
        {
            AnimatedDecoration listAnimation = new AnimatedDecoration(this.olvSimple);
            Animation          animation     = listAnimation.Animation;

            //Sprite image = new ImageSprite(Resource1.largestar);
            //image.FixedLocation = Locators.SpriteAligned(Corner.MiddleCenter);
            //image.Add(0, 2000, Effects.Rotate(0, 360 * 2f));
            //image.Add(1000, 1000, Effects.Fade(1.0f, 0.0f));
            //animation.Add(0, image);

            Sprite image = new ImageSprite(Resource1.largestar);

            image.Add(0, 500, Effects.Move(Corner.BottomCenter, Corner.MiddleCenter));
            image.Add(0, 500, Effects.Rotate(0, 180));
            image.Add(500, 1500, Effects.Rotate(180, 360 * 2.5f));
            image.Add(500, 1000, Effects.Scale(1.0f, 3.0f));
            image.Add(500, 1000, Effects.Goto(Corner.MiddleCenter));
            image.Add(1000, 900, Effects.Fade(1.0f, 0.0f));
            animation.Add(0, image);

            Sprite text = new TextSprite("Animations!", new Font("Tahoma", 32), Color.Blue, Color.AliceBlue, Color.Red, 3.0f);

            text.Opacity       = 0.0f;
            text.FixedLocation = Locators.SpriteAligned(Corner.MiddleCenter);
            text.Add(900, 900, Effects.Fade(0.0f, 1.0f));
            text.Add(1000, 800, Effects.Rotate(180, 1440));
            text.Add(2000, 500, Effects.Scale(1.0f, 0.5f));
            text.Add(3500, 1000, Effects.Scale(0.5f, 3.0f));
            text.Add(3500, 1000, Effects.Fade(1.0f, 0.0f));
            animation.Add(0, text);

            animation.Start();
        }
Example #8
0
        private void MenuMoveDown_Click(object sender, EventArgs e)
        {
            var index = ListFrame.SelectedIndex;

            // Se o item não for o último da lista.
            if (index >= 0 && index < animation.Count(selectedLayerIndex) - 1)
            {
                var frame = animation[selectedLayerIndex, index];

                animation.RemoveLayerFrame(selectedLayerIndex, index);

                // Como o item foi removido.
                // Verifica se ultrapassou a quantidade de items adicionados.
                // Caso verdadeiro, insere novamente para ir para a última posição.
                if (index + 1 >= animation.Count(selectedLayerIndex))
                {
                    animation.Add(selectedLayerIndex, (frame));
                }
                else
                {
                    // Caso contrário, insere na posição especificada.
                    animation.Insert(selectedLayerIndex, index + 1, frame);
                }

                // Atualiza o novo índice.
                selectedItemIndex = -1;

                UpdateListFrame();
            }
        }
Example #9
0
        protected override async void OnAppearing()
        {
            base.OnAppearing();
            MainStack.TranslationY = 640;
            if (Device.RuntimePlatform == Device.Android)
            {
                await Task.Delay(100);
            }

            //Button.FadeTo(1, 3000, Easing.CubicIn);
            //LblEntry.RotateTo(180, 250, Easing.CubicIn);
            //Button.ScaleTo(10);
            MainStack.TranslateTo(0, 0, 500, Easing.SpringOut);


            var parentAnimacion = new Animation();


            var fadetoAnimation   = new Animation(v => Button.Opacity = v, 0, 1, Easing.BounceOut);
            var rotateToAnimation = new Animation(v => LblEntry.FontSize = v, 14, 50, Easing.SpringIn);

            parentAnimacion.Add(0, 1, fadetoAnimation);
            parentAnimacion.Add(0.5, 1, rotateToAnimation);


            parentAnimacion.Commit(this, "myAnimation", 16, 3000, Easing.CubicIn);
        }
Example #10
0
        /// <summary>
        /// animate a dashed storke animation form the "from" dashed stroke to the "to" dashes stroke
        /// </summary>
        /// <param name="onValueCallback">the callback to set the changed dashed stroke</param>
        /// <returns>a task contains the animation</returns>
        public Task <bool> Start(Action <DashedStroke> onValueCallback)
        {
            _strokeDash = From;

            var taskCompletionSource = new TaskCompletionSource <bool>();
            var anim = new Animation(_ => onValueCallback(_strokeDash));

            anim.Add(0, 1, new Animation(
                         callback: v => _strokeDash.Phase = (float)v,
                         start: From.Phase,
                         end: To.Phase,
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _strokeDash.Intervals[0] = (float)v,
                         start: From.Intervals[0],
                         end: To.Intervals[0],
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _strokeDash.Intervals[1] = (float)v,
                         start: From.Intervals[1],
                         end: To.Intervals[1],
                         easing: Easing));

            anim.Commit(
                owner: Application.Current.MainPage,
                name: "highlightAnimation",
                length: Duration,
                easing: Easing,
                finished: (v, c) => taskCompletionSource.SetResult(c));

            return(taskCompletionSource.Task);
        }
Example #11
0
        private void PresentEntryAnimation(uint duration)
        {
            var animationController   = new Animation();
            var fadeIconsBackDrop     = new Animation(v => BackDrop.Opacity = v, 0, 0.5, Easing.CubicIn);
            var fadeActivityIndicator = new Animation(v => ActivityIndicator.Opacity = v);

            animationController.Add(0.55, 1, fadeIconsBackDrop);
            animationController.Add(0.85, 1, fadeActivityIndicator);

            if (Device.RuntimePlatform == Device.Android)
            {
                var startColor     = new Color(1);
                var targetColor    = new Color(0.196, 0.639, 0.839);
                var tintBackground = new Animation(v => Container.LerpBackgroundColor(startColor, targetColor, v));
                var fadeLogo       = new Animation(v => Logo.Opacity = v);
                var rotateLogo     = new Animation(v => Logo.RotationY = v, -90, 0, Easing.BounceIn);

                animationController.Add(0, 0.65, tintBackground);
                animationController.Add(0.35, 0.8, fadeLogo);
                animationController.Add(0.5, 1, rotateLogo);
            }

            animationController.Commit(this, StartAnimation, 16, duration, finished: (d, b) =>
            {
                _startAnimationComplete = true;
                StartAnimationCompleteHandler?.Invoke(this, EventArgs.Empty);
            });
        }
Example #12
0
        private void PresentPage()
        {
            if (_hasFinishedAnimation)
            {
                return;
            }

            var animationController = new Animation();

            var fadeAnimation = new Animation(v => GridContainer.Opacity = v, 0, 1, Easing.CubicIn);

            var startOffset   = GridContainer.Height * 0.10;
            var containerMove = new Animation(
                v => GridContainer.TranslationY = Lerp(startOffset, 0, v),
                0, 1,
                Easing.CubicInOut);

            animationController.Add(0, 0.65, fadeAnimation);
            animationController.Add(0, 1, containerMove);

            animationController.Commit(this, AnimationEnter,
                                       16, 500, null,
                                       async(d, b) =>
            {
                await Task.Delay(500);
                CodeEntry.Focus();
                _hasFinishedAnimation = true;
            });
        }
        void onLogoTap(object sender, System.EventArgs args)
        {
            try
            {
                Image savLogo = (Image)sender;

                // Dirty hack you probably shouldn't use
                var width = Application.Current.MainPage.Width;

                var storyboard = new Animation();

                if (Accueil.buttonValeur != "accueil")
                {
                    var rotation = new Animation(callback: d => savLogo.Rotation = d,
                                                 start: 0,
                                                 end: 380,
                                                 easing: Easing.SpringOut);

                    var rotation2 = new Animation(callback: d => savLogo.Rotation = d,
                                                  start: 380,
                                                  end: 360,
                                                  easing: Easing.SpringOut);

                    storyboard.Add(0, 0.85, rotation);
                    storyboard.Add(0.85, 1, rotation2);


                    storyboard.Commit(savLogo, "Loop", 16, length: 600, Easing.Linear, (v, c) => finLogo());
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
        private void creditCard_NextStep(object sender, EventArgs e)
        {
            // move the current stuff off the screen
            var onscreencreditCardSlideOut = new Animation(v => creditCard.TranslationX = v, 0, -this.Width, Easing.SinIn);
            var onscreencreditCardFade     = new Animation(v => creditCard.Opacity = v, 1, 0, Easing.SinIn);

            // move the offscreen stuff onto the screen
            var offscreenLastStepSlideIn = new Animation(v => LastStep.TranslationX = v, this.Width, 0, Easing.SinOut);
            var offscreenLastStepFadeIn  = new Animation(v => LastStep.Opacity = v, 0, 1, Easing.SinOut);

            var parentAnimation = new Animation();

            // outgoing child animations
            parentAnimation.Add(0, 1, onscreencreditCardSlideOut);
            parentAnimation.Add(0, .5, onscreencreditCardFade);
            // inbound child animations
            parentAnimation.Add(.2, 1, offscreenLastStepSlideIn);
            parentAnimation.Add(.2, 1, offscreenLastStepFadeIn);


            // animation for skia elements
            var skiaAnimation = new Animation(
                callback: v =>
            {
                LastStep.IsVisible = true;
                step = Steps.third;
                skiaBar.InvalidateSurface();
            }, start: 0, end: 1, easing: Easing.SinInOut);

            parentAnimation.Add(0, 1, skiaAnimation);

            parentAnimation.Commit(this, "creditCardTransitionAnimation", 16, 500, null);
        }
Example #15
0
        /// <summary>
        /// Create opening animations for modal background and popup
        /// </summary>
        private Animation CreateOpeningAnimation()
        {
            Animation animationGroup = new Animation();

            if (OpeningAnimation != null)
            {
                if (OpeningAnimation is IAnimation popupAnimation)
                {
                    animationGroup.Add(0, 1, popupAnimation.Create(_popupRootLayout));
                }
                else
                {
                    animationGroup.Add(0, 1, OpeningAnimation.Create(_popupRootLayout));
                }

                Animation backgroundAnimation = PopupLayout.CreateModalBackgroundAnimation(true);
                if (backgroundAnimation != null && HasModalBackground)
                {
                    animationGroup.Add(0, 1, backgroundAnimation);
                }
            }

            if (animationGroup.HasSubAnimations())
            {
                return(animationGroup);
            }
            else
            {
                return(null);
            }
        }
        private void SwipeGestureRecognizer_Swiped(object sender, SwipedEventArgs e)
        {
            // see if the animation is running
            if (this.AnimationIsRunning("TransitionAnimation"))
            {
                return;
            }

            // update the elements
            UpdateOffScreenElements();

            // user has swipped
            var onScreenHeadingSlideOut = new Animation(v => currentHeading.TranslationX = v, 0, -this.Width, Easing.SinIn);
            var onScreenHeadingFadeOut  = new Animation(v => currentHeading.Opacity = v, 1, 0, Easing.SinIn);
            var onScreenBodySlideOut    = new Animation(v => currentBody.TranslationX = v, 0, -this.Width, Easing.SinIn);
            var onScreenBodyFadeOut     = new Animation(v => currentBody.Opacity = v, 1, 0, Easing.SinIn);

            var offScreenHeadingSlideIn = new Animation(v => offscreenHeading.TranslationX = v, this.Width, 0, Easing.SinIn);
            var offScreenHeadingFadeIn  = new Animation(v => offscreenHeading.Opacity = v, 0, 1, Easing.SinIn);
            var offScreenBodySlideIn    = new Animation(v => offscreenBody.TranslationX = v, this.Width, 0, Easing.SinIn);
            var offScreenBodyFadeIn     = new Animation(v => offscreenBody.Opacity = v, 0, 1, Easing.SinIn);

            // animation for skia
            var skiaAnimation = new Animation(
                callback: v =>
            {
                transitionValue = v;
                ImageSkiaCanvas.InvalidateSurface();
            }, start: 0, end: 2);

            var outgoingImageAnimation = new Animation(
                callback: v =>
            {
                outgoingImageOffset = v;
                ImageSkiaCanvas.InvalidateSurface();
            }, start: 0, end: this.Width);

            var parentAnimation = new Animation();

            parentAnimation.Add(0, 1, onScreenHeadingSlideOut);
            parentAnimation.Add(0, 1, onScreenHeadingFadeOut);
            parentAnimation.Add(.2, 1, onScreenBodySlideOut);
            parentAnimation.Add(0, 1, onScreenBodyFadeOut);

            parentAnimation.Add(0, 1, offScreenHeadingSlideIn);
            parentAnimation.Add(0, 1, offScreenHeadingFadeIn);
            parentAnimation.Add(.2, 1, offScreenBodySlideIn);
            parentAnimation.Add(0, 1, offScreenBodyFadeIn);

            parentAnimation.Add(0, 1, skiaAnimation);
            parentAnimation.Add(0.5, 1, outgoingImageAnimation);

            parentAnimation.Commit(this, "TransitionAnimation", 16, 800, null,
                                   (v, c) =>
            {
                viewModel.MoveNext();
                CycleElement();
                currentBitmap = offscreenBitmap;
            });
        }
Example #17
0
        public void RenderAnimation()
        {
            GameCell gameCell  = null;
            var      animation = new Animation();

            game.LastTransforms.ForEach(transform =>
            {
                //translate && merge
                if (transform.Type != TransformType.New)
                {
                    gameCell = gameCells[transform.LastY, transform.LastX];
                    animation.Add(0, 0.3, gameCell.AnimateTranslation(transform));
                }

                if (transform.Type == TransformType.Merge)
                {
                    gameCell = AddGameCell(game.GameBoard[transform.Y, transform.X], transform.X, transform.Y);
                    animation.Add(0.2, 0.6, gameCell.AnimateNew());
                }

                if (transform.Type == TransformType.New)
                {
                    gameCell = AddGameCell(game.GameBoard[transform.Y, transform.X], transform.X, transform.Y);
                    animation.Add(0.6, 1, gameCell.AnimateNew());
                }
            });

            animation.Commit(this, "gameCellsTransforms", 16, 400, null, (arg1, arg2) => Render());
        }
        public async Task AnimateAnswerImage(bool is_correct)
        {
            if (this.AnimationIsRunning("TransitionAnimationAnswer"))
            {
                return;
            }
            await QuestionCustomTimer.StopTimer();

            string answer_correct   = "https://cdn.pixabay.com/photo/2012/04/24/13/49/tick-40143_960_720.png";
            string answer_incorrect = "https://cdn.pixabay.com/photo/2012/04/13/00/22/red-31226_960_720.png";

            string answer = is_correct ? answer_correct : answer_incorrect;

            AnswerImage.Source  = ImageSource.FromUri(new Uri(answer));
            AnswerImage.Opacity = 1;

            var AnswerImageScalingIn  = new Animation(v => AnswerImage.Scale = v, 1, 5, Easing.SpringOut);
            var AnswerImageScalingOut = new Animation(v => AnswerImage.Scale = v, 5, 4, Easing.SpringOut);
            var AnswerImageFading     = new Animation(v => AnswerImage.Opacity = v, 1, 0, Easing.SpringOut);

            var parentAnimation = new Animation();

            parentAnimation.Add(0, 0.7, AnswerImageScalingIn);
            parentAnimation.Add(0.7, 1, AnswerImageScalingOut);
            parentAnimation.Add(0.6, 1, AnswerImageFading);

            parentAnimation.Commit(this, "TransitionAnimationAnswer", 16, 1000, null, (v, c) => { });
            await Task.Delay(1000);

            await ShowResult();
        }
Example #19
0
        public void Start(Action <StrokeDash> onValueCallback)
        {
            _currStrokeDash = From;

            var anim = new Animation(_ => onValueCallback(_currStrokeDash));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Phase = (float)v,
                         start: From.Phase,
                         end: To.Phase,
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Intervals[0] = (float)v,
                         start: From.Intervals[0],
                         end: To.Intervals[0],
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Intervals[1] = (float)v,
                         start: From.Intervals[1],
                         end: To.Intervals[1],
                         easing: Easing));

            anim.Commit(
                owner: Application.Current.MainPage,
                name: "highlightAnimation",
                length: (uint)Duration.TotalMilliseconds);
        }
        /// <summary>
        /// Setup the Dice Animation
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public bool DiceAnimationHandeler()
        {
            // Animate the Rolling of the Dice
            ImageButton image    = RollDice;
            uint        duration = 1000;

            var parentAnimation = new Animation();

            // Grow the image Size
            var scaleUpAnimation = new Animation(v => image.Scale = v, 1, 2, Easing.SpringIn);

            // Spin the Image
            var rotateAnimation = new Animation(v => image.Rotation = v, 0, 360);

            // Shrink the Image
            var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SpringOut);

            parentAnimation.Add(0, 0.5, scaleUpAnimation);
            parentAnimation.Add(0, 1, rotateAnimation);
            parentAnimation.Add(0.5, 1, scaleDownAnimation);

            parentAnimation.Commit(this, "ChildAnimations", 16, duration, null, null);

            return(true);
        }
Example #21
0
        //public static Animation[] CreateAnimations()
        //{
        //    return new Animation[] { Error() };

        //}
        public static Animation Error()
        {
            Animation animation = new Animation();

            animation.Name     = "ERROR";
            animation.Duration = 5000;
            animation.Text     = "ERROR!!!";

            Effect effect = new Effect();

            effect.KeyName = "ToScreen_X";
            effect.End     = 1000;
            effect.Number  = 200;
            animation.Add(effect);

            effect         = new Effect();
            effect.KeyName = "ToScreen_Y";
            effect.End     = 1000;
            effect.Number  = 250;
            animation.Add(effect);

            effect         = new Effect();
            effect.KeyName = "MoveToAxeY";
            effect.End     = 1000;
            effect.Number  = 250;
            animation.Add(effect);

            return(animation);
        }
Example #22
0
        private Animation GetExpandAnimation()
        {
            var iconAnimationTime = (1 - SlideAnimationDuration) / _menuItemsView.Count();
            var animation         = new Animation
            {
                { 0, SlideAnimationDuration, new Animation(v => ToolbarSafeAreaRow.Height = v, _safeInsetsTop, 0) },
                {
                    0, SlideAnimationDuration,
                    new Animation(v => Page.TranslationX = v, 0, Device.Info.ScaledScreenSize.Width * PageTranslation)
                },
                { 0, SlideAnimationDuration, new Animation(v => Page.Scale = v, 1, PageScale) },
                {
                    0, SlideAnimationDuration,
                    new Animation(v => Page.Margin = new Thickness(0, v, 0, 0), 0, _safeInsetsTop)
                },
                { 0, SlideAnimationDuration, new Animation(v => Page.CornerRadius = (float)v, 0, 5) }
            };

            foreach (var view in _menuItemsView)
            {
                var index = _menuItemsView.IndexOf(view);
                animation.Add(SlideAnimationDuration + iconAnimationTime * index - 0.05,
                              SlideAnimationDuration + iconAnimationTime * (index + 1) - 0.05, new Animation(
                                  v => view.Opacity = (float)v, 0, 1));
                animation.Add(SlideAnimationDuration + iconAnimationTime * index,
                              SlideAnimationDuration + iconAnimationTime * (index + 1), new Animation(
                                  v => view.TranslationY = (float)v, -10, 0));
            }

            return(animation);
        }
        void animate1()
        {
            var a = new Animation();

            a.Add(0, 0.5, new Animation((v) =>
            {
                ParentLayout1.TranslationY = v;
            }, _thisContainerHeight, -10, Easing.CubicInOut, () =>
            {
                ParentLayout1.RotationX = 180;
                System.Diagnostics.Debug.WriteLine("ANIMATION UPWARDS");
            }));

            a.Add(0.5, 1, new Animation((v) =>
            {
                ParentLayout1.TranslationY = v;
            }, -10, _thisContainerHeight, Easing.CubicInOut, () =>
            {
                ParentLayout1.RotationX = 0;
                System.Diagnostics.Debug.WriteLine("ANIMATION DOWNWARDS");
            }));

            a.Commit(ParentLayout1, "animation", 16, 2500, null, (d, f) =>
            {
                ParentLayout1.TranslationY = _thisContainerHeight;
                System.Diagnostics.Debug.WriteLine("ANIMATION COMPLETED AND REPEATING NOW");

                animate1();
            });
        }
Example #24
0
        public Task OnSelectionChanged(TransitionSelectionChangedArgs args)
        {
            if (args.Status == TransitionSelectionChanged.Reset)
            {
                var tcs = new TaskCompletionSource <bool>();

                Device.BeginInvokeOnMainThread(() =>
                {
                    Animation resetAnimation = new Animation();

                    var animationPercentLength = AnimationLength;

                    if (args.CurrentView != null)
                    {
                        resetAnimation.Add(0, 1, new Animation(v => args.CurrentView.TranslationY = v, args.CurrentView.TranslationY, 0));
                    }

                    if (args.NextView != null)
                    {
                        resetAnimation.Add(0, 1, new Animation(v => args.NextView.TranslationY = v, args.NextView.TranslationY, Math.Sign((int)args.Direction) * args.Parent.Height));
                        animationPercentLength = (uint)(AnimationLength * (args.Parent.Height - Math.Abs(args.NextView.TranslationY)) / args.Parent.Height);
                    }

                    resetAnimation.Commit(args.Parent, nameof(OnSelectionChanged), length: animationPercentLength, easing: AnimationEasing,
                                          finished: (v, t) => tcs.SetResult(true));
                });

                return(tcs.Task);
            }

            if (args.Status == TransitionSelectionChanged.Completed)
            {
                var tcs = new TaskCompletionSource <bool>();

                Device.BeginInvokeOnMainThread(() =>
                {
                    Animation completeAnimation = new Animation();

                    var animationPercentLength = AnimationLength;

                    if (args.CurrentView != null)
                    {
                        completeAnimation.Add(0, 1, new Animation(v => args.CurrentView.TranslationY = v, args.CurrentView.TranslationY, -Math.Sign((int)args.Direction) * args.Parent.Height));
                        animationPercentLength = (uint)(AnimationLength * (args.Parent.Height - Math.Abs(args.CurrentView.TranslationY)) / args.Parent.Height);
                    }

                    if (args.NextView != null)
                    {
                        completeAnimation.Add(0, 1, new Animation(v => args.NextView.TranslationY = v, args.NextView.TranslationY, 0));
                    }

                    completeAnimation.Commit(args.Parent, nameof(OnSelectionChanged), length: animationPercentLength, easing: AnimationEasing,
                                             finished: (v, t) => tcs.SetResult(true));
                });

                return(tcs.Task);
            }

            return(Task.FromResult(true));
        }
Example #25
0
        private void addClick(AnimationFrameEditor obj)
        {
            if (animation == null)
            {
                MessageBox.Show("You must create an animation first.", "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            AddClick?.Invoke(this);

            if (Selection == null || Selection.Length <= 0)
            {
                return;
            }

            if (obj.FrameMask == null)
            {
                animation.Add(Selection, 0);
            }
            else
            {
                animation.Add(Selection, obj.FrameMask.Index);
            }
            buildTable();
            _Animation = animation;
        }
 private void MakeAndCommitSymbolAnimation()
 {
     _symbolAnimation = new Animation();
     _symbolAnimation.Add(0, 0.2, new Animation(v => BGSymbolImage.Opacity = v, 1, 0, Easing.SinOut));
     _symbolAnimation.Add(0.8, 1, new Animation(v => BGSymbolImage.Opacity = v, 0, 1, Easing.SinIn));
     AddSymbolAnimation(Symbol1, 0, 0.8);
     AddSymbolAnimation(Symbol2, 0.1, 0.9);
     AddSymbolAnimation(Symbol3, 0.3, 1);
     AddSymbolAnimation(Symbol4, 0.25, 0.95);
     AddSymbolAnimation(Symbol5, 0.15, 0.85);
     AddSymbolAnimation(Symbol6, 0.4, 1);
     AddSymbolAnimation(Symbol7, 0.2, 1);
     AddSymbolAnimation(Symbol8, 0.15, 0.95);
     AddSymbolAnimation(Symbol9, 0.4, 1);
     AddSymbolAnimation(Symbol1, 0.4, 1);
     AddSymbolAnimation(Symbol2, 0.5, 1);
     AddSymbolAnimation(Symbol3, 0.8, 1);
     AddSymbolAnimation(Symbol4, 0.65, 1);
     AddSymbolAnimation(Symbol5, 0.55, 1);
     AddSymbolAnimation(Symbol6, 0.9, 1);
     AddSymbolAnimation(Symbol7, 0.6, 1);
     AddSymbolAnimation(Symbol8, 0.55, 1);
     AddSymbolAnimation(Symbol9, 0.8, 1);
     _symbolAnimation.Commit(this, "MultiAnimation", 16, 3000, null);
 }
Example #27
0
        private async void OnStartAnimationButtonClicked(object sender, EventArgs e)
        {
            CatchElementTransfProperties(image);
            SetIsEnabledButtonState(false, true, true);
            //simple animation
            //var animation = new Animation(v => image.Scale = v, 1, 2);
            //animation.Commit(this, "simpleAnimation", 16, 2000,
            //    Easing.Linear, (v, c) => image.Scale = 1, () => true);

            var parentAnimation    = new Animation();
            var scaleUpAnimation   = new Animation(v => image.Scale = v, 1, 2, Easing.SinIn);
            var rotateAnimation    = new Animation(v => image.Rotation = v, 0, 360, Easing.CubicIn);
            var reRotateAnimation  = new Animation(v => image.Rotation = v, 360, 0, Easing.CubicOut);
            var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SinOut);

            parentAnimation.Add(0, 0.5, scaleUpAnimation);
            parentAnimation.Add(0.5, 1, scaleDownAnimation);
            parentAnimation.Add(0, 0.5, rotateAnimation);
            parentAnimation.Add(0.5, 1, reRotateAnimation);

            parentAnimation.Commit(this, "ChildAnimation", 16, 4000, null,
                                   (v, c) =>
            {
                SetIsEnabledButtonState(true, false, false);
            });
        }
        public Animation Create(View target)
        {
            PopupRootLayout rootLayout = (PopupRootLayout)target;

            // If full screen popup which is closing
            if (rootLayout.Popup.IsOpen == false && rootLayout.Popup.ActualPlacement == PopupPlacements.FullScreen)
            {
                return(new Animation(d =>
                {
                    rootLayout.TranslationY = rootLayout.Height * d;
                }, 0, 1));
            }

            Animation animationGroup = new Animation();

            if (OpacityStartTime.Equals(OpacityEndTime) == false && OpacityStart != OpacityEnd && OpacityInit != OpacityEnd)
            {
                if (OpacityInit.HasValue)
                {
                    rootLayout.Opacity = OpacityInit.Value;
                }

                Animation fadeAnimation = new Animation(d =>
                {
                    rootLayout.Opacity = d;
                }, OpacityStart, OpacityEnd);

                animationGroup.Add(OpacityStartTime, OpacityEndTime, fadeAnimation);
            }

            double animatedValue = 0;

            if (SlideStartOffset != 0)
            {
                EventHandler sizeChanged = null;
                sizeChanged = (s, a) =>
                {
                    rootLayout.Content.TranslationY = CalculateTranslateY(animatedValue, rootLayout);
                };

                rootLayout.SizeChanged += sizeChanged;

                // Init TranslationY
                rootLayout.Content.TranslationY = CalculateTranslateY(0, rootLayout);

                Animation slideAnimation = new Animation(d =>
                {
                    animatedValue = d;
                    rootLayout.Content.TranslationY = CalculateTranslateY(d, rootLayout);
                }, 0, 1, AnimationUtils.EaseOutQuint, finished: () =>
                {
                    rootLayout.Content.SizeChanged -= sizeChanged;
                });

                animationGroup.Add(0, 1, slideAnimation);
            }

            return(animationGroup);
        }
        private Animation CreateBounceAnimation()
        {
            var animation = new Animation();

            animation.Add(0, 0.5, new Animation((r) => { Control.TranslationY = r; }, 0, -BounceHeight, Easing.SinOut));
            animation.Add(0.5, 1, new Animation((r) => { Control.TranslationY = r; }, -BounceHeight, 0, Easing.BounceOut));
            return(animation);
        }
Example #30
0
        /// <summary>
        /// Reflect the checked event change on the UI
        /// with a small animation
        /// </summary>
        /// <param name="isChecked"></param>
        ///
        void ApplyCheckedState()
        {
            Animation storyboard      = new Animation();
            Animation fadeAnim        = null;
            Animation checkBounceAnim = null;
            Animation checkFadeAnim   = null;
            double    fadeStartVal    = 0;
            double    fadeEndVal      = 1;
            double    scaleStartVal   = 0;
            double    scaleEndVal     = 1;
            Easing    checkEasing     = Easing.CubicIn;

            if (IsChecked)
            {
                checkedImage.Scale = 0;
                fadeStartVal       = 0;
                fadeEndVal         = 1;
                scaleStartVal      = 0;
                scaleEndVal        = 1;
                checkEasing        = Easing.CubicIn;
            }
            else
            {
                fadeStartVal  = 1;
                fadeEndVal    = 0;
                scaleStartVal = 1;
                scaleEndVal   = 0;
                checkEasing   = Easing.CubicOut;
            }
            fadeAnim = new Animation(
                callback: d => checkedBackground.Opacity = d,
                start: fadeStartVal,
                end: fadeEndVal,
                easing: Easing.CubicOut
                );
            checkFadeAnim = new Animation(
                callback: d => checkedImage.Opacity = d,
                start: fadeStartVal,
                end: fadeEndVal,
                easing: checkEasing
                );
            checkBounceAnim = new Animation(
                callback: d => checkedImage.Scale = d,
                start: scaleStartVal,
                end: scaleEndVal,
                easing: checkEasing
                );

            storyboard.Add(0, 0.6, fadeAnim);
            storyboard.Add(0, 0.6, checkFadeAnim);
            storyboard.Add(0.4, 1, checkBounceAnim);
            storyboard.Commit(this, "checkAnimation", length: 600);

            if (CheckedChangedCommand != null && CheckedChangedCommand.CanExecute(this))
            {
                CheckedChangedCommand.Execute(this);
            }
        }
Example #31
0
        private void RightToLeftAnimation()
        {
            if (!(FindByName("CoffeeList") is StackLayout coffeeListStackLayout))
            {
                return;
            }

            var parentAnimation = new Animation();
            var control         = coffeeListStackLayout;

            foreach (var item in control.Children)
            {
                if (!(item is Grid grid))
                {
                    return;
                }

                if (!(grid.Children.FirstOrDefault(i => i is Frame) is Frame frame))
                {
                    return;
                }

                var labels     = grid.Children.Where(i => i is Label);
                var enumerable = labels.ToList();

                if (enumerable.Count() < 3)
                {
                    return;
                }

                if (!(enumerable.First() is Label labelWebsite) ||
                    !(enumerable.Skip(1).Take(1).FirstOrDefault() is Label labelName) ||
                    !(enumerable.LastOrDefault() is Label labelPrice))
                {
                    return;
                }

                var movingLabelWebsiteToTheLeftAnimation = new Animation(d => { labelWebsite.TranslationX = d; },
                                                                         labelWebsite.TranslationX, 0, Easing.Linear);
                var movingLabelNameToTheLeftAnimation = new Animation(d => { labelName.TranslationX = d; },
                                                                      labelName.TranslationX, 0, Easing.Linear);
                var movingLabelPriceToTheLeftAnimation =
                    new Animation(d => { labelPrice.TranslationX = d; }, labelPrice.TranslationX, 0);
                var showingImageAnimation = new Animation(d => frame.Opacity = d, 0, 1);

                parentAnimation.Add(0.0, 1.0, movingLabelWebsiteToTheLeftAnimation);
                parentAnimation.Add(0.0, 1.0, movingLabelNameToTheLeftAnimation);
                parentAnimation.Add(0.0, 1.0, movingLabelPriceToTheLeftAnimation);
                parentAnimation.Add(0.9, 1.0, showingImageAnimation);
            }

            parentAnimation.Commit(control, nameof(RightToLeftAnimation), FrameRate, TotalAnimationDurationInMs,
                                   Easing.Linear,
                                   (d, b) =>
            {
                //do nothing
            });
        }
 private static Animation CreateGrid(int size, Rect rect)
 {
     var ani = new Animation();
     for (var i = 0; i < size; i++) {
         ani.Add(new LineSegmentDesc(new Point(GetX(i, size, rect), rect.Top).Sweep(new Vector(0, rect.Height)), Brushes.Gray, 1));
         ani.Add(new LineSegmentDesc(new Point(rect.Left, GetY(i, size, rect)).Sweep(new Vector(rect.Width, 0)), Brushes.Gray, 1));
     }
     return ani;
 }
		void OnStartAnimationButtonClicked(object sender, EventArgs e)
		{
			SetIsEnabledButtonState(false, true);

			var parentAnimation = new Animation();
			var scaleUpAnimation = new Animation(v => image.Scale = v, 1, 2, Easing.SpringIn);
			var rotateAnimation = new Animation(v => image.Rotation = v, 0, 360);
			var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SpringOut);

			parentAnimation.Add(0, 0.5, scaleUpAnimation);
			parentAnimation.Add(0, 1, rotateAnimation);
			parentAnimation.Add(0.5, 1, scaleDownAnimation);

			parentAnimation.Commit(this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState(true, false));

			//			new Animation {
			//				{ 0, 0.5, new Animation (v => image.Scale = v, 1, 2) },
			//				{ 0, 1, new Animation (v => image.Rotation = v, 0, 360) },
			//				{ 0.5, 1, new Animation (v => image.Scale = v, 2, 1) }
			//			}.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));
		}
 private static Animation CreateLine(int y0, int slope, int size, Rect rect)
 {
     if (slope > size / 2) slope -= size;
     var ani = new Animation();
     var s = new Vector(rect.Width, -slope*rect.Height);
     var c = new Point(GetX(0, size, rect), GetY(y0, size, rect));
     var L = (c - s).To(c + s);
     var w = slope == 0 ? 0 : rect.Width / Math.Abs(slope);
     for (var i = -3; i <= Math.Abs(slope)+2; i++) {
         var Li = ClipLine(L + new Vector(w, 0)*i, rect);
         if (Li.HasValue) {
             ani.Add(new LineSegmentDesc(Li.Value, Brushes.Black, 2));
         }
         if (slope == 0) break;
     }
     return ani;
 }
 private static Animation MakeRotationAnimation(Point center, IEnumerable<Complex> input, TimeSpan dt, Point? rotationTextPos = null)
 {
     var aniTheta = Ani.Anon(t => (t.DividedBy(dt)*Math.PI*2).ProperMod(Math.PI*2));
     var aniMatrix = from theta in aniTheta
                     select ComplexMatrix.FromSquareData(Math.Cos(theta), Math.Sin(theta), -Math.Sin(theta), Math.Cos(theta));
     var ani = new Animation {
         MakeTransformAnimation(center, input, aniMatrix),
     };
     if (rotationTextPos.HasValue) {
         ani.Add(new TextDesc(text: from theta in aniTheta
                                    select string.Format("Current Rotation = {0:000}° =        ", theta*180/Math.PI),
                              pos: rotationTextPos.Value,
                              reference: new Point(0.5, 1)));
         ani.Add(QuantumCircuit.ShowComplex(
            Brushes.Transparent,
            Brushes.Black,
            from theta in aniTheta select Complex.FromPolarCoordinates(1, theta),
            rotationTextPos.Value + new Vector(70, -5),
            10,
            sweepFill: Brushes.Yellow,
            valueGuideStroke: Brushes.Transparent,
            sweepScale: 1.0));
     }
     return ani;
 }
        private static Animation MakeSuperpositionAnimation(Ani<Point> aniCenter, IReadOnlyDictionary<string, Ani<Complex>> vector, Brush[] colors)
        {
            var tau = 2*Math.PI;
            var aniVector =
                (from keyVal in vector
                 select from component in keyVal.Value
                        select new {
                            label = keyVal.Key,
                            value = new Complex(component.Real, -component.Imaginary),
                            scale = component.Magnitude < 0.1 ? component.Magnitude * 10 : 1
                }).ToArray()
                 .AniAll();
            var aniStartingPhase = from component in aniVector
                                   select (from e in component
                                           where e.value.Magnitude > 0
                                           select -e.scale * e.value / e.value.Magnitude
                                          ).Sum()
                                           .Phase;

            var aniBars =
                from component in aniVector
                from startingPhase in aniStartingPhase
                select component.Select((e, i) => new {
                    Label = e.label,
                    Width = 20*e.scale,
                    Height = e.value.Magnitude * (e.scale < 0.001 ? 0 : (100 / e.scale)),
                    Angle = e.value.Phase.ProperMod(tau),
                    Color = colors[i%colors.Length]
                }).OrderBy(e => (e.Angle - startingPhase).ProperMod(tau)).ToArray();

            var ani = new Animation();
            var c = 0;

            Func<double, Vector> angleToVector = theta => new Vector(Math.Cos(theta), Math.Sin(theta));

            var aniBorderDisplacements = from bars in aniBars
                                         select bars.Stream(
                                             default(Vector),
                                             (acc, bar) => acc + angleToVector(bar.Angle + tau/4)*bar.Width,
                                             streamSeed: true).ToArray();
            var aniAvgDisplacement = from borderDisplacements in aniBorderDisplacements
                                     select borderDisplacements.Average();

            var aniBorderPoints = from center in aniCenter
                                  from avgDisplacement in aniAvgDisplacement
                                  from borderDisplacements in aniBorderDisplacements
                                  select (from borderDisplacement in borderDisplacements
                                          select center + borderDisplacement - avgDisplacement).ToArray();
            foreach (var i in vector.Count.Range()) {
                var aniPt = from borderPoints in aniBorderPoints
                            select borderPoints[i];
                var aniBar = from bars in aniBars
                             select bars[i];
                var dw = from bar in aniBar
                         select angleToVector(bar.Angle + tau/4)*bar.Width;
                var dh = from bar in aniBar
                         select angleToVector(bar.Angle)*bar.Height;
                ani.Add(new PolygonDesc(pos: from pt in aniPt
                                             from w in dw
                                             from h in dh
                                             select new[] {
                                                 pt + w*c,
                                                 pt + w*(1 - c),
                                                 pt + w*(1 - c) + h,
                                                 pt + w*c + h
                                             }.AsEnumerable(),
                                        fill: from bar in aniBar
                                              select bar.Color));
                ani.Add(new TextDesc(text: from bar in aniBar
                                           select bar.Label,
                                     pos: from h in dh
                                          from w in dw
                                          from pt in aniPt
                                          select pt + h + w/2 + h.Normal()*5 - w.Normal()*2,
                                     reference: new Point(0, 0.5),
                                     fontSize: from bar in aniBar
                                               select bar.Width*1.2,
                                     direction: from bar in aniBar
                                                select Dir.FromNaturalAngle(bar.Angle)));
            }
            ani.Add(new PolygonDesc(aniBorderPoints.Select(e => e.AsEnumerable()), Brushes.Gray, 1, 2));
            return ani;
        }
        private static Animation RenderTree(Interval renderInterval, NestingDepthTreeNode root, HashSet<int> dealloced)
        {
            var v = renderInterval;
            var ani = new Animation();
            var r = 10;
            var query = new Dictionary<int, int>();
            var x = 100;
            var y = 350;

            for (var i = 0; i < v.Length; i++) {
                var h = NestingDepthTreeNode.QueryNestingDepthAt(root, i+v.Offset);
                query[i+v.Offset] = h;
                if (h== -1) throw new Exception();
                ani.Add(new RectDesc(new Rect(x + i * r, y - h * r - 1, r, h * r + 1), fill: Brushes.Black, stroke: Brushes.Black, strokeThickness: 0));
                if (dealloced.Contains(i+v.Offset)) {
                    ani.Add(new RectDesc(new Rect(x + i * r, y - 0.5 * r - 1, r, 1 * r + 1), fill: Brushes.Red, stroke: Brushes.Orange, strokeThickness: 1));
                }
            }

            var y2 = 125;
            Action<NestingDepthTreeNode, int> paintNode = null;
            paintNode = (n, l) => {
                if (n == null) return;

                var p = new Point(x + (n._offset-v.Offset)*r, y2 + l*r*5);
                if (n._parent != null) {
                    var q = new Point(x + (n._parent._offset - v.Offset) * r, y2 + (l - 1) * r * 5);
                    var b1 = false;
                    var b2 = false;
                    for (var i = Math.Min(n._offset, n._parent._offset); i < Math.Max(n._offset, n._parent._offset); i++) {
                        b1 |= query[i] != 0;
                        b2 |= query[i] == 0;
                    }
                    ani.Add(new LineSegmentDesc(new LineSegment(p, q), b1 && b2 ? Brushes.Red : b2 ? Brushes.Red : Brushes.Black, 1));
                }
                if (n._less != null) paintNode(n._less, l + 1);
                if (n._more != null) paintNode(n._more, l + 1);
                ani.Add(new RectDesc(new Rect(new Point(p.X - 18, p.Y - 22), new Size(36, 44)), n._fakeRefCount > 1 ? Brushes.Black : Brushes.Red, n._fakeRefCount > 0 ? Brushes.Gray : Brushes.Red, 1));
                var s = "d=" + n._adjust +Environment.NewLine + "t=" + n._subTreeTotalAdjust + Environment.NewLine + "m=" + n._subTreeRelativeMinimum;
                ani.Add(new TextDesc(s, new Point(p.X - 16, p.Y - 20), new Point(0, 0)));
                //var s = (n._adjust > 0 ? "+" : "") + n._adjust;
                //ani.Add(new PointDesc(p, n._fakeRefCount > 1 ? Brushes.Black : Brushes.Red, n._fakeRefCount > 0 ? Brushes.Gray : Brushes.Red, 15, 1));
                //ani.Add(new TextDesc(s, new Point(p.X - 8, p.Y - 8), new Point(0, 0)));
            };
            paintNode(root, 0);

            return ani;
        }
        private static Animation CreateAnimationOfOperations(Interval renderInterval, Interval targetInterval, params Operation[] operations)
        {
            var keyNodes = new Dictionary<int, Tuple<NestingDepthTreeNode, Interval, NestingDepthTreeNode>>();
            var activeOperation = default(Operation);

            var dt = 1.0;
            var ani = new Animation();

            ani.Add(new TextDesc("Using a Tree to Track Referenced Intervals", new Point(250, 5), new Point(0, 0), fontSize:20));
            ani.Add(new TextDesc("Referenced" + Environment.NewLine + "Intervals", new Point(10, 80)));
            ani.Add(new TextDesc("Tree", new Point(10, 220)));
            ani.Add(new TextDesc("Nesting" + Environment.NewLine + "Depth", new Point(10, 350)));
            ani.Add(new LineSegmentDesc(new Point(0, 30).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(0, 100).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(0, 300).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(75, 0).Sweep(new Vector(0, 10000)), Brushes.Black, 1));

            var i = 0.0;
            var dealloced = new HashSet<int>();
            for (var i2 = 0; i2 < renderInterval.Length; i2++) {
                if (i2 + renderInterval.Offset < targetInterval.Offset || i2 + renderInterval.Offset >= targetInterval.Offset + targetInterval.Length) {
                    dealloced.Add(i2 + renderInterval.Offset);
                }
            }
            var x = 100;
            var y = 90;
            Func<double, Animation> addFrame = focus => {
                var roots = keyNodes.Select(e => NestingDepthTreeNode.RootOf(e.Value.Item1)).Distinct().ToArray();

                var a = new Animation();

                var s = 10;
                if (!double.IsNaN(focus) && !double.IsInfinity(focus)) {
                    var dx = focus - renderInterval.Offset;
                    a.Add(new LineSegmentDesc(new LineSegment(new Point(x + dx*s, 0), new Point(x + dx*s, 10000)), activeOperation.Interval.HasValue ? Brushes.Green : Brushes.Red, 1, 1.0));
                }

                foreach (var r in roots) a.Add(RenderTree(renderInterval, r, dealloced));
                ani.LimitedNewTime(i.Seconds(), (i + dt).Seconds()).Add(a);
                i += dt;

                var bb = 0;
                foreach (var e in keyNodes) {
                    Brush brush;
                    if (e.Key == activeOperation.Key && !double.IsInfinity(focus)) {
                        brush = activeOperation.Interval.HasValue ? Brushes.Green : Brushes.Red;
                    } else {
                        brush = Brushes.Yellow;
                    }
                    var inv = e.Value.Item2;
                    var dx = inv.Offset - renderInterval.Offset;
                    a.Add(new RectDesc(new Rect(x + dx * s, y - (bb+1) * s*1.1, s*inv.Length, s), fill: brush, stroke: Brushes.Black, strokeThickness: 1));

                    bb += 1;
                }

                return a;
            };

            foreach (var e in operations) {
                activeOperation = e;
                var affectedRoot =
                    e.Interval.HasValue ?
                    keyNodes.Select(n => NestingDepthTreeNode.RootOf(n.Value.Item1)).FirstOrDefault(n => NestingDepthTreeNode.GetInterval(n).Overlaps(e.Interval.Value))
                    : NestingDepthTreeNode.RootOf(keyNodes[e.Key].Item1);

                if (e.Interval.HasValue) {
                    keyNodes.Add(e.Key, Tuple.Create((NestingDepthTreeNode)null, e.Interval.Value, (NestingDepthTreeNode)null));

                    addFrame(double.NaN);
                    addFrame(e.Interval.Value.Offset);

                    var a1 = NestingDepthTreeNode.Include(affectedRoot, e.Interval.Value.Offset, +1, +1);
                    a1.AdjustedNode._fakeRefCount += 2;
                    keyNodes[e.Key] = Tuple.Create(a1.AdjustedNode, e.Interval.Value, (NestingDepthTreeNode)null);
                    addFrame(e.Interval.Value.Offset);

                    addFrame(e.Interval.Value.Offset + e.Interval.Value.Length);
                    var a2 = NestingDepthTreeNode.Include(a1.NewRoot, e.Interval.Value.Offset + e.Interval.Value.Length, -1, +1);
                    a2.AdjustedNode._fakeRefCount += 2;
                    keyNodes[e.Key] = Tuple.Create(a1.AdjustedNode, e.Interval.Value, a2.AdjustedNode);

                    addFrame(e.Interval.Value.Offset + e.Interval.Value.Length);
                    addFrame(double.PositiveInfinity);
                }
                else {
                    var xs = keyNodes[e.Key];

                    var r = NestingDepthTreeNode.RootOf(xs.Item1);
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, +1, 0).NewRoot;
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset, -1, 0).NewRoot;
                    var hh = new HashSet<int>();
                    foreach (var ex in NestingDepthTreeNode.FindHolesIn(NestingDepthTreeNode.GetInterval(r), r)) {
                        for (var ii = ex.Offset; ii < ex.Offset + ex.Length; ii++) {
                            hh.Add(ii);
                        }
                    }
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, -1, 0).NewRoot;
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset, +1, 0).NewRoot;

                    xs.Item3._fakeRefCount -= 1;
                    xs.Item3._fakeRefCount -= 1;
                    xs.Item1._fakeRefCount -= 1;
                    addFrame(xs.Item2.Offset + xs.Item2.Length);
                    var r1 = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, +1, -1);
                    addFrame(xs.Item2.Offset + xs.Item2.Length);

                    xs.Item1._fakeRefCount -= 1;
                    addFrame(xs.Item2.Offset);
                    var r2 = NestingDepthTreeNode.Include(r1.NewRoot, xs.Item2.Offset, -1, -1);
                    keyNodes.Remove(e.Key);
                    addFrame(double.NaN);

                    foreach (var xxx in hh) {
                        dealloced.Add(xxx);
                    }

                    NestingDepthTreeNode.PartitionAroundHoles(r2.NewRoot);

                    addFrame(double.NaN);
                }
            }

            var xx = new Animation();
            xx.Periodic(i.Seconds()).Add(ani);
            return xx;
        }
Example #39
0
		/// <summary>
		/// Sets the translation.
		/// </summary>
		/// <param name="translation">Translation.</param>
		private Task SetTranslationAsync(double translation, bool animate, double delta,
			DateTime startTime, DateTime endTime)
		{
			if (Children.Count == 0)
				return Task.FromResult (true);
			
			var tcs = new TaskCompletionSource<bool> ();
			double speed = 250.0;

			// velocity:
			if(startTime != DateTime.MinValue)
			{
				var deltaT = (endTime - startTime).Milliseconds;
				double velocity_X = (double)deltaT / (double)delta;
				speed = Math.Abs((translation  -_childLayout.TranslationX) * velocity_X);
			}

			var animation = new Animation ();

			if (animate)
				animation.Add(0.0, 1.0, new Animation((d) => _childLayout.TranslationX = d,
					_childLayout.TranslationX, translation));
			else
				_childLayout.TranslationX = translation;			

			if (animate) 
			{
				var endAnimation = new Animation ((d) => {
				}, 0, 1, Easing.CubicInOut, () => {
					tcs.SetResult (true);
				});

				animation.Add (0.0, 1.0, endAnimation);
				animation.Commit (this, "Translate", 16, Math.Min (350, (uint)speed), Easing.CubicOut);
			} 
			else 
			{
				tcs.SetResult (true);
			}

			return tcs.Task;
		}
 private static Animation MakeScalingAnimation(Point center, IEnumerable<Complex> input, Ani<Complex> scale, Point? scalingTextPos = null)
 {
     var n = input.Count();
     var I = ComplexMatrix.MakeIdentity(n);
     var ani = new Animation {
         MakeTransformAnimation(center,
                                input,
                                from s in scale
                                select I*s)
     };
     if (scalingTextPos.HasValue) {
         ani.Add(new TextDesc(text: from s in scale
                                    select string.Format("Current Scale Factor =        = {0}",
                                                         s.Imaginary == 0
                                                             ? s.Real.ToString("0.0")
                                                             : s.ToPrettyString("0.0")),
                              pos: scalingTextPos));
         ani.Add(new RectDesc(
             new Rect(scalingTextPos.Value + new Vector(130, -5) + new Vector(-10, -5), new Size(20, 10)),
             stroke: from s in scale select s.Imaginary != 0 ? (Brush)Brushes.Transparent : Brushes.Black,
             strokeThickness: 1,
             dashed: 3));
         ani.Add(new RectDesc(
             from s in scale select new Rect(scalingTextPos.Value + new Vector(130, -5) + new Vector(s.Real.Min(0)*10, -5), new Size(s.Real.Abs()*10, 10)),
             fill: from s in scale select s.Imaginary != 0 ? (Brush)Brushes.Transparent : Brushes.Green));
         ani.Add(QuantumCircuit.ShowComplex(
             Brushes.Transparent,
             from s in scale select s.Imaginary == 0 ? (Brush)Brushes.Transparent : Brushes.Black,
             scale,
             scalingTextPos.Value + new Vector(130, -5),
             10,
             sweepFill: from s in scale select s.Imaginary == 0 ? (Brush)Brushes.Transparent : Brushes.Green,
             valueGuideStroke: from s in scale select s.Imaginary == 0 ? (Brush)Brushes.Transparent : Brushes.Black));
     }
     return ani;
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="NControl.Controls.TabStripControl"/> class.
		/// </summary>
		/// <param name="view">View.</param>
		public void Activate (TabItem tabChild, bool animate)
		{
			var existingChild = Children.FirstOrDefault (t => t.View == 
				_contentView.Children.FirstOrDefault (v => v.IsVisible));

			if (existingChild == tabChild)
				return;

			var idxOfExisting = existingChild != null ? Children.IndexOf (existingChild) : -1;
			var idxOfNew = Children.IndexOf (tabChild);

			if (idxOfExisting > -1 && animate) 
			{
				_inTransition = true;

				// Animate
				var translation = idxOfExisting < idxOfNew ? 
					_contentView.Width : - _contentView.Width;

				tabChild.View.TranslationX = translation;
				if (tabChild.View.Parent != _contentView)
					_contentView.Children.Add(tabChild.View);
				else
					tabChild.View.IsVisible = true;

				var newElementWidth = _buttonStack.Children.ElementAt (idxOfNew).Width;
				var newElementLeft = _buttonStack.Children.ElementAt (idxOfNew).X;

				var animation = new Animation ();
				var existingViewOutAnimation = new Animation ((d) => existingChild.View.TranslationX = d,
					0, -translation, Easing.CubicInOut, () => {
						existingChild.View.IsVisible = false;
						_inTransition = false;
					});

				var newViewInAnimation = new Animation ((d) => tabChild.View.TranslationX = d,
					translation, 0, Easing.CubicInOut);

				var existingTranslation = _indicator.TranslationX;

				var indicatorTranslation = newElementLeft;
				var indicatorViewAnimation = new Animation ((d) => _indicator.TranslationX = d,
					existingTranslation, indicatorTranslation, Easing.CubicInOut);

				var startWidth = _indicator.Width;
				var indicatorSizeAnimation = new Animation ((d) => _indicator.WidthRequest = d,
					startWidth, newElementWidth, Easing.CubicInOut);

				animation.Add (0.0, 1.0, existingViewOutAnimation);
				animation.Add (0.0, 1.0, newViewInAnimation);
				animation.Add (0.0, 1.0, indicatorViewAnimation);
				animation.Add (0.0, 1.0, indicatorSizeAnimation);
				animation.Commit (this, "TabAnimation");
			} 
			else 
			{
				// Just set first view
				_contentView.Children.Clear();
				_contentView.Children.Add(tabChild.View);
			}

			foreach (var tabBtn in _buttonStack.Children)
				((TabBarButton)tabBtn).IsSelected = _buttonStack.Children.IndexOf(tabBtn) == idxOfNew;

			if (TabActivated != null)
				TabActivated(this, idxOfNew);
		}
        private static Animation CreateVarySlopeSolveYAnimation(int size, Rect rect, int xq, int yq)
        {
            var ani = new Animation { CreateGrid(size, rect) };

            var dt = 50.Milliseconds();
            var p = ani.Periodic(dt.Times(size));
            for (var slope = 0; slope < size; slope++) {
                var y0 = size.Range().Single(y => (y + slope * xq) % size == yq);
                var q = p.LimitedNewTime(dt.Times(slope), dt.Times(slope + 1));
                q.Add(CreateLine(y0, slope, size, rect));
                q.Add(new PointDesc(GetP(0, y0, size, rect), fill: Brushes.Red, radius: 8));
                q.Add(new TextDesc(string.Format("Target = ({0}, {1}), Slope = {2}, Y-Intercept = {3}", xq, yq, slope, y0),
                    new Point(rect.Left + 67, rect.Bottom + 5),
                    new Point(0, 0), fontSize: 14));
                q.Add(new PointDesc(GetP(xq, yq, size, rect), fill: Brushes.Blue, radius: 8));
            }

            ani.Add(new TextDesc("Varying Slope, Solving Y-Intercept", new Point(rect.Left + rect.Width / 2, rect.Top - 30), new Point(0.5, 0), fontSize: 18));

            return ani;
        }
        private static Animation CreateVaryQSolveSlopeAnimation(Rect rect)
        {
            var size = 13;
            var yq = 10;
            var y0 = 5;

            var ani = new Animation { CreateGrid(size, rect) };
            var dt = 50.Milliseconds();
            var p = ani.Periodic(dt.Times(size - 1));
            for (var xq = 1; xq < size; xq++) {
                var slope = size.Range().Single(s => (y0 + s * xq) % size == yq);
                var q = p.LimitedNewTime(dt.Times(xq - 1), dt.Times(xq));
                q.Add(CreateLine(y0, slope, size, rect));
                q.Add(new PointDesc(GetP(0, y0, size, rect), fill: Brushes.Red, radius: 8));
                q.Add(new TextDesc(string.Format("Target = ({0}, {1}), Slope = {2}, Y-Intercept = {3}", xq, yq, slope, y0),
                    new Point(rect.Left + 67, rect.Bottom + 5),
                    new Point(0, 0), fontSize: 14));
                q.Add(new PointDesc(GetP(xq, yq, size, rect), fill: Brushes.Blue, radius: 8));
            }

            ani.Add(new TextDesc("Varying Target, Solving Slope", new Point(rect.Left + rect.Width / 2, rect.Top - 30), new Point(0.5, 0), fontSize: 18));

            return ani;
        }
        public static Animation CreateCircuitAnimation(double span,
                                                       TimeSpan duration, 
                                                       IReadOnlyList<CircuitOperationWithStyle> ops, 
                                                       IReadOnlyList<CircuitInputWithStyle> ins, 
                                                       string desc, 
                                                       IReadOnlyList<string[][]> wireLabels = null, 
                                                       string[] stateLabels = null, 
                                                       bool showMatrix = true, 
                                                       double wireSpace = 80)
        {
            var matrixFill = (Brush)Brushes.Orange.LerpToTransparent(0.5);

            var vals = ins.Select(e => ops.Stream(e.Value, (a, x) => x.Operation*a, streamSeed: true).ToArray()).ToArray();

            var numOp = ops.Count;
            var numIn = ins.Count;
            var maxIn = numOp + 1;
            var numState = ins.First().Value.Values.Count;
            var numWire = (int)Math.Round(Math.Log(numState, 2));
            var matrixWidth = 150.0;
            var cellRadius = matrixWidth / (vals[0][0].Values.Count + 2) / 2;
            var matrixRadius = matrixWidth / 2;
            var opXs = numOp.Range().Select(i => -cellRadius+span*(i+0.75)/maxIn).ToArray();

            var sweepX = Ani.Anon(t => new Point(t.DividedBy(duration).LerpTransition(-cellRadius * 2, span - cellRadius * 2), 0).Sweep(new Vector(0, 1000)));
            var opTs = opXs.Select(x => new {s = duration.Times((x - matrixRadius + cellRadius*2)/span), f = duration.Times((x + matrixRadius)/span)}).ToArray();

            var wireYs = numWire.Range().Select(i => numWire == 1 ? 20 + wireSpace/2 : (wireSpace / 2 + i * wireSpace / 2 / (numWire - 1))).ToArray();
            var animation = new Animation {
                // top description
                new TextDesc(desc,
                             new Point(span/2.0 - (numOp == 1 ? cellRadius : 0), 5),
                             new Point(0.5, 0),
                             fontSize: 15,
                             foreground: Brushes.Gray),
                // wires
                wireYs.Select(y => new LineSegmentDesc(new Point(0, y).Sweep(new Vector(span+300, 0))))
            };
            if (showMatrix) {
                // static matrices
                animation.Add(
                    numOp.Range()
                         .Select(i => ShowMatrix(
                             new Rect(opXs[i] - matrixRadius, wireSpace+20, matrixRadius*2, matrixRadius*2),
                             ops[i].Operation,
                             matrixFill,
                             Brushes.Black)));
            }

            var offsetTimelines =
                ins.Count.Range()
                     .Select(
                         i => animation
                                  .Dilated(
                                      1.Seconds(),
                                      -duration.DividedBy(ins.Count).Times(i))
                                  .Periodic(duration))
                     .ToArray();

            // sweep line
            foreach (var p in offsetTimelines) {
                p.Add(new LineSegmentDesc(sweepX, Brushes.Red, 0.5, 4));
            }

            // state labels
            var tts = opTs.Select(e => e.s.LerpTo(e.f, 0.4));
            var wd = numIn.Range().Select(inid => numWire.Range().Select(wid => (numOp + 1).Range().Select(tid => {
                var label = wireLabels == null ? new[] {"On", "Off"} : wireLabels[wid][tid];
                var p = numState.Range().Where(i => ((i >> wid) & 1) == 0).Select(i => vals[inid][tid].Values[i].SquaredMagnitude()).Sum();
                if (p < 0.001) return label[1];
                if (p < 0.01) return string.Format("~{0}", label[1]);
                if (p < 0.49) return string.Format("~{0}:{1:0}%", label[1], (1 - p) * 100);

                if (p > 0.999) return label[0];
                if (p > 0.99) return string.Format("~{0}", label[0]);
                if (p > 0.51) return string.Format("~{0}:{1:0}%", label[0], p * 100);

                return string.Format("{0}/{1}", label[0], label[1]);
            }).ToArray()).ToArray()).ToArray();
            foreach (var i in numIn.Range()) {
                foreach (var j in numWire.Range()) {
                    animation.Add(
                        new TextDesc(
                            Ani.Anon(t => (t + duration.DividedBy(numIn).Times(i)).Mod(duration))
                               .Select(t => wd[i][j][tts.TakeWhile(c => t >= c).Count()]),
                            Ani.Anon(
                                t =>
                                new Point((t.DividedBy(duration) + i * 1.0 / numIn).ProperMod(1).LerpTransition(-cellRadius * 2, span - cellRadius * 2), wireYs[j]))));
                }
            }

            // matrix multiplications
            if (showMatrix) {
                foreach (var i in numIn.Range()) {
                    foreach (var j in numOp.Range()) {
                        var p = offsetTimelines[i].LimitedNewTime(opTs[j].s, opTs[j].f);
                        var r = new Rect(opXs[j] - matrixRadius, wireSpace + 20, matrixRadius * 2, matrixRadius * 2);
                        p.Add(
                            ShowMatrixMultiplication(
                                opTs[j].f - opTs[j].s,
                                r,
                                ops[j].Operation,
                                vals[i][j],
                                matrixFill,
                                ins[i].Color,
                                Brushes.Black));
                    }
                }
            }

            // pushed values
            if (showMatrix) {
                foreach (var i in numIn.Range()) {
                    foreach (var s in maxIn.Range()) {
                        var p = offsetTimelines[i].LimitedSameTime(s == 0 ? 0.Seconds() : opTs[s - 1].f, s == maxIn - 1 ? duration : opTs[s].s);
                        p.Add(numState.Range().Select(
                            j => ShowComplex(
                                ins[i].Color,
                                Brushes.Black,
                                vals[i][s].Values[j],
                                sweepX.Select(e => new Point(e.LerpAcross(0.3).X + cellRadius, wireSpace + 20 + cellRadius) + new Vector(0, j * cellRadius * 2)),
                                cellRadius)));
                    }
                }
            }

            // state labels
            if (showMatrix) {
                wireLabels = wireLabels ?? new[] {"On", "Off"}.Repeat(maxIn).ToArray().Repeat(numWire);
                stateLabels = stateLabels
                              ?? numState.Range().Select(
                                  i => numWire.Range().Select(
                                      w => maxIn.Range().Select(
                                          inid => wireLabels[w][inid][(i >> w) & 1]
                                               ).Distinct().StringJoin("")
                                           ).StringJoin(",")
                                     ).ToArray();
                foreach (var i in numState.Range()) {
                    animation.Add(
                        new TextDesc(
                            stateLabels[i] + ":",
                            new Point(0, wireSpace + 20 + cellRadius + i*2*cellRadius),
                            new Point(0, 0.5)));
                }
            }

            // circuit diagram
            foreach (var i in numOp.Range()) {
                var op = ops[i];
                var h = (numWire == 1 ? 50 : op.MaxWire - op.MinWire == numWire - 1 ? wireSpace*0.80 : (wireYs[1] - wireYs[0]) * (op.MaxWire - op.MinWire + 1)) * 0.9;
                var r = new Rect(
                    opXs[i] - op.Width/2,
                    (wireYs[op.MaxWire] + wireYs[op.MinWire] - h)/2,
                    op.Width,
                    h);
                foreach (var c in op.ConditionedWires ?? new int[0]) {
                    animation.Add(
                        new LineSegmentDesc(
                            new Point(opXs[i], wireYs[op.MaxWire]).To(new Point(opXs[i], wireYs[c])),
                            Brushes.Black,
                            1));
                    animation.Add(
                        new PointDesc(
                            new Point(opXs[i], wireYs[c]),
                            fill: Brushes.Black,
                            radius: 3));
                }
                animation.Add(
                    new RectDesc(
                        r,
                        Brushes.Black,
                        Brushes.White,
                        1.0));
                animation.Add(
                    new TextDesc(
                        op.Description,
                        r.TopLeft + new Vector(r.Width, r.Height) / 2,
                        new Point(0.5, 0.5),
                        fontWeight: FontWeights.ExtraBold,
                        fontSize: 20));
                if (op.WireHints != null) {
                    foreach (var j in op.WireHints.Length.Range()) {
                        animation.Add(
                            new TextDesc(
                                op.WireHints[j],
                                new Point(r.Left+5, wireYs[op.MinWire + j]),
                                new Point(0, 0.5),
                                foreground: Brushes.Gray,
                                fontSize: 10));
                    }
                }
            }

            return animation;
        }
Example #45
0
        public static Animation CreateCellAnimation()
        {
            var animation = new Animation();

            var liqs = new List<Liqs>();
            var rng = new Random();
            var n = 300;
            var w = 400.0;
            foreach (var i in n.Range()) {
                var p = new Point(rng.NextDouble()*w, rng.NextDouble()*w);
                var a = i*2*Math.PI/n;
                var v = new Vector(Math.Sin(a), Math.Cos(a));
                //p = new Point(w/2,w/2) + (w/8+rng.NextDouble()*5)* v;
                var l1 = new Liqs {
                    P = p,
                    V = new Vector(rng.NextDouble() - 0.5, rng.NextDouble() - 0.5) * 25,
                    Charge = -1 //(rng.Next(2) * 2 - 1)
                };
                var l2 = new Liqs {
                    P = p + v*20*(rng.Next(3)==0?-1:1) + 8*new Vector(rng.NextDouble() * -0.5, rng.NextDouble() * -0.5),
                    V = new Vector(rng.NextDouble()-0.5, rng.NextDouble()-0.5)*10,
                    Partner =  l1,
                    Charge = -l1.Charge
                };
                l1.Partner = l2;
                liqs.Add(l1);
                liqs.Add(l2);
                //animation.Add(new LineSegmentDesc(Ani.Anon(t => l1.P.To(l2.P)), Brushes.Black, 1.0, 3));
                animation.Add(new PointDesc(Ani.Anon(t => l1.P), Brushes.Transparent, l1.Charge == -1 ? Brushes.Red : Brushes.Blue, 3, 0.0));
                animation.Add(new PointDesc(Ani.Anon(t => l2.P), Brushes.Transparent, l2.Charge == -1 ? Brushes.Red : Brushes.Blue, 3, 0.0));
            }
            foreach (var i in (n*4).Range()) {
                var p = new Point((rng.NextDouble() * 2 - 1) *w / 2 + w / 2, (rng.NextDouble() * 2 - 1) * w / 2 + w / 2);
                var a = i * 2 * Math.PI / n;
                var v = new Vector(Math.Sin(a), Math.Cos(a));
                //p = new Point(w / 2, w / 2) + ((rng.Next(12) == 0 ? w / 32 : w * 0.25 * (rng.NextDouble() * 0.2 + 0.9)) + rng.NextDouble() * 5) * v;
                var l1 = new Liqs {
                    P = p,
                    Charge = 0
                };
                liqs.Add(l1);
                animation.Add(new PointDesc(Ani.Anon(t => l1.P), Brushes.Transparent, Brushes.DarkGreen, 2, 0.0));
            }

            Action<TimeSpan> sstep = dt => {
                var ds = dt.TotalSeconds;
                foreach (var p in liqs) {
                    var a = new Vector(0, 0);
                    foreach (var q in liqs) {
                        if (q == p) continue;
                        a += p.ForceTowards(q) * 1;
                    }
                    var f = 5;
                    if (p.P.X > w-10) a -= f*new Vector(1, 0);
                    if (p.P.X < 10) a -= f * new Vector(-1, 0);
                    if (p.P.Y > w - 10) a -= f * new Vector(0, 1);
                    if (p.P.Y < 10) a -= f * new Vector(0, -1);
                    var t = 1.0;
                    //foreach (var q in liqs) {
                    //    if (q == p || q == p.Partner) continue;
                    //    var r = GeometryUtilities.LineDefinedByMovingEndPointsCrossesOrigin(q.P.To(q.P - p.V * ds * t), q.Partner.P.To(q.Partner.P - p.V * ds * t), p.P);
                    //    if (r.HasValue) t *= r.Value.T;
                    //}
                    //foreach (var q in liqs) {
                    //    if (q == p || q == p.Partner) continue;
                    //    var r = GeometryUtilities.LineDefinedByMovingEndPointsCrossesOrigin(p.P.To(p.P + p.V*ds*t), p.Partner.P.To(p.Partner.P + p.V*ds*t), q.P);
                    //    if (r.HasValue) t *= r.Value.T;
                    //}
                    p.P += p.V * ds * t;
                    p.P += new Vector(rng.NextDouble() - 0.5, rng.NextDouble() - 0.5);
                    p.V += a * ds;
                    p.V *= Math.Pow(0.5, ds);
                }
            };
            animation.Add(new RectDesc(new Rect(10,10,w-20,w-20), Brushes.Black, Brushes.Transparent, 1, 2));

            animation.StepActions.Add(step => {
                sstep(step.TimeStep);
            }, Lifetime.Immortal);
            return animation;
        }