void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionState) { if (string.isEmpty()) return; RefPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create(); if (BisonCSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, HTMLStandardMode, 0)) { // Convert to TransformOperations. This can fail if a property // requires style (i.e., param uses 'ems' or 'exs') RefPtrWillBeRawPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform); // Check for a "none" or empty transform. In these cases we can use the default identity matrix. if (!value || (value->isPrimitiveValue() && (toCSSPrimitiveValue(value.get()))->getValueID() == CSSValueNone)) return; DEFINE_STATIC_REF(RenderStyle, defaultStyle, RenderStyle::createDefaultStyle()); TransformOperations operations; if (!TransformBuilder::createTransformOperations(value.get(), CSSToLengthConversionData(defaultStyle, defaultStyle, 0, 0, 1.0f), operations)) { exceptionState.throwDOMException(SyntaxError, "Failed to interpret '" + string + "' as a transformation operation."); return; } // Convert transform operations to a TransformationMatrix. This can fail // if a param has a percentage ('%') if (operations.dependsOnBoxSize()) exceptionState.throwDOMException(SyntaxError, "The transformation depends on the box size, which is not supported."); TransformationMatrix t; operations.apply(FloatSize(0, 0), t); // set the matrix m_matrix = t; } else { // There is something there but parsing failed. exceptionState.throwDOMException(SyntaxError, "Failed to parse '" + string + "'."); } }
void CCLayerAnimationControllerImpl::tickAnimations(double now) { for (size_t i = 0; i < m_activeAnimations.size(); ++i) { if (m_activeAnimations[i]->runState() == CCActiveAnimation::Running) { double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(now); switch (m_activeAnimations[i]->targetProperty()) { case CCActiveAnimation::Transform: { const CCTransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->animationCurve()->toTransformAnimationCurve(); const TransformOperations operations = transformAnimationCurve->getValue(trimmed); if (m_activeAnimations[i]->isFinishedAt(now)) m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, now); // Decide here if absolute or relative. Absolute for now. TransformationMatrix toApply; operations.apply(FloatSize(), toApply); m_client->setTransform(toApply); break; } case CCActiveAnimation::Opacity: { const CCFloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->animationCurve()->toFloatAnimationCurve(); const float opacity = floatAnimationCurve->getValue(trimmed); if (m_activeAnimations[i]->isFinishedAt(now)) m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, now); m_client->setOpacity(opacity); break; } } // switch } // if running } // for each animation }
void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionState) { if (string.isEmpty()) return; if (const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyTransform, string)) { // Check for a "none" transform. In these cases we can use the default // identity matrix. if (value->isIdentifierValue() && (toCSSIdentifierValue(value))->getValueID() == CSSValueNone) return; DEFINE_STATIC_REF(ComputedStyle, initialStyle, createInitialStyle()); TransformOperations operations = TransformBuilder::createTransformOperations( *value, CSSToLengthConversionData(initialStyle, initialStyle, LayoutViewItem(nullptr), 1.0f)); // Convert transform operations to a TransformationMatrix. This can fail // if a param has a percentage ('%') if (operations.dependsOnBoxSize()) exceptionState.throwDOMException(SyntaxError, "The transformation depends on the box " "size, which is not supported."); m_matrix = TransformationMatrix::create(); operations.apply(FloatSize(0, 0), *m_matrix); } else { // There is something there but parsing failed. exceptionState.throwDOMException(SyntaxError, "Failed to parse '" + string + "'."); } }
void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionState) { if (string.isEmpty()) return; // FIXME: crbug.com/154772 - should this continue to use legacy style parsing? if (RefPtrWillBeRawPtr<CSSValue> value = CSSParser::parseSingleValue(CSSPropertyWebkitTransform, string)) { // Check for a "none" transform. In these cases we can use the default identity matrix. if (value->isPrimitiveValue() && (toCSSPrimitiveValue(value.get()))->getValueID() == CSSValueNone) return; // FIXME: This has a null pointer crash if we use ex units (crbug.com/414145) DEFINE_STATIC_REF(RenderStyle, defaultStyle, RenderStyle::createDefaultStyle()); TransformOperations operations; if (!TransformBuilder::createTransformOperations(value.get(), CSSToLengthConversionData(defaultStyle, defaultStyle, 0, 0, 1.0f), operations)) { exceptionState.throwDOMException(SyntaxError, "Failed to interpret '" + string + "' as a transformation operation."); return; } // Convert transform operations to a TransformationMatrix. This can fail // if a param has a percentage ('%') if (operations.dependsOnBoxSize()) exceptionState.throwDOMException(SyntaxError, "The transformation depends on the box size, which is not supported."); TransformationMatrix t; operations.apply(FloatSize(0, 0), t); // set the matrix m_matrix = t; } else { // There is something there but parsing failed. exceptionState.throwDOMException(SyntaxError, "Failed to parse '" + string + "'."); } }
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; }
TransformOperations TransformOperations::blendByUsingMatrixInterpolation(const TransformOperations& from, double progress, const LayoutSize& size) const { TransformOperations result; // Convert the TransformOperations into matrices TransformationMatrix fromTransform; TransformationMatrix toTransform; from.apply(size, fromTransform); apply(size, toTransform); toTransform.blend(fromTransform, progress); // Append the result result.operations().append(Matrix3DTransformOperation::create(toTransform)); return result; }