25 #if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
38 using namespace SVGNames;
40 SVGAnimateMotionElement::SVGAnimateMotionElement(
const QualifiedName& tagName, Document* doc)
41 : SVGAnimationElement(tagName, doc)
42 , m_baseIndexInTransformList(0)
47 SVGAnimateMotionElement::~SVGAnimateMotionElement()
51 bool SVGAnimateMotionElement::hasValidTarget()
const
53 if (!SVGAnimationElement::hasValidTarget())
55 SVGElement* targetElement = this->targetElement();
56 if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(
SVGNames::textTag))
59 if (targetElement->hasTagName(
gTag)
60 || targetElement->hasTagName(
defsTag)
61 || targetElement->hasTagName(
useTag)
62 || targetElement->hasTagName(
imageTag)
64 || targetElement->hasTagName(
pathTag)
65 || targetElement->hasTagName(
rectTag)
68 || targetElement->hasTagName(
lineTag)
71 || targetElement->hasTagName(
textTag)
73 || targetElement->hasTagName(
maskTag)
74 || targetElement->hasTagName(
aTag)
75 #if ENABLE(SVG_FOREIGN_OBJECT)
83 void SVGAnimateMotionElement::parseMappedAttribute(MappedAttribute* attr)
87 pathFromSVGData(m_path, attr->value());
89 SVGAnimationElement::parseMappedAttribute(attr);
92 SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode()
const
94 static const AtomicString autoVal(
"auto");
95 static const AtomicString autoReverse(
"auto-reverse");
97 if (rotate == autoVal)
99 if (rotate == autoReverse)
100 return RotateAutoReverse;
104 Path SVGAnimateMotionElement::animationPath()
const
106 for (Node* child = firstChild(); child; child = child->nextSibling()) {
108 SVGMPathElement* mPath =
static_cast<SVGMPathElement*
>(child);
109 SVGPathElement* pathElement = mPath->pathElement();
111 return pathElement->toPathData();
120 static bool parsePoint(
const String& s, FloatPoint& point)
124 const UChar* cur = s.characters();
125 const UChar*
end = cur + s.length();
127 if (!skipOptionalSpaces(cur, end))
131 if (!parseNumber(cur, end, x))
135 if (!parseNumber(cur, end, y))
138 point = FloatPoint(x, y);
141 return !skipOptionalSpaces(cur, end);
144 void SVGAnimateMotionElement::resetToBaseValue(
const String&)
146 if (!hasValidTarget())
148 SVGElement* target = targetElement();
149 AffineTransform* transform = target->supplementalTransform();
155 bool SVGAnimateMotionElement::calculateFromAndToValues(
const String& fromString,
const String& toString)
157 parsePoint(fromString, m_fromPoint);
158 parsePoint(toString, m_toPoint);
162 bool SVGAnimateMotionElement::calculateFromAndByValues(
const String& fromString,
const String& byString)
164 parsePoint(fromString, m_fromPoint);
166 parsePoint(byString, byPoint);
167 m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y());
171 void SVGAnimateMotionElement::calculateAnimatedValue(
float percentage,
unsigned repeat, SVGSMILElement*)
173 SVGElement* target = targetElement();
176 AffineTransform* transform = target->supplementalTransform();
185 if (animationMode() == PathAnimation) {
186 ASSERT(!animationPath().isEmpty());
187 Path path = animationPath();
188 float positionOnPath = path.length() * percentage;
190 FloatPoint position = path.pointAtLength(positionOnPath, ok);
192 transform->translate(position.x(), position.y());
193 RotateMode rotateMode = this->rotateMode();
194 if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) {
195 float angle = path.normalAngleAtLength(positionOnPath, ok);
196 if (rotateMode == RotateAutoReverse)
198 transform->rotate(angle);
203 FloatSize diff = m_toPoint - m_fromPoint;
204 transform->translate(diff.width() * percentage + m_fromPoint.x(), diff.height() * percentage + m_fromPoint.y());
207 void SVGAnimateMotionElement::applyResultsToTarget()
210 SVGElement* targetElement = this->targetElement();
211 if (targetElement && targetElement->renderer())
212 targetElement->renderer()->setNeedsLayout(
true);
215 HashSet<SVGElementInstance*>* instances = document()->accessSVGExtensions()->instancesForElement(targetElement);
218 HashSet<SVGElementInstance*>::iterator end = instances->end();
219 for (HashSet<SVGElementInstance*>::iterator it = instances->begin(); it != end; ++it) {
220 SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
221 ASSERT(shadowTreeElement);
222 AffineTransform* transform = shadowTreeElement->supplementalTransform();
223 AffineTransform* t = targetElement->supplementalTransform();
224 transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
225 if (shadowTreeElement->renderer())
226 shadowTreeElement->renderer()->setNeedsLayout(
true);
230 float SVGAnimateMotionElement::calculateDistance(
const String& fromString,
const String& toString)
234 if (!parsePoint(fromString, from))
236 if (!parsePoint(toString, to))
238 FloatSize diff = to - from;
239 return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
244 #endif // ENABLE(SVG)
DOM::QualifiedName useTag
DOM::QualifiedName polylineTag
DOM::QualifiedName polygonTag
DOM::QualifiedName circleTag
DOM::QualifiedName lineTag
DOM::QualifiedName ellipseTag
DOM::QualifiedName rectTag
DOM::QualifiedName pathTag
DOM::QualifiedName maskTag
DOM::QualifiedName imageTag
DOM::QualifiedName switchTag
DOM::QualifiedName mpathTag
DOM::QualifiedName pathAttr
DOM::QualifiedName rotateAttr
DOM::QualifiedName foreignObjectTag
DOM::QualifiedName defsTag
DOM::QualifiedName clipPathTag
DOM::QualifiedName textTag