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

Side by Side Diff: Source/core/animation/StringKeyframe.cpp

Issue 863863004: Implemented additive animations for length (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed AnimationStackTest Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/animation/StringKeyframe.h" 6 #include "core/animation/StringKeyframe.h"
7 7
8 #include "core/animation/ColorStyleInterpolation.h" 8 #include "core/animation/InterpolationFactory.h"
9 #include "core/animation/ConstantStyleInterpolation.h" 9 #include "core/animation/StyleInterpolation.h"
10 #include "core/animation/DeferredLegacyStyleInterpolation.h"
11 #include "core/animation/DoubleStyleInterpolation.h"
12 #include "core/animation/ImageStyleInterpolation.h"
13 #include "core/animation/LegacyStyleInterpolation.h"
14 #include "core/animation/LengthBoxStyleInterpolation.h"
15 #include "core/animation/LengthPairStyleInterpolation.h"
16 #include "core/animation/LengthStyleInterpolation.h"
17 #include "core/animation/ListStyleInterpolation.h"
18 #include "core/animation/SVGLengthStyleInterpolation.h"
19 #include "core/animation/ShadowStyleInterpolation.h"
20 #include "core/animation/VisibilityStyleInterpolation.h"
21 #include "core/animation/css/CSSAnimations.h" 10 #include "core/animation/css/CSSAnimations.h"
22 #include "core/css/CSSPropertyMetadata.h" 11 #include "core/css/CSSPropertyMetadata.h"
23 #include "core/css/resolver/StyleResolver.h" 12 #include "core/css/resolver/StyleResolver.h"
24 #include "core/layout/style/LayoutStyle.h" 13 #include "core/layout/style/LayoutStyle.h"
25 14
26 namespace blink { 15 namespace blink {
27 16
28 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom) 17 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom)
29 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing) 18 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
30 , m_propertySet(copyFrom.m_propertySet->mutableCopy()) 19 , m_propertySet(copyFrom.m_propertySet->mutableCopy())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 , m_value(value) 57 , m_value(value)
69 { } 58 { }
70 59
71 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset , PassRefPtr<TimingFunction> easing, CSSValue* value) 60 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset , PassRefPtr<TimingFunction> easing, CSSValue* value)
72 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::Compos iteReplace) 61 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::Compos iteReplace)
73 , m_value(value) 62 , m_value(value)
74 { 63 {
75 ASSERT(!isNull(m_offset)); 64 ASSERT(!isNull(m_offset));
76 } 65 }
77 66
78 namespace {
79 InterpolationRange setRange(CSSPropertyID id)
80 {
81 switch (id) {
82 case CSSPropertyOrphans:
83 case CSSPropertyWebkitColumnCount:
84 case CSSPropertyWidows:
85 return RangeRoundGreaterThanOrEqualToOne;
86 case CSSPropertyWebkitColumnRuleWidth:
87 case CSSPropertyZIndex:
88 return RangeRound;
89 case CSSPropertyFloodOpacity:
90 case CSSPropertyStopOpacity:
91 case CSSPropertyStrokeOpacity:
92 case CSSPropertyShapeImageThreshold:
93 return RangeZeroToOne;
94 case CSSPropertyFillOpacity:
95 case CSSPropertyOpacity:
96 return RangeOpacityFIXME;
97 case CSSPropertyStrokeMiterlimit:
98 return RangeGreaterThanOrEqualToOne;
99 case CSSPropertyZoom:
100 return RangePositive;
101 default:
102 ASSERT_NOT_REACHED();
103 return RangeAll;
104 }
105 }
106
107 } // namespace
108
109 // FIXME: Refactor this into a generic piece that lives in InterpolationEffect, and a template parameter specific converter. 67 // FIXME: Refactor this into a generic piece that lives in InterpolationEffect, and a template parameter specific converter.
110 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe:: maybeCreateInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyfr ame& end, Element* element) const 68 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe:: maybeCreateInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyfr ame& end, Element* element) const
111 { 69 {
112 CSSValue* fromCSSValue = m_value.get(); 70 CSSValue* fromCSSValue = m_value.get();
113 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end).value(); 71 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end).value();
114 InterpolationRange range = RangeAll;
115 bool fallBackToLegacy = false;
116 72
117 // FIXME: Remove this flag once we can rely on legacy's behaviour being corr ect. 73 return InterpolationFactory::maybeCreateInterpolation(property, fromCSSValue , toCSSValue, m_composite, toStringPropertySpecificKeyframe(end).m_composite, &m _animatableValueCache, &toStringPropertySpecificKeyframe(end).m_animatableValueC ache, element);
118 bool forceDefaultInterpolation = false;
119
120 if (!CSSPropertyMetadata::isAnimatableProperty(property)) {
121 if (fromCSSValue == toCSSValue)
122 return ConstantStyleInterpolation::create(fromCSSValue, property);
123
124 return nullptr;
125 }
126
127 // FIXME: Generate this giant switch statement.
128 switch (property) {
129 case CSSPropertyLineHeight:
130 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue))
131 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative);
132
133 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl eInterpolation::canCreateFrom(*toCSSValue))
134 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, CSSPrimitiveValue::CSS_NUMBER, RangeNonNegative);
135
136 break;
137 case CSSPropertyBorderBottomWidth:
138 case CSSPropertyBorderLeftWidth:
139 case CSSPropertyBorderRightWidth:
140 case CSSPropertyBorderTopWidth:
141 case CSSPropertyFlexBasis:
142 case CSSPropertyFontSize:
143 case CSSPropertyHeight:
144 case CSSPropertyMaxHeight:
145 case CSSPropertyMaxWidth:
146 case CSSPropertyMinHeight:
147 case CSSPropertyMinWidth:
148 case CSSPropertyMotionPosition:
149 case CSSPropertyOutlineWidth:
150 case CSSPropertyPaddingBottom:
151 case CSSPropertyPaddingLeft:
152 case CSSPropertyPaddingRight:
153 case CSSPropertyPaddingTop:
154 case CSSPropertyPerspective:
155 case CSSPropertyShapeMargin:
156 case CSSPropertyWebkitBorderHorizontalSpacing:
157 case CSSPropertyWebkitBorderVerticalSpacing:
158 case CSSPropertyWebkitColumnGap:
159 case CSSPropertyWebkitColumnWidth:
160 case CSSPropertyWidth:
161 range = RangeNonNegative;
162 // Fall through
163 case CSSPropertyBottom:
164 case CSSPropertyLeft:
165 case CSSPropertyLetterSpacing:
166 case CSSPropertyMarginBottom:
167 case CSSPropertyMarginLeft:
168 case CSSPropertyMarginRight:
169 case CSSPropertyMarginTop:
170 case CSSPropertyOutlineOffset:
171 case CSSPropertyRight:
172 case CSSPropertyTop:
173 case CSSPropertyVerticalAlign:
174 case CSSPropertyWordSpacing:
175 case CSSPropertyWebkitColumnRuleWidth:
176 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue))
177 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range);
178
179 // FIXME: Handle keywords e.g. 'none'.
180 if (property == CSSPropertyPerspective)
181 fallBackToLegacy = true;
182 // FIXME: Handle keywords e.g. 'smaller', 'larger'.
183 if (property == CSSPropertyFontSize)
184 fallBackToLegacy = true;
185
186 // FIXME: Handle keywords e.g. 'normal'
187 if (property == CSSPropertyLetterSpacing)
188 fallBackToLegacy = true;
189
190 // FIXME: Handle keywords e.g. 'thick'
191 if (property == CSSPropertyOutlineWidth || CSSPropertyWebkitColumnRuleWi dth)
192 fallBackToLegacy = true;
193 break;
194 case CSSPropertyOrphans:
195 case CSSPropertyWidows:
196 case CSSPropertyZIndex:
197 case CSSPropertyWebkitColumnCount:
198 case CSSPropertyShapeImageThreshold:
199 case CSSPropertyFillOpacity:
200 case CSSPropertyFloodOpacity:
201 case CSSPropertyOpacity:
202 case CSSPropertyStopOpacity:
203 case CSSPropertyStrokeOpacity:
204 case CSSPropertyStrokeMiterlimit:
205 case CSSPropertyZoom:
206 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl eInterpolation::canCreateFrom(*toCSSValue)) {
207 if (property == CSSPropertyOpacity)
208 StringKeyframe::PropertySpecificKeyframe::ensureAnimatableValueC aches(property, end, element, *fromCSSValue, *toCSSValue);
209 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, toCSSPrimitiveValue(fromCSSValue)->primitiveType(), setRange(property) );
210 }
211 break;
212
213 case CSSPropertyMotionRotation: {
214 RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolati on::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property);
215 if (interpolation)
216 return interpolation.release();
217 break;
218 }
219 case CSSPropertyVisibility:
220 if (VisibilityStyleInterpolation::canCreateFrom(*fromCSSValue) && Visibi lityStyleInterpolation::canCreateFrom(*toCSSValue) && (VisibilityStyleInterpolat ion::isVisible(*fromCSSValue) || VisibilityStyleInterpolation::isVisible(*toCSSV alue)))
221 return VisibilityStyleInterpolation::create(*fromCSSValue, *toCSSVal ue, property);
222
223 break;
224
225 case CSSPropertyBackgroundColor:
226 case CSSPropertyBorderBottomColor:
227 case CSSPropertyBorderLeftColor:
228 case CSSPropertyBorderRightColor:
229 case CSSPropertyBorderTopColor:
230 case CSSPropertyColor:
231 case CSSPropertyFloodColor:
232 case CSSPropertyLightingColor:
233 case CSSPropertyOutlineColor:
234 case CSSPropertyStopColor:
235 case CSSPropertyTextDecorationColor:
236 case CSSPropertyWebkitColumnRuleColor:
237 case CSSPropertyWebkitTextStrokeColor:
238 {
239 RefPtrWillBeRawPtr<Interpolation> interpolation = ColorStyleInterpol ation::maybeCreateFromColor(*fromCSSValue, *toCSSValue, property);
240 if (interpolation)
241 return interpolation.release();
242
243 // Current color should use LegacyStyleInterpolation
244 if (ColorStyleInterpolation::shouldUseLegacyStyleInterpolation(*from CSSValue, *toCSSValue))
245 fallBackToLegacy = true;
246
247 break;
248 }
249
250 case CSSPropertyBorderImageSource:
251 case CSSPropertyListStyleImage:
252 case CSSPropertyWebkitMaskBoxImageSource:
253 if (ImageStyleInterpolation::canCreateFrom(*fromCSSValue) && ImageStyleI nterpolation::canCreateFrom(*toCSSValue))
254 return ImageStyleInterpolation::create(*fromCSSValue, *toCSSValue, p roperty);
255
256 // FIXME: Handle gradients.
257 fallBackToLegacy = true;
258 break;
259 case CSSPropertyBorderBottomLeftRadius:
260 case CSSPropertyBorderBottomRightRadius:
261 case CSSPropertyBorderTopLeftRadius:
262 case CSSPropertyBorderTopRightRadius:
263 range = RangeNonNegative;
264 // Fall through
265 case CSSPropertyObjectPosition:
266 if (LengthPairStyleInterpolation::canCreateFrom(*fromCSSValue) && Length PairStyleInterpolation::canCreateFrom(*toCSSValue))
267 return LengthPairStyleInterpolation::create(*fromCSSValue, *toCSSVal ue, property, range);
268 break;
269
270 case CSSPropertyPerspectiveOrigin:
271 case CSSPropertyTransformOrigin: {
272 RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation <LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, prop erty, range);
273 if (interpolation)
274 return interpolation.release();
275 break;
276 }
277
278 case CSSPropertyBoxShadow:
279 case CSSPropertyTextShadow:
280 case CSSPropertyWebkitBoxShadow: {
281 RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation <ShadowStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, prop erty);
282 if (interpolation)
283 return interpolation.release();
284
285 // FIXME: AnimatableShadow incorrectly animates between inset and non-in set values so it will never indicate it needs default interpolation
286 if (ShadowStyleInterpolation::usesDefaultStyleInterpolation(*fromCSSValu e, *toCSSValue)) {
287 forceDefaultInterpolation = true;
288 break;
289 }
290
291 // FIXME: Handle interpolation from/to none, unspecified color values
292 fallBackToLegacy = true;
293
294 break;
295
296 }
297
298 case CSSPropertyClip:
299 case CSSPropertyBorderImageSlice:
300 case CSSPropertyWebkitMaskBoxImageSlice: {
301 RefPtrWillBeRawPtr<Interpolation> interpolation = LengthBoxStyleInterpol ation::maybeCreateFrom(fromCSSValue, toCSSValue, property);
302 if (interpolation)
303 return interpolation.release();
304 break;
305 }
306
307 case CSSPropertyStrokeWidth:
308 range = RangeNonNegative;
309 // Fall through
310 case CSSPropertyBaselineShift:
311 case CSSPropertyStrokeDashoffset: {
312 RefPtrWillBeRawPtr<Interpolation> interpolation = SVGLengthStyleInterpol ation::maybeCreate(*fromCSSValue, *toCSSValue, property, range);
313 if (interpolation)
314 return interpolation.release();
315
316 break;
317 }
318
319 default:
320 // Fall back to LegacyStyleInterpolation.
321 fallBackToLegacy = true;
322 break;
323 }
324
325 if (fromCSSValue == toCSSValue)
326 return ConstantStyleInterpolation::create(fromCSSValue, property);
327
328 if (forceDefaultInterpolation)
329 return nullptr;
330
331 if (fromCSSValue->isUnsetValue() || fromCSSValue->isInheritedValue() || from CSSValue->isInitialValue()
332 || toCSSValue->isUnsetValue() || toCSSValue->isInheritedValue() || toCSS Value->isInitialValue())
333 fallBackToLegacy = true;
334
335 if (fallBackToLegacy) {
336 if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve( *fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleRe solve(*toCSSValue)) {
337 // FIXME: Handle these cases outside of DeferredLegacyStyleInterpola tion.
338 return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSV alue, property);
339 }
340
341 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here.
342 // FIXME: Remove this cache
343 ASSERT(element);
344 if (!m_animatableValueCache)
345 m_animatableValueCache = StyleResolver::createAnimatableValueSnapsho t(*element, property, *fromCSSValue);
346
347 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatable ValueSnapshot(*element, property, *toCSSValue);
348 toStringPropertySpecificKeyframe(end).m_animatableValueCache = to;
349
350 return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to .release(), property);
351 }
352
353 ASSERT(AnimatableValue::usesDefaultInterpolation(
354 StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCS SValue).get(),
355 StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSV alue).get()));
356
357 return nullptr;
358
359 }
360 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here.
361 // FIXME: Remove this cache
362 void StringKeyframe::PropertySpecificKeyframe::ensureAnimatableValueCaches(CSSPr opertyID property, Keyframe::PropertySpecificKeyframe& end, Element* element, CS SValue& fromCSSValue, CSSValue& toCSSValue) const
363 {
364 ASSERT(element);
365 if (!m_animatableValueCache)
366 m_animatableValueCache = StyleResolver::createAnimatableValueSnapshot(*e lement, property, fromCSSValue);
367 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValu eSnapshot(*element, property, toCSSValue);
368 toStringPropertySpecificKeyframe(end).m_animatableValueCache = to;
369 } 74 }
370 75
371 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> e asing) const 76 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> e asing) const
372 { 77 {
373 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, An imationEffect::CompositeAdd)); 78 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, An imationEffect::CompositeAdd));
374 } 79 }
375 80
376 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::cloneWithOffset(double offset) const 81 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::cloneWithOffset(double offset) const
377 { 82 {
378 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe( offset, m_easing, m_value.get()); 83 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe( offset, m_easing, m_value.get());
379 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_anima tableValueCache; 84 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_anima tableValueCache;
380 return adoptPtrWillBeNoop(theClone); 85 return adoptPtrWillBeNoop(theClone);
381 } 86 }
382 87
383 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor) 88 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
384 { 89 {
385 visitor->trace(m_value); 90 visitor->trace(m_value);
386 visitor->trace(m_animatableValueCache); 91 visitor->trace(m_animatableValueCache);
387 Keyframe::PropertySpecificKeyframe::trace(visitor); 92 Keyframe::PropertySpecificKeyframe::trace(visitor);
388 } 93 }
389 94
390 } 95 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698