public Transition CreateZoomAndPanTransition(ContainerVisual targetVisual)
        {
            Vector3 targetCenter, targetCenterPoint, viewportCenter;
            GetValues(targetVisual, out targetCenter, out targetCenterPoint, out viewportCenter);

            _zoomOffsetAnimation.SetVector3Parameter("myViewportCenter", viewportCenter);
            _zoomCenterAnimation.SetVector3Parameter("myTargetCenterPoint", targetCenterPoint);
            _zoomScaleAnimation.SetVector3Parameter("myScale", new Vector3(_zoomScale, _zoomScale, 1.0f));

            var panningVisual = targetVisual.Parent;
            var offsetAnimator = panningVisual.ConnectAnimation("Offset", _zoomOffsetAnimation);
            var centerAnimator = panningVisual.ConnectAnimation("CenterPoint", _zoomCenterAnimation);
            var scaleAnimator = panningVisual.ConnectAnimation("Scale", _zoomScaleAnimation);

            var transition = new Transition();
            transition.InsertAnimator(offsetAnimator);
            transition.InsertAnimator(centerAnimator);
            transition.InsertAnimator(scaleAnimator);

            return transition;
        }
        public Transition CreateUnstackTransition(ContainerVisual targetVisual)
        {
            Debug.Assert((_stackedTiles != null) && (_stackedTiles.Count > 0));

            var transition = new Transition();

            for (int i = 0; i < _stackedTiles.Count; i++)
            {
                Vector3 offset = _stackedTiles[i].Frame.Offset - _stackVisual.Offset;
                Vector3 direction = offset / offset.Length();
                Vector3 delta = direction * Math.Max(_windowWidth, _windowHeight);

                _stackFlyOutAnimation.SetVector3Parameter("delta", delta);
                _stackFlyOutAnimation.SetVector3Parameter("originalOffset", _stackedTiles[i].Offset);
                _stackFlyOutAnimation.DelayTime = TimeSpan.FromMilliseconds(1500 + (_stackedTiles.Count - i) * 100);

                var flyOutAnimator = _stackedTiles[i].Frame.ConnectAnimation("Offset", _stackFlyOutAnimation);
                transition.InsertAnimator(flyOutAnimator);
            }

            _stackedTiles.Clear();
            _stackedTiles = null;

            return transition;
        }
        public Transition CreateFarSlideTransition(ContainerVisual targetVisual)
        {
            Vector3 targetCenter, targetCenterPoint, viewportCenter;
            GetValues(targetVisual, out targetCenter, out targetCenterPoint, out viewportCenter);

            _farSlideOffsetAnimation.SetVector3Parameter("myViewportCenter", viewportCenter);
            _slideCenterAnimation.SetVector3Parameter("myTargetCenterPoint", targetCenterPoint);

            _slideCenterAnimation.Duration = _farSlideOffsetAnimation.Duration;

            var parentVisual = targetVisual.Parent;
            var offsetAnimator = parentVisual.ConnectAnimation("Offset", _farSlideOffsetAnimation);
            var centerAnimator = parentVisual.ConnectAnimation("CenterPoint", _slideCenterAnimation);
            var scaleAnimator = parentVisual.ConnectAnimation("Scale", _farSlideScaleAnimation);

            var transition = new Transition();
            transition.InsertAnimator(offsetAnimator);
            transition.InsertAnimator(centerAnimator);
            transition.InsertAnimator(scaleAnimator);

            return transition;
        }
        public Transition CreateStackTransition(ContainerVisual targetVisual)
        {
            int stackSize = _random.Next(4, 9);

            Debug.Assert(_stackedTiles == null);
            _stackedTiles = new List<Tile>();
            _stackVisual = targetVisual;

            var transition = new Transition();

            _stackScaleAnimation.SetVector3Parameter("myScale", new Vector3(_zoomScale, _zoomScale, 1.0f));
            var stackScaleAnimator = targetVisual.Parent.ConnectAnimation("Scale", _stackScaleAnimation);
            transition.InsertAnimator(stackScaleAnimator);

            for (int i = 0; i < stackSize; i++)
            {
                var tile = _layoutManager.GetFarNeighborPreserveSelection();
                _stackedTiles.Add(tile);

                Vector3 offset = tile.Frame.Offset - targetVisual.Offset;
                Vector3 direction = offset / offset.Length();
                Vector3 startDelta = direction * Math.Max(_windowWidth, _windowHeight);

                float rx = (float) (_random.NextDouble() * 100 - 50);
                float ry = (float) (_random.NextDouble() * 100 - 50);
                Vector3 endDelta = -direction * new Vector3(rx, ry, 0.0f);

                _stackFlyInAnimation.SetReferenceParameter("stackVisual", targetVisual);
                _stackFlyInAnimation.SetVector3Parameter("startDelta", startDelta);
                _stackFlyInAnimation.SetVector3Parameter("endDelta", endDelta);
                _stackFlyInAnimation.DelayTime = TimeSpan.FromSeconds(i * 2);

                var flyInAnimator = tile.Frame.ConnectAnimation("Offset", _stackFlyInAnimation);
                transition.InsertAnimator(flyInAnimator);

                tile.BringToTop();
            }

            return transition;
        }
        private void Transition_TransitionFinished(Transition sender)
        {
            _currentTransition.TransitionFinished -= Transition_TransitionFinished;
            _currentTransition.Dispose();
            _currentTransition = null;

            NextTransition();
        }