Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Unified Diff: Source/core/animation/ElementAnimation.cpp

Issue 105273010: Web Animations API: Start implementation of timing input objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Change treatment of invalid duration input Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/animation/ElementAnimation.cpp
diff --git a/Source/core/animation/ElementAnimation.cpp b/Source/core/animation/ElementAnimation.cpp
index 517004ffd48ab6f7ed6c0343a170189ea1723ec0..cf0b331142850ae7f094d6d6a3998fec9f7c67b1 100644
--- a/Source/core/animation/ElementAnimation.cpp
+++ b/Source/core/animation/ElementAnimation.cpp
@@ -32,10 +32,10 @@
#include "core/animation/ElementAnimation.h"
#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ScriptValue.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/css/CSSAnimations.h"
#include "core/css/parser/BisonCSSParser.h"
-#include "core/css/RuntimeCSSEnabled.h"
#include "core/css/resolver/StyleResolver.h"
#include "wtf/text/StringBuilder.h"
#include <algorithm>
@@ -60,22 +60,113 @@ CSSPropertyID ElementAnimation::camelCaseCSSPropertyNameToID(const String& prope
return id;
}
-Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, double duration)
+void ElementAnimation::populateTiming(Timing& timing, Dictionary timingInputDictionary)
+{
+ // FIXME: This method needs to be refactored to handle invalid
+ // null, NaN, Infinity values better.
+ // See: http://www.w3.org/TR/WebIDL/#es-double
+ double startDelay = 0;
+ timingInputDictionary.get("delay", startDelay);
+ if (!isnan(startDelay) && !isinf(startDelay))
+ timing.startDelay = startDelay;
+
+ String fillMode;
+ timingInputDictionary.get("fill", fillMode);
+ if (fillMode == "none") {
+ timing.fillMode = Timing::FillModeNone;
+ } else if (fillMode == "backwards") {
+ timing.fillMode = Timing::FillModeBackwards;
+ } else if (fillMode == "both") {
+ timing.fillMode = Timing::FillModeBoth;
+ } else if (fillMode == "forwards") {
+ timing.fillMode = Timing::FillModeForwards;
+ }
+
+ double iterationStart = 0;
+ timingInputDictionary.get("iterationStart", iterationStart);
+ if (!isnan(iterationStart) && !isinf(iterationStart))
+ timing.iterationStart = std::max<double>(iterationStart, 0);
+
+ double iterationCount = 1;
+ timingInputDictionary.get("iterations", iterationCount);
+ if (!isnan(iterationCount))
+ timing.iterationCount = std::max<double>(iterationCount, 0);
+
+ v8::Local<v8::Value> iterationDurationValue;
+ bool hasIterationDurationValue = timingInputDictionary.get("duration", iterationDurationValue);
+ if (hasIterationDurationValue) {
+ double iterationDuration = iterationDurationValue->NumberValue();
+ if (!isnan(iterationDuration) && iterationDuration >= 0) {
+ timing.iterationDuration = iterationDuration;
+ timing.hasIterationDuration = true;
+ }
+ }
+
+ double playbackRate = 1;
+ timingInputDictionary.get("playbackRate", playbackRate);
+ if (!isnan(playbackRate) && !isinf(playbackRate))
+ timing.playbackRate = playbackRate;
+
+ String direction;
+ timingInputDictionary.get("direction", direction);
+ if (direction == "reverse") {
+ timing.direction = Timing::PlaybackDirectionReverse;
+ } else if (direction == "alternate") {
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ } else if (direction == "alternate-reverse") {
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ }
+
+ timing.assertValid();
+}
+
+static bool checkDocumentAndRenderer(Element* element)
+{
+ if (!element->inActiveDocument())
+ return false;
+ element->document().updateStyleIfNeeded();
+ if (!element->renderer())
+ return false;
+ return true;
+}
+
+Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
{
ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
// FIXME: This test will not be neccessary once resolution of keyframe values occurs at
// animation application time.
- if (!element->inActiveDocument())
+ if (!checkDocumentAndRenderer(element))
return 0;
- element->document().updateStyleIfNeeded();
- if (!element->renderer())
+
+ return startAnimation(element, keyframeDictionaryVector, timingInput);
+}
+
+Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+
+ // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
+ // animation application time.
+ if (!checkDocumentAndRenderer(element))
+ return 0;
+
+ return startAnimation(element, keyframeDictionaryVector, timingInput);
+}
+
+Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+
+ // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
+ // animation application time.
+ if (!checkDocumentAndRenderer(element))
return 0;
- return startAnimation(element, keyframeDictionaryVector, duration);
+ return startAnimation(element, keyframeDictionaryVector);
}
-Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, double duration)
+static PassRefPtr<KeyframeEffectModel> createKeyframeEffectModel(Element* element, Vector<Dictionary> keyframeDictionaryVector)
{
KeyframeEffectModel::KeyframeVector keyframes;
Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
@@ -108,7 +199,7 @@ Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary>
for (size_t j = 0; j < keyframeProperties.size(); ++j) {
String property = keyframeProperties[j];
- CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
+ CSSPropertyID id = ElementAnimation::camelCaseCSSPropertyNameToID(property);
// FIXME: There is no way to store invalid properties or invalid values
// in a Keyframe object, so for now I just skip over them. Eventually we
@@ -126,15 +217,47 @@ Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary>
// FIXME: Replace this with code that just parses, when that code is available.
RefPtr<KeyframeEffectModel> effect = StyleResolver::createKeyframeEffectModel(*element, propertySetVector, keyframes);
+ return effect;
+}
+
+Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
+{
+ RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
+
+ Timing timing;
+ populateTiming(timing, timingInput);
+
+ RefPtr<Animation> animation = Animation::create(element, effect, timing);
+ DocumentTimeline* timeline = element->document().timeline();
+ ASSERT(timeline);
+ timeline->play(animation.get());
+
+ return animation.get();
+}
+
+Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
+{
+ RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
+
+ Timing timing;
+ if (!isnan(timingInput)) {
+ timing.hasIterationDuration = true;
+ timing.iterationDuration = std::max<double>(timingInput, 0);
+ }
+
+ RefPtr<Animation> animation = Animation::create(element, effect, timing);
+ DocumentTimeline* timeline = element->document().timeline();
+ ASSERT(timeline);
+ timeline->play(animation.get());
+
+ return animation.get();
+}
+
+Animation* ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector)
+{
+ RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
- // FIXME: Totally hardcoded Timing for now. Will handle timing parameters later.
Timing timing;
- // FIXME: Currently there is no way to tell whether or not an iterationDuration
- // has been specified (becauser the default argument is 0). So any animation
- // created using Element.animate() will have a timing with hasIterationDuration()
- // == true.
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::max<double>(duration, 0);
RefPtr<Animation> animation = Animation::create(element, effect, timing);
DocumentTimeline* timeline = element->document().timeline();

Powered by Google App Engine
This is Rietveld 408576698