流畅的动画效果使用MatrixTransform? [英] Smooth animation using MatrixTransform?

查看:196
本文介绍了流畅的动画效果使用MatrixTransform?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个矩阵动画​​在同一时间,我规模和调换的画布。我发现的唯一方法是使用MatrixTransform和MatrixAnimationUsingKeyFrames。由于有犯规似乎是建于(仅针对路径/旋转)矩阵的插值似乎唯一的选择是尝试建立插值和DiscreteMatrixKeyFrame的自己。

我做的这个基本实现,但它不是准确流畅,我不知道这是最好的方式,以及如何处理等,帧率有任何改进的建议?这里的code:

  MatrixAnimationUsingKeyFrames阿尼姆=新MatrixAnimationUsingKeyFrames();
        INT持续时间= 1;
        anim.KeyFrames =插值(新点(0,0),中心点,1,因子,100,持续时间);
        this.matrixTransform.BeginAnimation(Matr​​ixTransform.MatrixProperty,动画,HandoffBehavior.Compose);
公共MatrixKeyFrameCollection插值(点的startPoint,Point端点,双startScale,双endScale,双倍帧速率,双时间)
    {
        MatrixKeyFrameCollection关键帧=新MatrixKeyFrameCollection();        双步=持续时间*帧率;
        双毫秒= 1000 /帧率;
        双timeCounter = 0;        双diffX = Math.Abs​​(startPoint.X- endPoint.X);
        双XSTEP = diffX /步骤;        双diffY = Math.Abs​​(startPoint.Y - endPoint.Y);
        双yStep = diffY /步骤;        双diffScale = Math.Abs​​(startScale- endScale);
        双scaleStep = diffScale /步骤;
        如果(endPoint.Y< startPoint.Y)
        {
            yStep = -yStep;
        }        如果(endPoint.X< startPoint.X)
        {
            XSTEP = -xStep;
        }
        如果(endScale< startScale)
        {
            scaleStep = -scaleStep;
        }
        点currentPoint =新点();
        双currentScale = startScale;        的for(int i = 0; I<步骤;我++)
        {
            keyframes.Add(新DiscreteMatrixKeyFrame(新矩阵(currentScale,0,0,currentScale,currentPoint.X,currentPoint.Y),KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(timeCounter))));
            currentPoint.X + = XSTEP;
            currentPoint.Y + = yStep;
            currentScale + = scaleStep;
            timeCounter + =毫秒;        }        keyframes.Add(新DiscreteMatrixKeyFrame(新矩阵(endScale,0,0,endScale,endPoint.X,endPoint.Y),KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0))));        返回关键帧;    }


解决方案

试试这个!只要你不旋转/剪切它会做的伎俩。

 使用System.Windows;
使用System.Windows.Media;
用System.Windows.Media.Animation;命名空间地图控件
{
    公共类LinearMatrixAnimation:AnimationTimeline
    {        公共矩阵?从
        {
            集合{的SetValue(FromProperty,价值);}
            {返回(矩阵)的GetValue(FromProperty); }
        }
        公共静态的DependencyProperty FromProperty = DependencyProperty.Register(?发件人的typeof(矩阵)的typeof(LinearMatrixAnimation),新PropertyMetadata(NULL));        公共矩阵?至
        {
            集合{的SetValue(ToProperty,值); }
            {返回(矩阵)的GetValue(ToProperty); }
        }
        公共静态的DependencyProperty ToProperty = DependencyProperty.Register(收件人,typeof运算(矩阵)的typeof(LinearMatrixAnimation),新PropertyMetadata(空)?);        公共LinearMatrixAnimation()
        {
        }        公共LinearMatrixAnimation(从矩阵,矩阵为,持续时间长)
        {
            持续时间=持续时间;
            从自=;
            为了给=;
        }        公众覆盖对象GetCurrentValue(对象defaultOriginValue,对象defaultDestinationValue,AnimationClock应用AnimationClock应用)
        {
            如果(animationClock.CurrentProgress == NULL)
            {
                返回null;
            }            双进度= animationClock.CurrentProgress.Value;
            从=从矩阵? (矩阵)defaultOriginValue;            如果(To.HasValue)
            {
                矩阵= To.Value;
                矩阵newMatrix =新矩阵(((to.M11 - from.M11)*进展)+ from.M11,0,0,((to.M22 - from.M22)*进展)+ from.M22,
                                              ((to.OffsetX - from.OffsetX)*进度)+ from.OffsetX,((to.OffsetY - from.OffsetY)*进度)+ from.OffsetY);
                返回newMatrix;
            }            返回Matrix.Identity;
        }        保护覆盖System.Windows.Freezable CreateInstanceCore()
        {
            返回新LinearMatrixAnimation();
        }        公众覆盖的System.Type TargetPropertyType
        {
            得到{typeof运算(矩阵); }
        }
    }
}

