static TransformationMatrix applyTransformAnimation(const TransformOperations& from, const TransformOperations& to, double progress, const FloatSize& boxSize, bool listsMatch) { TransformationMatrix matrix; // First frame of an animation. if (!progress) { from.apply(boxSize, matrix); return matrix; } // Last frame of an animation. if (progress == 1) { to.apply(boxSize, matrix); return matrix; } // If we have incompatible operation lists, we blend the resulting matrices. if (!listsMatch) { TransformationMatrix fromMatrix; to.apply(boxSize, matrix); from.apply(boxSize, fromMatrix); matrix.blend(fromMatrix, progress); return matrix; } // Animation to "-webkit-transform: none". if (!to.size()) { TransformOperations blended(from); for (auto& operation : blended.operations()) operation->blend(nullptr, progress, true)->apply(matrix, boxSize); return matrix; } // Animation from "-webkit-transform: none". if (!from.size()) { TransformOperations blended(to); for (auto& operation : blended.operations()) operation->blend(nullptr, 1 - progress, true)->apply(matrix, boxSize); return matrix; } // Normal animation with a matching operation list. TransformOperations blended(to); for (size_t i = 0; i < blended.operations().size(); ++i) blended.operations()[i]->blend(from.at(i), progress, !from.at(i))->apply(matrix, boxSize); return matrix; }
void ArgumentCoder<TransformOperations>::encode(ArgumentEncoder& encoder, const TransformOperations& transformOperations) { encoder << static_cast<uint32_t>(transformOperations.size()); for (size_t i = 0; i < transformOperations.size(); ++i) { const TransformOperation* operation = transformOperations.at(i); encoder.encodeEnum(operation->getOperationType()); switch (operation->getOperationType()) { case TransformOperation::SCALE_X: case TransformOperation::SCALE_Y: case TransformOperation::SCALE: case TransformOperation::SCALE_Z: case TransformOperation::SCALE_3D: encoder << static_cast<const ScaleTransformOperation*>(operation)->x(); encoder << static_cast<const ScaleTransformOperation*>(operation)->y(); encoder << static_cast<const ScaleTransformOperation*>(operation)->z(); break; case TransformOperation::TRANSLATE_X: case TransformOperation::TRANSLATE_Y: case TransformOperation::TRANSLATE: case TransformOperation::TRANSLATE_Z: case TransformOperation::TRANSLATE_3D: ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->x()); ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->y()); ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->z()); break; case TransformOperation::ROTATE: case TransformOperation::ROTATE_X: case TransformOperation::ROTATE_Y: case TransformOperation::ROTATE_3D: encoder << static_cast<const RotateTransformOperation*>(operation)->x(); encoder << static_cast<const RotateTransformOperation*>(operation)->y(); encoder << static_cast<const RotateTransformOperation*>(operation)->z(); encoder << static_cast<const RotateTransformOperation*>(operation)->angle(); break; case TransformOperation::SKEW_X: case TransformOperation::SKEW_Y: case TransformOperation::SKEW: encoder << static_cast<const SkewTransformOperation*>(operation)->angleX(); encoder << static_cast<const SkewTransformOperation*>(operation)->angleY(); break; case TransformOperation::MATRIX: ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const MatrixTransformOperation*>(operation)->matrix()); break; case TransformOperation::MATRIX_3D: ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const Matrix3DTransformOperation*>(operation)->matrix()); break; case TransformOperation::PERSPECTIVE: ArgumentCoder<Length>::encode(encoder, static_cast<const PerspectiveTransformOperation*>(operation)->perspective()); break; case TransformOperation::IDENTITY: break; case TransformOperation::NONE: ASSERT_NOT_REACHED(); break; } } }
void PrintTo(const AnimatableTransform& animTransform, ::std::ostream* os) { TransformOperations ops = animTransform.transformOperations(); *os << "AnimatableTransform("; // FIXME: TransformOperations should really have it's own pretty-printer // then we could just call that. // FIXME: Output useful names not just the raw matrixes. for (unsigned i = 0; i < ops.size(); i++) { const TransformOperation* op = ops.at(i); TransformationMatrix matrix; op->apply(matrix, FloatSize(1.0, 1.0)); *os << "["; if (matrix.isAffine()) { *os << matrix.a(); *os << " " << matrix.b(); *os << " " << matrix.c(); *os << " " << matrix.d(); *os << " " << matrix.e(); *os << " " << matrix.f(); } else { *os << matrix.m11(); *os << " " << matrix.m12(); *os << " " << matrix.m13(); *os << " " << matrix.m14(); *os << " "; *os << " " << matrix.m21(); *os << " " << matrix.m22(); *os << " " << matrix.m23(); *os << " " << matrix.m24(); *os << " "; *os << " " << matrix.m31(); *os << " " << matrix.m32(); *os << " " << matrix.m33(); *os << " " << matrix.m34(); *os << " "; *os << " " << matrix.m41(); *os << " " << matrix.m42(); *os << " " << matrix.m43(); *os << " " << matrix.m44(); } *os << "]"; if (i < ops.size() - 1) *os << ", "; } *os << ")"; }