WebTransformationMatrix WebTransformOperations::blend(const WebTransformOperations& from, double progress) const { WebTransformationMatrix toReturn; bool fromIdentity = from.isIdentity(); bool toIdentity = isIdentity(); if (fromIdentity && toIdentity) return toReturn; if (matchesTypes(from)) { size_t numOperations = max(fromIdentity ? 0 : from.m_private->operations.size(), toIdentity ? 0 : m_private->operations.size()); for (size_t i = 0; i < numOperations; ++i) { WebTransformationMatrix blended = blendTransformOperations( fromIdentity ? 0 : &from.m_private->operations[i], toIdentity ? 0 : &m_private->operations[i], progress); toReturn.multiply(blended); } } else { toReturn = apply(); WebTransformationMatrix fromTransform = from.apply(); toReturn.blend(fromTransform, progress); } return toReturn; }
bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize) { if (causesRotationOfAtLeast180Degrees(value, lastValue)) return false; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (operations.apply().isInvertible()) { curve->add(WebTransformKeyframe(keyTime, operations), x1, y1, x2, y2); return true; } return false; }
bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize) { if (causesRotationOfAtLeast180Degrees(value, lastValue)) return false; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (operations.apply().isInvertible()) { curve->add(WebTransformKeyframe(keyTime, operations), timingFunctionType); return true; } return false; }
bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize) { bool canBlend = !lastValue; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (!canBlend) { WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize); canBlend = lastOperations.canBlendWith(operations); } if (canBlend) { curve->add(WebTransformKeyframe(keyTime, operations), x1, y1, x2, y2); return true; } return false; }
bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize) { bool canBlend = !lastValue; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (!canBlend) { WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize); canBlend = lastOperations.canBlendWith(operations); } if (canBlend) { curve->add(WebTransformKeyframe(keyTime, operations), timingFunctionType); return true; } return false; }
bool WebTransformOperations::matchesTypes(const WebTransformOperations& other) const { if (isIdentity() || other.isIdentity()) return true; if (m_private->operations.size() != other.m_private->operations.size()) return false; for (size_t i = 0; i < m_private->operations.size(); ++i) { if (m_private->operations[i].type != other.m_private->operations[i].type && !m_private->operations[i].isIdentity() && !other.m_private->operations[i].isIdentity()) return false; } return true; }
WebTransformOperations toWebTransformOperations(const TransformOperations& transformOperations, const FloatSize& boxSize) { // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects. WebTransformOperations webTransformOperations; for (size_t j = 0; j < transformOperations.size(); ++j) { TransformOperation::OperationType operationType = transformOperations.operations()[j]->getOperationType(); switch (operationType) { case TransformOperation::SCALE_X: case TransformOperation::SCALE_Y: case TransformOperation::SCALE_Z: case TransformOperation::SCALE_3D: case TransformOperation::SCALE: { ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get()); webTransformOperations.appendScale(transform->x(), transform->y(), transform->z()); break; } case TransformOperation::TRANSLATE_X: case TransformOperation::TRANSLATE_Y: case TransformOperation::TRANSLATE_Z: case TransformOperation::TRANSLATE_3D: case TransformOperation::TRANSLATE: { TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get()); webTransformOperations.appendTranslate(floatValueForLength(transform->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1)); break; } case TransformOperation::ROTATE_X: case TransformOperation::ROTATE_Y: case TransformOperation::ROTATE_3D: case TransformOperation::ROTATE: { RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get()); webTransformOperations.appendRotate(transform->x(), transform->y(), transform->z(), transform->angle()); break; } case TransformOperation::SKEW_X: case TransformOperation::SKEW_Y: case TransformOperation::SKEW: { SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get()); webTransformOperations.appendSkew(transform->angleX(), transform->angleY()); break; } case TransformOperation::MATRIX: { MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get()); TransformationMatrix m = transform->matrix(); webTransformOperations.appendMatrix(WebTransformationMatrix(m)); break; } case TransformOperation::MATRIX_3D: { Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get()); TransformationMatrix m = transform->matrix(); webTransformOperations.appendMatrix(WebTransformationMatrix(m)); break; } case TransformOperation::PERSPECTIVE: { PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get()); webTransformOperations.appendPerspective(floatValueForLength(transform->perspective(), 0)); break; } case TransformOperation::IDENTITY: webTransformOperations.appendIdentity(); break; case TransformOperation::NONE: // Do nothing. break; } // switch } // for each operation return webTransformOperations; }