 Chromium Code Reviews
 Chromium Code Reviews Issue 142523005:
  Web Animations: Define easing for each keyframe  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink@master
    
  
    Issue 142523005:
  Web Animations: Define easing for each keyframe  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink@master| OLD | NEW | 
|---|---|
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 , m_after(const_cast<AnimationEffect::CompositableValue*>(after)) | 80 , m_after(const_cast<AnimationEffect::CompositableValue*>(after)) | 
| 81 , m_fraction(fraction) | 81 , m_fraction(fraction) | 
| 82 , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after ->dependsOnUnderlyingValue()) | 82 , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after ->dependsOnUnderlyingValue()) | 
| 83 { } | 83 { } | 
| 84 RefPtr<AnimationEffect::CompositableValue> m_before; | 84 RefPtr<AnimationEffect::CompositableValue> m_before; | 
| 85 RefPtr<AnimationEffect::CompositableValue> m_after; | 85 RefPtr<AnimationEffect::CompositableValue> m_after; | 
| 86 double m_fraction; | 86 double m_fraction; | 
| 87 bool m_dependsOnUnderlyingValue; | 87 bool m_dependsOnUnderlyingValue; | 
| 88 }; | 88 }; | 
| 89 | 89 | 
| 90 const double s_accuracy = 0.0000001; | |
| 
Timothy Loh
2014/02/07 04:49:09
Maybe something like accuracyForKeyframeEasing?
 
Eric Willigers
2014/02/07 05:19:27
Done.
 | |
