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

Side by Side 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 default fill back to "forwards". Move timing input processing into method. 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 unified diff | Download patch
« no previous file with comments | « Source/core/animation/ElementAnimation.h ('k') | Source/core/animation/ElementAnimation.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 14 matching lines...) Expand all
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "core/animation/ElementAnimation.h" 32 #include "core/animation/ElementAnimation.h"
33 33
34 #include "bindings/v8/Dictionary.h" 34 #include "bindings/v8/Dictionary.h"
35 #include "bindings/v8/ScriptValue.h"
35 #include "core/animation/DocumentTimeline.h" 36 #include "core/animation/DocumentTimeline.h"
36 #include "core/css/parser/BisonCSSParser.h" 37 #include "core/css/parser/BisonCSSParser.h"
37 #include "core/css/RuntimeCSSEnabled.h"
38 #include "core/css/resolver/StyleResolver.h" 38 #include "core/css/resolver/StyleResolver.h"
39 #include "wtf/text/StringBuilder.h" 39 #include "wtf/text/StringBuilder.h"
40 #include <algorithm> 40 #include <algorithm>
41 41
42 namespace WebCore { 42 namespace WebCore {
43 43
44 CSSPropertyID ElementAnimation::camelCaseCSSPropertyNameToID(const String& prope rtyName) 44 CSSPropertyID ElementAnimation::camelCaseCSSPropertyNameToID(const String& prope rtyName)
45 { 45 {
46 if (propertyName.find('-') != kNotFound) 46 if (propertyName.find('-') != kNotFound)
47 return CSSPropertyInvalid; 47 return CSSPropertyInvalid;
48 48
49 StringBuilder builder; 49 StringBuilder builder;
50 size_t position = 0; 50 size_t position = 0;
51 size_t end; 51 size_t end;
52 while ((end = propertyName.find(isASCIIUpper, position)) != kNotFound) { 52 while ((end = propertyName.find(isASCIIUpper, position)) != kNotFound) {
53 builder.append(propertyName.substring(position, end - position) + "-" + toASCIILower((propertyName)[end])); 53 builder.append(propertyName.substring(position, end - position) + "-" + toASCIILower((propertyName)[end]));
54 position = end + 1; 54 position = end + 1;
55 } 55 }
56 builder.append(propertyName.substring(position)); 56 builder.append(propertyName.substring(position));
57 // Doesn't handle prefixed properties. 57 // Doesn't handle prefixed properties.
58 CSSPropertyID id = cssPropertyID(builder.toString()); 58 CSSPropertyID id = cssPropertyID(builder.toString());
59 return id; 59 return id;
60 } 60 }
61 61
62 void ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDict ionaryVector, double duration) 62 static void populateTiming(Timing& timing, Dictionary timingInputDictionary)
63 {
64 double startDelay = 0;
65 timingInputDictionary.get("delay", startDelay);
66 if (!isnan(startDelay) && !isinf(startDelay))
67 timing.startDelay = startDelay;
68
69 String fillMode;
70 timingInputDictionary.get("fill", fillMode);
71 // FIXME: This will need to be changed to "forwards" when
72 // Timing.h implements the spec change that makes default
73 // fill mode "none".
74 if (fillMode == "none") {
75 timing.fillMode = Timing::FillModeNone;
76 } else if (fillMode == "backwards") {
77 timing.fillMode = Timing::FillModeBackwards;
78 } else if (fillMode == "both") {
79 timing.fillMode = Timing::FillModeBoth;
80 }
81
82 double iterationStart = 0;
83 timingInputDictionary.get("iterationStart", iterationStart);
84 if (!isnan(iterationStart) && !isinf(iterationStart))
dstockwell 2014/01/15 11:13:52 I'm not sure this is the correct procedure for con
rjwright 2014/01/17 05:08:15 Yeah I wasn't sure what to do about this.
85 timing.iterationStart = std::max<double>(iterationStart, 0);
86
87 double iterationCount = 1;
88 timingInputDictionary.get("iterations", iterationCount);
89 if (!isnan(iterationCount))
90 timing.iterationCount = std::max<double>(iterationCount, 0);
91
92 v8::Local<v8::Value> iterationDurationValue;
93 bool hasIterationDurationValue = timingInputDictionary.get("duration", itera tionDurationValue);
dstockwell 2014/01/15 11:13:52 Did we discover whether this will invoke a custom
rjwright 2014/01/17 05:08:15 Yes it does invoke the getter in this case.
94 double iterationDuration = 0;
dstockwell 2014/01/15 11:13:52 just declare this as needed on lines 98 / 103
rjwright 2014/01/17 05:08:15 Done.
95 if (hasIterationDurationValue) {
96 if (iterationDurationValue->IsString()) {
97 // All strings are treated as 'auto' except strings that are numbers , e.g. '1', 'Infinity'.
98 iterationDuration = iterationDurationValue->NumberValue();
99 if (!isnan(iterationDuration))
100 timing.iterationDuration = std::max<double>(iterationDuration, 0 );
101 timing.hasIterationDuration = true;
102 } else if (iterationDurationValue->IsNumber()) {
103 iterationDuration = iterationDurationValue->NumberValue();
104 if (!isnan(iterationDuration)) {
105 timing.iterationDuration = std::max<double>(iterationDuration, 0 );
106 timing.hasIterationDuration = true;
107 }
108 }
109 }
110
111 double playbackRate = 1;
112 timingInputDictionary.get("playbackRate", playbackRate);
113 if (!isnan(playbackRate) && !isinf(playbackRate))
114 timing.playbackRate = playbackRate;
115
116 String direction;
117 timingInputDictionary.get("direction", direction);
118 if (direction == "reverse") {
119 timing.direction = Timing::PlaybackDirectionReverse;
120 } else if (direction == "alternate") {
121 timing.direction = Timing::PlaybackDirectionAlternate;
122 } else if (direction == "alternate-reverse") {
123 timing.direction = Timing::PlaybackDirectionAlternateReverse;
124 }
125 }
dstockwell 2014/01/15 11:13:52 timing.assertValid();
rjwright 2014/01/17 05:08:15 Done.
126
127 static void processTimingInput(Timing& timing, v8::Handle<v8::Value> timingInput )
128 {
129 if (!timingInput.IsEmpty()) {
130 if (timingInput->IsObject()) {
131 populateTiming(timing, Dictionary(v8::Handle<v8::Value>::Cast(timing Input), v8::Isolate::GetCurrent()));
132 } else {
133 double duration = timingInput->NumberValue();
134 if (!isnan(duration)) {
135 timing.hasIterationDuration = true;
136 timing.iterationDuration = std::max<double>(duration, 0);
137 }
138 }
139 }
140 }
141
142 static bool checkDocumentAndRenderer(Element* element)
143 {
144 if (!element->inActiveDocument())
145 return false;
146 element->document().updateStyleIfNeeded();
147 if (!element->renderer())
148 return false;
149 return true;
150 }
151
152 void ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDict ionaryVector)
63 { 153 {
64 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); 154 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
65 155
66 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at 156 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at
67 // animation application time. 157 // animation application time.
68 if (!element->inActiveDocument()) 158 if (!checkDocumentAndRenderer(element))
69 return;
70 element->document().updateStyleIfNeeded();
71 if (!element->renderer())
72 return; 159 return;
73 160
74 startAnimation(element, keyframeDictionaryVector, duration); 161 startAnimation(element, keyframeDictionaryVector);
75 } 162 }
76 163
77 void ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyfr ameDictionaryVector, double duration) 164 void ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDict ionaryVector, ScriptValue timingInput)
165 {
166 ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
167
168 // FIXME: This test will not be neccessary once resolution of keyframe value s occurs at
169 // animation application time.
170 if (!checkDocumentAndRenderer(element))
171 return;
172
173 startAnimation(element, keyframeDictionaryVector, timingInput.v8Value());
174 }
175
176 void ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyfr ameDictionaryVector, v8::Handle<v8::Value> timingInput)
78 { 177 {
79 KeyframeEffectModel::KeyframeVector keyframes; 178 KeyframeEffectModel::KeyframeVector keyframes;
80 Vector<RefPtr<MutableStylePropertySet> > propertySetVector; 179 Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
81 180
82 for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) { 181 for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
83 RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::c reate(); 182 RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::c reate();
84 propertySetVector.append(propertySet); 183 propertySetVector.append(propertySet);
85 184
86 RefPtr<Keyframe> keyframe = Keyframe::create(); 185 RefPtr<Keyframe> keyframe = Keyframe::create();
87 keyframes.append(keyframe); 186 keyframes.append(keyframe);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 218
120 String value; 219 String value;
121 keyframeDictionaryVector[i].get(property, value); 220 keyframeDictionaryVector[i].get(property, value);
122 propertySet->setProperty(id, value); 221 propertySet->setProperty(id, value);
123 } 222 }
124 } 223 }
125 224
126 // FIXME: Replace this with code that just parses, when that code is availab le. 225 // FIXME: Replace this with code that just parses, when that code is availab le.
127 RefPtr<KeyframeEffectModel> effect = StyleResolver::createKeyframeEffectMode l(*element, propertySetVector, keyframes); 226 RefPtr<KeyframeEffectModel> effect = StyleResolver::createKeyframeEffectMode l(*element, propertySetVector, keyframes);
128 227
129 // FIXME: Totally hardcoded Timing for now. Will handle timing parameters la ter.
130 Timing timing; 228 Timing timing;
131 // FIXME: Currently there is no way to tell whether or not an iterationDurat ion 229 processTimingInput(timing, timingInput);
132 // has been specified (becauser the default argument is 0). So any animation
133 // created using Element.animate() will have a timing with hasIterationDurat ion()
134 // == true.
135 timing.hasIterationDuration = true;
136 timing.iterationDuration = std::max<double>(duration, 0);
137 230
138 RefPtr<Animation> animation = Animation::create(element, effect, timing); 231 RefPtr<Animation> animation = Animation::create(element, effect, timing);
139 DocumentTimeline* timeline = element->document().timeline(); 232 DocumentTimeline* timeline = element->document().timeline();
140 ASSERT(timeline); 233 ASSERT(timeline);
141 timeline->play(animation.get()); 234 timeline->play(animation.get());
142 } 235 }
143 236
144 } // namespace WebCore 237 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/animation/ElementAnimation.h ('k') | Source/core/animation/ElementAnimation.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698