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

Side by Side Diff: Source/core/animation/InterpolationFactory.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 2015 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/InterpolationFactory.h"
7 7
8 #include "core/animation/ColorStyleInterpolation.h" 8 #include "core/animation/ColorStyleInterpolation.h"
9 #include "core/animation/ConstantStyleInterpolation.h" 9 #include "core/animation/ConstantStyleInterpolation.h"
10 #include "core/animation/DeferredLegacyStyleInterpolation.h" 10 #include "core/animation/DeferredLegacyStyleInterpolation.h"
11 #include "core/animation/DoubleStyleInterpolation.h" 11 #include "core/animation/DoubleStyleInterpolation.h"
12 #include "core/animation/ImageStyleInterpolation.h" 12 #include "core/animation/ImageStyleInterpolation.h"
13 #include "core/animation/LegacyStyleInterpolation.h" 13 #include "core/animation/LegacyStyleInterpolation.h"
14 #include "core/animation/LengthBoxStyleInterpolation.h" 14 #include "core/animation/LengthBoxStyleInterpolation.h"
15 #include "core/animation/LengthPairStyleInterpolation.h" 15 #include "core/animation/LengthPairStyleInterpolation.h"
16 #include "core/animation/LengthStyleInterpolation.h" 16 #include "core/animation/LengthStyleInterpolation.h"
17 #include "core/animation/ListStyleInterpolation.h" 17 #include "core/animation/ListStyleInterpolation.h"
18 #include "core/animation/SVGLengthStyleInterpolation.h" 18 #include "core/animation/SVGLengthStyleInterpolation.h"
19 #include "core/animation/ShadowStyleInterpolation.h" 19 #include "core/animation/ShadowStyleInterpolation.h"
20 #include "core/animation/VisibilityStyleInterpolation.h" 20 #include "core/animation/VisibilityStyleInterpolation.h"
21 #include "core/animation/css/CSSAnimations.h"
22 #include "core/css/CSSPropertyMetadata.h" 21 #include "core/css/CSSPropertyMetadata.h"
23 #include "core/css/resolver/StyleResolver.h" 22 #include "core/css/resolver/StyleResolver.h"
24 #include "core/layout/style/LayoutStyle.h"
25 23
26 namespace blink { 24 namespace blink {
27 25
28 StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom) 26 static InterpolationRange setRange(CSSPropertyID id)
29 : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
30 , m_propertySet(copyFrom.m_propertySet->mutableCopy())
31 {
32 }
33
34 void StringKeyframe::setPropertyValue(CSSPropertyID property, const String& valu e, StyleSheetContents* styleSheetContents)
35 {
36 ASSERT(property != CSSPropertyInvalid);
37 if (CSSAnimations::isAllowedAnimation(property))
38 m_propertySet->setProperty(property, value, false, styleSheetContents);
39 }
40
41 PropertySet StringKeyframe::properties() const
42 {
43 // This is not used in time-critical code, so we probably don't need to
44 // worry about caching this result.
45 PropertySet properties;
46 for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i)
47 properties.add(m_propertySet->propertyAt(i).id());
48 return properties;
49 }
50
51 PassRefPtrWillBeRawPtr<Keyframe> StringKeyframe::clone() const
52 {
53 return adoptRefWillBeNoop(new StringKeyframe(*this));
54 }
55 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::creat ePropertySpecificKeyframe(CSSPropertyID property) const
56 {
57 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset(), &easing(), propertyValue(property), composite()));
58 }
59
60 void StringKeyframe::trace(Visitor* visitor)
61 {
62 visitor->trace(m_propertySet);
63 Keyframe::trace(visitor);
64 }
65
66 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset , PassRefPtr<TimingFunction> easing, CSSValue* value, AnimationEffect::Composite Operation op)
67 : Keyframe::PropertySpecificKeyframe(offset, easing, op)
68 , m_value(value)
69 { }
70
71 StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset , PassRefPtr<TimingFunction> easing, CSSValue* value)
72 : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::Compos iteReplace)
73 , m_value(value)
74 {
75 ASSERT(!isNull(m_offset));
76 }
77
78 namespace {
79 InterpolationRange setRange(CSSPropertyID id)
80 { 27 {
81 switch (id) { 28 switch (id) {
82 case CSSPropertyOrphans: 29 case CSSPropertyOrphans:
83 case CSSPropertyWebkitColumnCount: 30 case CSSPropertyWebkitColumnCount:
84 case CSSPropertyWidows: 31 case CSSPropertyWidows:
85 return RangeRoundGreaterThanOrEqualToOne; 32 return RangeRoundGreaterThanOrEqualToOne;
86 case CSSPropertyWebkitColumnRuleWidth: 33 case CSSPropertyWebkitColumnRuleWidth:
87 case CSSPropertyZIndex: 34 case CSSPropertyZIndex:
88 return RangeRound; 35 return RangeRound;
89 case CSSPropertyFloodOpacity: 36 case CSSPropertyFloodOpacity:
90 case CSSPropertyStopOpacity: 37 case CSSPropertyStopOpacity:
91 case CSSPropertyStrokeOpacity: 38 case CSSPropertyStrokeOpacity:
92 case CSSPropertyShapeImageThreshold: 39 case CSSPropertyShapeImageThreshold:
93 return RangeZeroToOne; 40 return RangeZeroToOne;
94 case CSSPropertyFillOpacity: 41 case CSSPropertyFillOpacity:
95 case CSSPropertyOpacity: 42 case CSSPropertyOpacity:
96 return RangeOpacityFIXME; 43 return RangeOpacityFIXME;
97 case CSSPropertyStrokeMiterlimit: 44 case CSSPropertyStrokeMiterlimit:
98 return RangeGreaterThanOrEqualToOne; 45 return RangeGreaterThanOrEqualToOne;
99 case CSSPropertyZoom: 46 case CSSPropertyZoom:
100 return RangePositive; 47 return RangePositive;
101 default: 48 default:
102 ASSERT_NOT_REACHED(); 49 ASSERT_NOT_REACHED();
103 return RangeAll; 50 return RangeAll;
104 } 51 }
105 } 52 }
106 53
107 } // namespace 54 static void ensureAnimatableValueCaches(
55 CSSPropertyID property,
56 CSSValue& fromCSSValue,
57 CSSValue& toCSSValue,
58 RefPtrWillBeRawPtr<AnimatableValue>* fromAnimatableValueCache,
59 RefPtrWillBeRawPtr<AnimatableValue>* toAnimatableValueCache,
60 Element* element)
61 {
62 if (!*fromAnimatableValueCache)
63 *fromAnimatableValueCache = StyleResolver::createAnimatableValueSnapshot (*element, property, fromCSSValue);
108 64
109 // FIXME: Refactor this into a generic piece that lives in InterpolationEffect, and a template parameter specific converter. 65 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValu eSnapshot(*element, property, toCSSValue);
110 PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe:: maybeCreateInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyfr ame& end, Element* element) const 66 *toAnimatableValueCache = to;
67 }
68
69 // FIXME: Remove the use of AnimatableValues and Elements here.
70 PassRefPtrWillBeRawPtr<Interpolation> InterpolationFactory::maybeCreateInterpola tion(
71 CSSPropertyID property,
72 CSSValue* fromCSSValue,
73 CSSValue* toCSSValue,
74 AnimationEffect::CompositeOperation fromComposite,
75 AnimationEffect::CompositeOperation toComposite,
76 RefPtrWillBeRawPtr<AnimatableValue>* fromAnimatableValueCache,
77 RefPtrWillBeRawPtr<AnimatableValue>* toAnimatableValueCache,
78 Element* element)
111 { 79 {
112 CSSValue* fromCSSValue = m_value.get(); 80 ASSERT(fromCSSValue);
113 CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end).value(); 81 ASSERT(toCSSValue);
82
114 InterpolationRange range = RangeAll; 83 InterpolationRange range = RangeAll;
115 bool fallBackToLegacy = false; 84 bool fallBackToLegacy = false;
116 85
117 // FIXME: Remove this flag once we can rely on legacy's behaviour being corr ect. 86 // FIXME: Remove this flag once we can rely on legacy's behaviour being corr ect.
118 bool forceDefaultInterpolation = false; 87 bool forceDefaultInterpolation = false;
119 88
120 if (!CSSPropertyMetadata::isAnimatableProperty(property)) { 89 if (!CSSPropertyMetadata::isAnimatableProperty(property)) {
121 if (fromCSSValue == toCSSValue) 90 if (fromCSSValue == toCSSValue)
122 return ConstantStyleInterpolation::create(fromCSSValue, property); 91 return ConstantStyleInterpolation::create(fromCSSValue, property, fr omComposite, toComposite);
123 92
124 return nullptr; 93 return nullptr;
125 } 94 }
126 95
127 // FIXME: Generate this giant switch statement. 96 // FIXME: Generate this giant switch statement.
128 switch (property) { 97 switch (property) {
129 case CSSPropertyLineHeight: 98 case CSSPropertyLineHeight:
130 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue)) 99 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue))
131 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative); 100 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative);
132 101
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 case CSSPropertyMarginLeft: 136 case CSSPropertyMarginLeft:
168 case CSSPropertyMarginRight: 137 case CSSPropertyMarginRight:
169 case CSSPropertyMarginTop: 138 case CSSPropertyMarginTop:
170 case CSSPropertyOutlineOffset: 139 case CSSPropertyOutlineOffset:
171 case CSSPropertyRight: 140 case CSSPropertyRight:
172 case CSSPropertyTop: 141 case CSSPropertyTop:
173 case CSSPropertyVerticalAlign: 142 case CSSPropertyVerticalAlign:
174 case CSSPropertyWordSpacing: 143 case CSSPropertyWordSpacing:
175 case CSSPropertyWebkitColumnRuleWidth: 144 case CSSPropertyWebkitColumnRuleWidth:
176 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue)) 145 if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyl eInterpolation::canCreateFrom(*toCSSValue))
177 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range); 146 return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range, fromComposite, toComposite);
178 147
179 // FIXME: Handle keywords e.g. 'none'. 148 // FIXME: Handle keywords e.g. 'none'.
180 if (property == CSSPropertyPerspective) 149 if (property == CSSPropertyPerspective)
181 fallBackToLegacy = true; 150 fallBackToLegacy = true;
182 // FIXME: Handle keywords e.g. 'smaller', 'larger'. 151 // FIXME: Handle keywords e.g. 'smaller', 'larger'.
183 if (property == CSSPropertyFontSize) 152 if (property == CSSPropertyFontSize)
184 fallBackToLegacy = true; 153 fallBackToLegacy = true;
185 154
186 // FIXME: Handle keywords e.g. 'normal' 155 // FIXME: Handle keywords e.g. 'normal'
187 if (property == CSSPropertyLetterSpacing) 156 if (property == CSSPropertyLetterSpacing)
188 fallBackToLegacy = true; 157 fallBackToLegacy = true;
189 158
190 // FIXME: Handle keywords e.g. 'thick' 159 // FIXME: Handle keywords e.g. 'thick'
191 if (property == CSSPropertyOutlineWidth || CSSPropertyWebkitColumnRuleWi dth) 160 if (property == CSSPropertyOutlineWidth || CSSPropertyWebkitColumnRuleWi dth)
192 fallBackToLegacy = true; 161 fallBackToLegacy = true;
193 break; 162 break;
194 case CSSPropertyOrphans: 163 case CSSPropertyOrphans:
195 case CSSPropertyWidows: 164 case CSSPropertyWidows:
196 case CSSPropertyZIndex: 165 case CSSPropertyZIndex:
197 case CSSPropertyWebkitColumnCount: 166 case CSSPropertyWebkitColumnCount:
198 case CSSPropertyShapeImageThreshold: 167 case CSSPropertyShapeImageThreshold:
199 case CSSPropertyFillOpacity: 168 case CSSPropertyFillOpacity:
200 case CSSPropertyFloodOpacity: 169 case CSSPropertyFloodOpacity:
201 case CSSPropertyOpacity: 170 case CSSPropertyOpacity:
202 case CSSPropertyStopOpacity: 171 case CSSPropertyStopOpacity:
203 case CSSPropertyStrokeOpacity: 172 case CSSPropertyStrokeOpacity:
204 case CSSPropertyStrokeMiterlimit: 173 case CSSPropertyStrokeMiterlimit:
205 case CSSPropertyZoom: 174 case CSSPropertyZoom:
206 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl eInterpolation::canCreateFrom(*toCSSValue)) { 175 if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyl eInterpolation::canCreateFrom(*toCSSValue)) {
207 if (property == CSSPropertyOpacity) 176 if (property == CSSPropertyOpacity) {
208 StringKeyframe::PropertySpecificKeyframe::ensureAnimatableValueC aches(property, end, element, *fromCSSValue, *toCSSValue); 177 // FIXME: Remove the use of AnimatableValues and Elements here.
178 ASSERT(element);
179 ASSERT(fromAnimatableValueCache);
180 ASSERT(toAnimatableValueCache);
181
182 ensureAnimatableValueCaches(property, *fromCSSValue, *toCSSValue , fromAnimatableValueCache, toAnimatableValueCache, element);
183 }
209 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, toCSSPrimitiveValue(fromCSSValue)->primitiveType(), setRange(property) ); 184 return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, toCSSPrimitiveValue(fromCSSValue)->primitiveType(), setRange(property) );
210 } 185 }
211 break; 186 break;
212 187
213 case CSSPropertyMotionRotation: { 188 case CSSPropertyMotionRotation: {
214 RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolati on::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property); 189 RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolati on::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property);
215 if (interpolation) 190 if (interpolation)
216 return interpolation.release(); 191 return interpolation.release();
217 break; 192 break;
218 } 193 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 break; 291 break;
317 } 292 }
318 293
319 default: 294 default:
320 // Fall back to LegacyStyleInterpolation. 295 // Fall back to LegacyStyleInterpolation.
321 fallBackToLegacy = true; 296 fallBackToLegacy = true;
322 break; 297 break;
323 } 298 }
324 299
325 if (fromCSSValue == toCSSValue) 300 if (fromCSSValue == toCSSValue)
326 return ConstantStyleInterpolation::create(fromCSSValue, property); 301 return ConstantStyleInterpolation::create(fromCSSValue, property, fromCo mposite, toComposite);
327 302
328 if (forceDefaultInterpolation) 303 if (forceDefaultInterpolation)
329 return nullptr; 304 return nullptr;
330 305
331 if (fromCSSValue->isUnsetValue() || fromCSSValue->isInheritedValue() || from CSSValue->isInitialValue() 306 if (fromCSSValue->isUnsetValue() || fromCSSValue->isInheritedValue() || from CSSValue->isInitialValue()
332 || toCSSValue->isUnsetValue() || toCSSValue->isInheritedValue() || toCSS Value->isInitialValue()) 307 || toCSSValue->isUnsetValue() || toCSSValue->isInheritedValue() || toCSS Value->isInitialValue())
333 fallBackToLegacy = true; 308 fallBackToLegacy = true;
334 309
310 ASSERT(element);
335 if (fallBackToLegacy) { 311 if (fallBackToLegacy) {
312 ASSERT(fromAnimatableValueCache);
313 ASSERT(toAnimatableValueCache);
314
336 if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve( *fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleRe solve(*toCSSValue)) { 315 if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve( *fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleRe solve(*toCSSValue)) {
337 // FIXME: Handle these cases outside of DeferredLegacyStyleInterpola tion. 316 // FIXME: Handle these cases outside of DeferredLegacyStyleInterpola tion.
338 return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSV alue, property); 317 return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSV alue, property);
339 } 318 }
340 319
341 // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here. 320 // FIXME: Remove the use of AnimatableValues and Elements here.
342 // FIXME: Remove this cache 321 ensureAnimatableValueCaches(property, *fromCSSValue, *toCSSValue, fromAn imatableValueCache, toAnimatableValueCache, element);
343 ASSERT(element);
344 if (!m_animatableValueCache)
345 m_animatableValueCache = StyleResolver::createAnimatableValueSnapsho t(*element, property, *fromCSSValue);
346 322
347 RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatable ValueSnapshot(*element, property, *toCSSValue); 323 return LegacyStyleInterpolation::create((*fromAnimatableValueCache).get( ), (*toAnimatableValueCache).get(), property);
348 toStringPropertySpecificKeyframe(end).m_animatableValueCache = to;
349
350 return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to .release(), property);
351 } 324 }
352 325
353 ASSERT(AnimatableValue::usesDefaultInterpolation( 326 ASSERT(AnimatableValue::usesDefaultInterpolation(
354 StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCS SValue).get(), 327 StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCS SValue).get(),
355 StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSV alue).get())); 328 StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSV alue).get()));
356 329
357 return nullptr; 330 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 } 331 }
370 332
371 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> e asing) const 333 PassRefPtrWillBeRawPtr<Interpolation> InterpolationFactory::createConstantInterp olation(
334 CSSPropertyID property,
335 CSSValue* value,
336 AnimationEffect::CompositeOperation fromComposite,
337 AnimationEffect::CompositeOperation toComposite)
372 { 338 {
373 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, An imationEffect::CompositeAdd)); 339 RefPtrWillBeRawPtr<Interpolation> interpolation = InterpolationFactory::mayb eCreateInterpolation(
374 } 340 property,
341 value,
342 value,
343 fromComposite,
344 toComposite);
375 345
376 PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::Prope rtySpecificKeyframe::cloneWithOffset(double offset) const 346 ASSERT(interpolation);
377 {
378 Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe( offset, m_easing, m_value.get());
379 toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_anima tableValueCache;
380 return adoptPtrWillBeNoop(theClone);
381 }
382 347
383 void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor) 348 return interpolation.release();
384 {
385 visitor->trace(m_value);
386 visitor->trace(m_animatableValueCache);
387 Keyframe::PropertySpecificKeyframe::trace(visitor);
388 } 349 }
389 350
390 } 351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698