void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) { ASSERT(resultElement); SVGElement* targetElement = this->targetElement(); if (!targetElement || !isSVGAnimateElement(*resultElement)) return; ASSERT(percentage >= 0 && percentage <= 1); ASSERT(m_animator); ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this)); ASSERT(animatedPropertyType() != AnimatedUnknown); ASSERT(m_fromProperty); ASSERT(m_fromProperty->type() == animatedPropertyType()); ASSERT(m_toProperty); SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement); ASSERT(resultAnimationElement->m_animatedProperty); ASSERT(resultAnimationElement->animatedPropertyType() == animatedPropertyType()); if (isSVGSetElement(*this)) percentage = 1; if (calcMode() == CalcModeDiscrete) percentage = percentage < 0.5 ? 0 : 1; // Target element might have changed. m_animator->setContextElement(targetElement); // Values-animation accumulates using the last values entry corresponding to the end of duration time. SVGPropertyBase* toAtEndOfDurationProperty = m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty.get() : m_toProperty.get(); m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromProperty.get(), m_toProperty.get(), toAtEndOfDurationProperty, resultAnimationElement->m_animatedProperty.get()); }
void SVGAnimateElement::applyResultsToTarget() { ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this)); ASSERT(animatedPropertyType() != AnimatedUnknown); // Early exit if our animated type got destructed by a previous endedActiveInterval(). if (!m_animatedProperty) return; // We do update the style and the animation property independent of each other. ShouldApplyAnimationType shouldApply = shouldApplyAnimation(targetElement(), attributeName()); if (shouldApply == ApplyXMLandCSSAnimation) { applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedProperty->valueAsString()); } else if (m_animator.isAnimatingCSSProperty()) { // CSS properties animation code-path. // Convert the result of the animation to a String and apply it as CSS property on the target & all instances. applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedProperty->valueAsString()); return; } // SVG DOM animVal animation code-path. // At this point the SVG DOM values are already changed, unlike for CSS. // We only have to trigger update notifications here. notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName()); }
bool SVGAnimateElement::hasValidAttributeType() { SVGElement* targetElement = this->targetElement(); if (!targetElement) return false; return animatedPropertyType() != AnimatedUnknown && !hasInvalidCSSAttributeType(); }
bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() { // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. switch (animatedPropertyType()) { case AnimatedBoolean: case AnimatedEnumeration: case AnimatedPreserveAspectRatio: case AnimatedString: case AnimatedUnknown: return false; default: return true; } }