| 91 | |
| 90 } // namespace | 92 } // namespace | 
| 91 | 93 | 
| 92 | 94 | 
| 93 namespace WebCore { | 95 namespace WebCore { | 
| 94 | 96 | 
| 95 Keyframe::Keyframe() | 97 Keyframe::Keyframe() | 
| 96 : m_offset(nullValue()) | 98 : m_offset(nullValue()) | 
| 97 , m_composite(AnimationEffect::CompositeReplace) | 99 , m_composite(AnimationEffect::CompositeReplace) | 
| 98 { } | 100 { } | 
| 99 | 101 | 
| 100 Keyframe::Keyframe(const Keyframe& copyFrom) | 102 Keyframe::Keyframe(const Keyframe& copyFrom) | 
| 101 : m_offset(copyFrom.m_offset) | 103 : m_offset(copyFrom.m_offset) | 
| 102 , m_composite(copyFrom.m_composite) | 104 , m_composite(copyFrom.m_composite) | 
| 105 , m_easing(copyFrom.m_easing) | |
| 103 { | 106 { | 
| 104 for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin (); iter != copyFrom.m_propertyValues.end(); ++iter) | 107 for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin (); iter != copyFrom.m_propertyValues.end(); ++iter) | 
| 105 setPropertyValue(iter->key, iter->value.get()); | 108 setPropertyValue(iter->key, iter->value.get()); | 
| 106 } | 109 } | 
| 107 | 110 | 
| 108 void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* v alue) | 111 void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* v alue) | 
| 109 { | 112 { | 
| 110 m_propertyValues.add(property, const_cast<AnimatableValue*>(value)); | 113 m_propertyValues.add(property, const_cast<AnimatableValue*>(value)); | 
| 111 } | 114 } | 
| 112 | 115 | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 PropertySet keyframeProperties = keyframe->properties(); | 249 PropertySet keyframeProperties = keyframe->properties(); | 
| 247 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) { | 250 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) { | 
| 248 CSSPropertyID property = *propertyIter; | 251 CSSPropertyID property = *propertyIter; | 
| 249 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty); | 252 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty); | 
| 250 if (groupIter == m_keyframeGroups->end()) { | 253 if (groupIter == m_keyframeGroups->end()) { | 
| 251 KeyframeGroupMap::AddResult result = m_keyframeGroups->add(prope rty, adoptPtr(new PropertySpecificKeyframeGroup)); | 254 KeyframeGroupMap::AddResult result = m_keyframeGroups->add(prope rty, adoptPtr(new PropertySpecificKeyframeGroup)); | 
| 252 ASSERT(result.isNewEntry); | 255 ASSERT(result.isNewEntry); | 
| 253 groupIter = result.iterator; | 256 groupIter = result.iterator; | 
| 254 } | 257 } | 
| 255 groupIter->value->appendKeyframe(adoptPtr( | 258 groupIter->value->appendKeyframe(adoptPtr( | 
| 256 new PropertySpecificKeyframe(keyframe->offset(), keyframe->prope rtyValue(property), keyframe->composite()))); | 259 new PropertySpecificKeyframe(keyframe->offset(), keyframe->easin g(), keyframe->propertyValue(property), keyframe->composite()))); | 
| 257 } | 260 } | 
| 258 } | 261 } | 
| 259 | 262 | 
| 260 // Add synthetic keyframes. | 263 // Add synthetic keyframes. | 
| 261 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { | 264 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { | 
| 262 iter->value->addSyntheticKeyframeIfRequired(); | 265 iter->value->addSyntheticKeyframeIfRequired(); | 
| 263 iter->value->removeRedundantKeyframes(); | 266 iter->value->removeRedundantKeyframes(); | 
| 264 } | 267 } | 
| 265 } | 268 } | 
| 266 | 269 | 
| 267 | 270 | 
| 268 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, const AnimatableValue* value, CompositeOperation composite) | 271 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite) | 
| 269 : m_offset(offset) | 272 : m_offset(offset) | 
| 273 , m_easing(easing) | |
| 270 , m_value(composite == AnimationEffect::CompositeReplace ? | 274 , m_value(composite == AnimationEffect::CompositeReplace ? | 
| 271 AnimatableValue::takeConstRef(value) : | 275 AnimatableValue::takeConstRef(value) : | 
| 272 static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create (value))) | 276 static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create (value))) | 
| 273 { | 277 { | 
| 274 } | 278 } | 
| 275 | 279 | 
| 276 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<CompositableValue> value) | 280 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, PassRefPtr<CompositableValue> value) | 
| 277 : m_offset(offset) | 281 : m_offset(offset) | 
| 282 , m_easing(easing) | |
| 278 , m_value(value) | 283 , m_value(value) | 
| 279 { | 284 { | 
| 280 ASSERT(!isNull(m_offset)); | 285 ASSERT(!isNull(m_offset)); | 
| 281 } | 286 } | 
| 282 | 287 | 
| 283 PassOwnPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEffectModel::P ropertySpecificKeyframe::cloneWithOffset(double offset) const | 288 PassOwnPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEffectModel::P ropertySpecificKeyframe::cloneWithOffset(double offset) const | 
| 284 { | 289 { | 
| 285 return adoptPtr(new PropertySpecificKeyframe(offset, PassRefPtr<Compositable Value>(m_value))); | 290 return adoptPtr(new PropertySpecificKeyframe(offset, m_easing, PassRefPtr<Co mpositableValue>(m_value))); | 
| 286 } | 291 } | 
| 287 | 292 | 
| 288 | 293 | 
| 289 void KeyframeEffectModel::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnP tr<PropertySpecificKeyframe> keyframe) | 294 void KeyframeEffectModel::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnP tr<PropertySpecificKeyframe> keyframe) | 
| 290 { | 295 { | 
| 291 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset()); | 296 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset()); | 
| 292 m_keyframes.append(keyframe); | 297 m_keyframes.append(keyframe); | 
| 293 } | 298 } | 
| 294 | 299 | 
| 295 void KeyframeEffectModel::PropertySpecificKeyframeGroup::removeRedundantKeyframe s() | 300 void KeyframeEffectModel::PropertySpecificKeyframeGroup::removeRedundantKeyframe s() | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 321 allOffsetsEqual = false; | 326 allOffsetsEqual = false; | 
| 322 break; | 327 break; | 
| 323 } | 328 } | 
| 324 } | 329 } | 
| 325 if (!allOffsetsEqual) | 330 if (!allOffsetsEqual) | 
| 326 return; | 331 return; | 
| 327 | 332 | 
| 328 if (!offset) | 333 if (!offset) | 
| 329 appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0)); | 334 appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0)); | 
| 330 else | 335 else | 
| 331 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, Animata bleValue::neutralValue(), CompositeAdd))); | 336 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, 0, Anim atableValue::neutralValue(), CompositeAdd))); | 
| 332 } | 337 } | 
| 333 | 338 | 
| 334 PassRefPtr<AnimationEffect::CompositableValue> KeyframeEffectModel::PropertySpec ificKeyframeGroup::sample(int iteration, double offset) const | 339 PassRefPtr<AnimationEffect::CompositableValue> KeyframeEffectModel::PropertySpec ificKeyframeGroup::sample(int iteration, double offset) const | 
| 335 { | 340 { | 
| 336 // FIXME: Implement accumulation. | 341 // FIXME: Implement accumulation. | 
| 337 ASSERT_UNUSED(iteration, iteration >= 0); | 342 ASSERT_UNUSED(iteration, iteration >= 0); | 
| 338 ASSERT(!isNull(offset)); | 343 ASSERT(!isNull(offset)); | 
| 339 | 344 | 
| 340 // Bail if offset is null, as this can lead to buffer overflow below. | 345 // Bail if offset is null, as this can lead to buffer overflow below. | 
| 341 if (isNull(offset)) | 346 if (isNull(offset)) | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 369 ++after; | 374 ++after; | 
| 370 before = after - 1; | 375 before = after - 1; | 
| 371 ASSERT((*before)->offset() <= offset); | 376 ASSERT((*before)->offset() <= offset); | 
| 372 ASSERT((*after)->offset() > offset); | 377 ASSERT((*after)->offset() > offset); | 
| 373 } | 378 } | 
| 374 | 379 | 
| 375 if ((*before)->offset() == offset) | 380 if ((*before)->offset() == offset) | 
| 376 return const_cast<CompositableValue*>((*before)->value()); | 381 return const_cast<CompositableValue*>((*before)->value()); | 
| 377 if ((*after)->offset() == offset) | 382 if ((*after)->offset() == offset) | 
| 378 return const_cast<CompositableValue*>((*after)->value()); | 383 return const_cast<CompositableValue*>((*after)->value()); | 
| 379 return BlendedCompositableValue::create((*before)->value(), (*after)->value( ), | 384 | 
| 380 (offset - (*before)->offset()) / ((*after)->offset() - (*before)->offset ())); | 385 double fraction = (offset - (*before)->offset()) / ((*after)->offset() - (*b efore)->offset()); | 
| 386 const TimingFunction* timingFunction = (*before)->easing(); | |
| 387 if (timingFunction) | |
| 
Timothy Loh
2014/02/07 04:49:09
if (const TimingFunction* ...) here is a bit clean
 
Eric Willigers
2014/02/07 05:19:27
Done.
 | |
| 388 fraction = timingFunction->evaluate(fraction, s_accuracy); | |
| 389 return BlendedCompositableValue::create((*before)->value(), (*after)->value( ), fraction); | |
| 381 } | 390 } | 
| 382 | 391 | 
| 383 } // namespace | 392 } // namespace | 
| OLD | NEW |