I'm trying to do an Matrix animation where I both scale and transpose a canvas at the same time. The only approach I found was using a MatrixTransform and MatrixAnimationUsingKeyFrames. Since there doesnt seem to be any interpolation for matrices built in (only for path/rotate) it seems the only choice is to try and build the interpolation and DiscreteMatrixKeyFrame's yourself.

I did a basic implementation of this but it isnt exactly smooth and I'm not sure if this is the best way and how to handle framerates etc. Anyone have suggestions for improvement? Here's the code:

        MatrixAnimationUsingKeyFrames anim = new MatrixAnimationUsingKeyFrames();
        int duration = 1;
        anim.KeyFrames = Interpolate(new Point(0, 0), centerPoint, 1, factor,100,duration);
        this.matrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, anim,HandoffBehavior.Compose);


public MatrixKeyFrameCollection Interpolate(Point startPoint, Point endPoint, double startScale, double endScale, double framerate,double duration)
    {
        MatrixKeyFrameCollection keyframes = new MatrixKeyFrameCollection();

        double steps = duration * framerate;
        double milliSeconds = 1000 / framerate;
        double timeCounter = 0;



        double diffX = Math.Abs(startPoint.X-  endPoint.X);
        double xStep = diffX / steps;

        double diffY = Math.Abs(startPoint.Y - endPoint.Y);
        double yStep = diffY / steps;

        double diffScale= Math.Abs(startScale- endScale);
        double scaleStep = diffScale / steps;


        if (endPoint.Y < startPoint.Y)
        {
            yStep =  -yStep;
        }

        if (endPoint.X < startPoint.X)
        {
            xStep =  -xStep;
        }


        if (endScale < startScale)
        {
            scaleStep =  -scaleStep;
        }


        Point currentPoint = new Point();
        double currentScale = startScale;

        for (int i = 0; i < steps; i++)
        {
            keyframes.Add(new DiscreteMatrixKeyFrame(new Matrix(currentScale, 0, 0, currentScale, currentPoint.X, currentPoint.Y), KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(timeCounter))));
            currentPoint.X += xStep;
            currentPoint.Y += yStep;
            currentScale += scaleStep;
            timeCounter += milliSeconds;

        }

        keyframes.Add(new DiscreteMatrixKeyFrame(new Matrix(endScale, 0, 0, endScale, endPoint.X, endPoint.Y), KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0))));

        return keyframes;

    }

解决方案

Try this! As long as you aren't rotating/shearing it will do the trick.

using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace MapControl
{
    public class LinearMatrixAnimation : AnimationTimeline
    {

        public Matrix? From
        {
            set { SetValue(FromProperty, value);}
            get { return (Matrix)GetValue(FromProperty); }
        }
        public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(Matrix?), typeof(LinearMatrixAnimation), new PropertyMetadata(null));

        public Matrix? To
        {
            set { SetValue(ToProperty, value); }
            get { return (Matrix)GetValue(ToProperty); }
        }
        public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(Matrix?), typeof(LinearMatrixAnimation), new PropertyMetadata(null));

        public LinearMatrixAnimation()
        {            
        }

        public LinearMatrixAnimation(Matrix from, Matrix to, Duration duration)
        {
            Duration = duration;
            From = from;
            To = to;
        }

        public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
        {
            if (animationClock.CurrentProgress == null)
            {
                return null;
            }

            double progress = animationClock.CurrentProgress.Value;
            Matrix from = From ?? (Matrix)defaultOriginValue;

            if (To.HasValue)
            {
                Matrix to = To.Value;
                Matrix newMatrix = new Matrix(((to.M11 - from.M11) * progress)+from.M11, 0, 0, ((to.M22 - from.M22) * progress)+from.M22,
                                              ((to.OffsetX - from.OffsetX) * progress) + from.OffsetX, ((to.OffsetY - from.OffsetY) * progress)+ from.OffsetY);
                return newMatrix;
            }

            return Matrix.Identity;
        }

        protected override System.Windows.Freezable CreateInstanceCore()
        {
            return new LinearMatrixAnimation();
        }

        public override System.Type  TargetPropertyType
        {
            get { return typeof(Matrix); }
        }
    }
}

这篇关于流畅的动画效果使用MatrixTransform?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