Плавная анимация с использованием MatrixTransform?
Я пытаюсь сделать матричную анимацию, где я одновременно масштабирую и транспонирую холст. Единственным подходом, который я нашел, было использование MatrixTransform и MatrixAnimationUsingKeyFrames. Поскольку кажется, что нет никакой интерполяции для встроенных матриц (только для пути / поворота), кажется, что единственный выбор состоит в том, чтобы попытаться создать интерполяцию и DiscreteMatrixKeyFrame самостоятельно.
Я сделал базовую реализацию этого, но это не совсем гладко, и я не уверен, что это лучший способ и как обрабатывать частоту кадров и т.д. У кого-нибудь есть предложения по улучшению? Вот код:
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;
}