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

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

Issue 203463009: Web Animations API: Fix Synthetic keyframes + partial keyframes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Return nullptr after exception + fixmes Created 6 years, 9 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 /* 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 PropertySet keyframeProperties = keyframe->properties(); 198 PropertySet keyframeProperties = keyframe->properties();
199 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) { 199 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) {
200 CSSPropertyID property = *propertyIter; 200 CSSPropertyID property = *propertyIter;
201 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty); 201 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty);
202 PropertySpecificKeyframeGroup* group; 202 PropertySpecificKeyframeGroup* group;
203 if (groupIter == m_keyframeGroups->end()) 203 if (groupIter == m_keyframeGroups->end())
204 group = m_keyframeGroups->add(property, adoptPtr(new PropertySpe cificKeyframeGroup)).storedValue->value.get(); 204 group = m_keyframeGroups->add(property, adoptPtr(new PropertySpe cificKeyframeGroup)).storedValue->value.get();
205 else 205 else
206 group = groupIter->value.get(); 206 group = groupIter->value.get();
207 207
208 ASSERT(keyframe->composite() == AnimationEffect::CompositeReplace);
208 group->appendKeyframe(adoptPtr( 209 group->appendKeyframe(adoptPtr(
209 new PropertySpecificKeyframe(keyframe->offset(), keyframe->easin g(), keyframe->propertyValue(property), keyframe->composite()))); 210 new PropertySpecificKeyframe(keyframe->offset(), keyframe->easin g(), keyframe->propertyValue(property), keyframe->composite())));
210 } 211 }
211 } 212 }
212 213
213 // Add synthetic keyframes. 214 // Add synthetic keyframes.
214 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { 215 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) {
215 iter->value->addSyntheticKeyframeIfRequired(); 216 iter->value->addSyntheticKeyframeIfRequired();
216 iter->value->removeRedundantKeyframes(); 217 iter->value->removeRedundantKeyframes();
217 } 218 }
218 } 219 }
219 220
220 void KeyframeEffectModel::ensureInterpolationEffect() const 221 void KeyframeEffectModel::ensureInterpolationEffect() const
221 { 222 {
222 if (m_interpolationEffect) 223 if (m_interpolationEffect)
223 return; 224 return;
224 m_interpolationEffect = InterpolationEffect::create(); 225 m_interpolationEffect = InterpolationEffect::create();
225 226
226 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) { 227 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
227 const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes (); 228 const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes ();
229 ASSERT(keyframes[0]->composite() == AnimationEffect::CompositeReplace);
228 const AnimatableValue* start; 230 const AnimatableValue* start;
229 const AnimatableValue* end = keyframes[0]->value(); 231 const AnimatableValue* end = keyframes[0]->value();
230 for (size_t i = 0; i < keyframes.size() - 1; i++) { 232 for (size_t i = 0; i < keyframes.size() - 1; i++) {
233 ASSERT(keyframes[i + 1]->composite() == AnimationEffect::CompositeRe place);
231 start = end; 234 start = end;
232 end = keyframes[i + 1]->value(); 235 end = keyframes[i + 1]->value();
233 double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limit s<double>::infinity()); 236 double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limit s<double>::infinity());
234 double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<dou ble>::infinity() : keyframes[i + 1]->offset(); 237 double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<dou ble>::infinity() : keyframes[i + 1]->offset();
235 if (applyTo == 1) 238 if (applyTo == 1)
236 applyTo = std::numeric_limits<double>::infinity(); 239 applyTo = std::numeric_limits<double>::infinity();
237 m_interpolationEffect->addInterpolation( 240 m_interpolationEffect->addInterpolation(
238 LegacyStyleInterpolation::create( 241 LegacyStyleInterpolation::create(
239 AnimatableValue::takeConstRef(start), 242 AnimatableValue::takeConstRef(start),
240 AnimatableValue::takeConstRef(end), iter->key), 243 AnimatableValue::takeConstRef(end), iter->key),
241 keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i + 1] ->offset(), applyFrom, applyTo); 244 keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i + 1] ->offset(), applyFrom, applyTo);
242 } 245 }
243 } 246 }
244 } 247 }
245 248
249 bool KeyframeEffectModel::isReplaceOnly()
250 {
251 ensureKeyframeGroups();
252 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) {
253 const PropertySpecificKeyframeVector& keyframeVector = iter->value->keyf rames();
254 for (size_t i = 0; i < keyframeVector.size(); ++i) {
255 if (keyframeVector[i]->composite() != AnimationEffect::CompositeRepl ace)
256 return false;
257 }
258 }
259 return true;
260 }
261
246 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite) 262 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite)
247 : m_offset(offset) 263 : m_offset(offset)
248 , m_easing(easing) 264 , m_easing(easing)
265 , m_composite(composite)
249 { 266 {
250 ASSERT(composite == AnimationEffect::CompositeReplace);
251 m_value = AnimatableValue::takeConstRef(value); 267 m_value = AnimatableValue::takeConstRef(value);
252 } 268 }
253 269
254 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, PassRefPtr<AnimatableValue> value) 270 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, PassRefPtr<AnimatableValue> value, Com positeOperation composite)
255 : m_offset(offset) 271 : m_offset(offset)
256 , m_easing(easing) 272 , m_easing(easing)
257 , m_value(value) 273 , m_value(value)
274 , m_composite(composite)
258 { 275 {
259 ASSERT(!isNull(m_offset)); 276 ASSERT(!isNull(m_offset));
260 } 277 }
261 278
262 PassOwnPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEffectModel::P ropertySpecificKeyframe::cloneWithOffset(double offset) const 279 PassOwnPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEffectModel::P ropertySpecificKeyframe::cloneWithOffset(double offset) const
263 { 280 {
264 return adoptPtr(new PropertySpecificKeyframe(offset, m_easing, m_value)); 281 return adoptPtr(new PropertySpecificKeyframe(offset, m_easing, m_value, m_co mposite));
265 } 282 }
266 283
267 284
268 void KeyframeEffectModel::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnP tr<PropertySpecificKeyframe> keyframe) 285 void KeyframeEffectModel::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnP tr<PropertySpecificKeyframe> keyframe)
269 { 286 {
270 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset()); 287 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset());
271 m_keyframes.append(keyframe); 288 m_keyframes.append(keyframe);
272 } 289 }
273 290
274 void KeyframeEffectModel::PropertySpecificKeyframeGroup::removeRedundantKeyframe s() 291 void KeyframeEffectModel::PropertySpecificKeyframeGroup::removeRedundantKeyframe s()
(...skipping 11 matching lines...) Expand all
286 bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.siz e() - 1) || m_keyframes[i + 1]->offset() == offset; 303 bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.siz e() - 1) || m_keyframes[i + 1]->offset() == offset;
287 if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor) 304 if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor)
288 m_keyframes.remove(i); 305 m_keyframes.remove(i);
289 } 306 }
290 ASSERT(m_keyframes.size() >= 2); 307 ASSERT(m_keyframes.size() >= 2);
291 } 308 }
292 309
293 void KeyframeEffectModel::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfR equired() 310 void KeyframeEffectModel::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfR equired()
294 { 311 {
295 ASSERT(!m_keyframes.isEmpty()); 312 ASSERT(!m_keyframes.isEmpty());
296 double offset = m_keyframes.first()->offset(); 313 if (m_keyframes.first()->offset() != 0.0)
297 bool allOffsetsEqual = true; 314 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0, nullptr, AnimatableValue::neutralValue(), CompositeAdd)));
298 for (PropertySpecificKeyframeVector::const_iterator iter = m_keyframes.begin () + 1; iter != m_keyframes.end(); ++iter) { 315 if (m_keyframes.last()->offset() != 1.0)
299 if ((*iter)->offset() != offset) { 316 appendKeyframe(adoptPtr(new PropertySpecificKeyframe(1, nullptr, Animata bleValue::neutralValue(), CompositeAdd)));
300 allOffsetsEqual = false;
301 break;
302 }
303 }
304 if (!allOffsetsEqual)
305 return;
306
307 if (!offset)
308 appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
309 else
310 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, nullptr , AnimatableValue::neutralValue(), CompositeAdd)));
311 } 317 }
312 318
313 void KeyframeEffectModel::trace(Visitor* visitor) 319 void KeyframeEffectModel::trace(Visitor* visitor)
314 { 320 {
315 visitor->trace(m_keyframes); 321 visitor->trace(m_keyframes);
316 } 322 }
317 323
318 } // namespace 324 } // namespace
OLDNEW
« no previous file with comments | « Source/core/animation/KeyframeEffectModel.h ('k') | Source/core/animation/KeyframeEffectModelTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698