public void AppendIdentity() { var toAdd = new TransformOperation(); toAdd.Type = TransformOperation.OperationType.Identity; _operations.Add(toAdd); }
public void AppendMatrix(Matrix matrix) { var toAdd = new TransformOperation(); toAdd.Type = TransformOperation.OperationType.Matrix; toAdd.Matrix = matrix; _operations.Add(toAdd); }
public void AppendRotate(double angle) { var toAdd = new TransformOperation(); toAdd.Type = TransformOperation.OperationType.Rotate; toAdd.Data.Rotate.Angle = angle; toAdd.Bake(); _operations.Add(toAdd); }
private static bool TryInterpolate(TransformOperations from, TransformOperations to, double progress, ref TransformOperations result) { bool fromIdentity = from.IsIdentity; bool toIdentity = to.IsIdentity; if (fromIdentity && toIdentity) { return(true); } int matchingPrefixLength = ComputeMatchingPrefixLength(from, to); int fromSize = fromIdentity ? 0 : from._operations.Count; int toSize = toIdentity ? 0 : to._operations.Count; int numOperations = Math.Max(fromSize, toSize); var builder = new Builder(matchingPrefixLength); for (int i = 0; i < matchingPrefixLength; i++) { TransformOperation interpolated = new TransformOperation { Type = TransformOperation.OperationType.Identity }; if (!TransformOperation.TryInterpolate( i >= fromSize ? default(TransformOperation?) : from._operations[i], i >= toSize ? default(TransformOperation?) : to._operations[i], progress, ref interpolated)) { return(false); } builder.Append(interpolated); } if (matchingPrefixLength < numOperations) { if (!ComputeDecomposedTransform(from, matchingPrefixLength, out Matrix.Decomposed fromDecomposed) || !ComputeDecomposedTransform(to, matchingPrefixLength, out Matrix.Decomposed toDecomposed)) { return(false); } var transform = InterpolationUtilities.InterpolateDecomposedTransforms(ref fromDecomposed, ref toDecomposed, progress); builder.AppendMatrix(InterpolationUtilities.ComposeTransform(transform)); } result = builder.Build(); return(true); }
private Matrix ApplyTransforms(int startOffset = 0) { Matrix matrix = Matrix.Identity; for (var i = startOffset; i < _operations.Count; i++) { TransformOperation operation = _operations[i]; matrix *= operation.Matrix; } return(matrix); }
public void AppendSkew(double x, double y) { var toAdd = new TransformOperation(); toAdd.Type = TransformOperation.OperationType.Skew; toAdd.Data.Skew.X = x; toAdd.Data.Skew.Y = y; toAdd.Bake(); _operations.Add(toAdd); }
public void AppendTranslate(double x, double y) { var toAdd = new TransformOperation(); toAdd.Type = TransformOperation.OperationType.Translate; toAdd.Data.Translate.X = x; toAdd.Data.Translate.Y = y; toAdd.Bake(); _operations.Add(toAdd); }
/// <summary> /// Attempts to interpolate between two transform operations. /// </summary> /// <param name="from">Source operation.</param> /// <param name="to">Target operation.</param> /// <param name="progress">Interpolation progress.</param> /// <param name="result">Interpolation result that will be filled in when operation was successful.</param> /// <remarks> /// Based upon https://www.w3.org/TR/css-transforms-1/#interpolation-of-transform-functions. /// </remarks> public static bool TryInterpolate(TransformOperation?from, TransformOperation?to, double progress, ref TransformOperation result) { bool fromIdentity = IsOperationIdentity(ref from); bool toIdentity = IsOperationIdentity(ref to); if (fromIdentity && toIdentity) { return(true); } // ReSharper disable PossibleInvalidOperationException TransformOperation fromValue = fromIdentity ? Identity : from.Value; TransformOperation toValue = toIdentity ? Identity : to.Value; // ReSharper restore PossibleInvalidOperationException var interpolationType = toIdentity ? fromValue.Type : toValue.Type; result.Type = interpolationType; switch (interpolationType) { case OperationType.Translate: { double fromX = fromIdentity ? 0 : fromValue.Data.Translate.X; double fromY = fromIdentity ? 0 : fromValue.Data.Translate.Y; double toX = toIdentity ? 0 : toValue.Data.Translate.X; double toY = toIdentity ? 0 : toValue.Data.Translate.Y; result.Data.Translate.X = InterpolationUtilities.InterpolateScalars(fromX, toX, progress); result.Data.Translate.Y = InterpolationUtilities.InterpolateScalars(fromY, toY, progress); result.Bake(); break; } case OperationType.Rotate: { double fromAngle = fromIdentity ? 0 : fromValue.Data.Rotate.Angle; double toAngle = toIdentity ? 0 : toValue.Data.Rotate.Angle; result.Data.Rotate.Angle = InterpolationUtilities.InterpolateScalars(fromAngle, toAngle, progress); result.Bake(); break; } case OperationType.Scale: { double fromX = fromIdentity ? 1 : fromValue.Data.Scale.X; double fromY = fromIdentity ? 1 : fromValue.Data.Scale.Y; double toX = toIdentity ? 1 : toValue.Data.Scale.X; double toY = toIdentity ? 1 : toValue.Data.Scale.Y; result.Data.Scale.X = InterpolationUtilities.InterpolateScalars(fromX, toX, progress); result.Data.Scale.Y = InterpolationUtilities.InterpolateScalars(fromY, toY, progress); result.Bake(); break; } case OperationType.Skew: { double fromX = fromIdentity ? 0 : fromValue.Data.Skew.X; double fromY = fromIdentity ? 0 : fromValue.Data.Skew.Y; double toX = toIdentity ? 0 : toValue.Data.Skew.X; double toY = toIdentity ? 0 : toValue.Data.Skew.Y; result.Data.Skew.X = InterpolationUtilities.InterpolateScalars(fromX, toX, progress); result.Data.Skew.Y = InterpolationUtilities.InterpolateScalars(fromY, toY, progress); result.Bake(); break; } case OperationType.Matrix: { var fromMatrix = fromIdentity ? Matrix.Identity : fromValue.Matrix; var toMatrix = toIdentity ? Matrix.Identity : toValue.Matrix; if (!Matrix.TryDecomposeTransform(fromMatrix, out Matrix.Decomposed fromDecomposed) || !Matrix.TryDecomposeTransform(toMatrix, out Matrix.Decomposed toDecomposed)) { return(false); } var interpolated = InterpolationUtilities.InterpolateDecomposedTransforms( ref fromDecomposed, ref toDecomposed, progress); result.Matrix = InterpolationUtilities.ComposeTransform(interpolated); break; } case OperationType.Identity: { // Do nothing. break; } } return(true); }
public void Append(TransformOperation toAdd) { _operations.Add(toAdd); }