| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #include "public/platform/WebTransformAnimationCurve.h" | 52 #include "public/platform/WebTransformAnimationCurve.h" |
| 53 #include "public/platform/WebTransformKeyframe.h" | 53 #include "public/platform/WebTransformKeyframe.h" |
| 54 | 54 |
| 55 #include <algorithm> | 55 #include <algorithm> |
| 56 #include <cmath> | 56 #include <cmath> |
| 57 | 57 |
| 58 namespace blink { | 58 namespace blink { |
| 59 | 59 |
| 60 namespace { | 60 namespace { |
| 61 | 61 |
| 62 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp
ertyID id, double scale, bool reverse, PropertySpecificKeyframeVector& values) | 62 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp
ertyID id, double scale, PropertySpecificKeyframeVector& values) |
| 63 { | 63 { |
| 64 ASSERT(values.isEmpty()); | 64 ASSERT(values.isEmpty()); |
| 65 const PropertySpecificKeyframeVector& group = effect->getPropertySpecificKey
frames(id); | 65 const PropertySpecificKeyframeVector& group = effect->getPropertySpecificKey
frames(id); |
| 66 | 66 |
| 67 if (reverse) { | 67 for (size_t i = 0; i < group.size(); ++i) { |
| 68 for (size_t i = group.size(); i--;) { | 68 double offset = group[i]->offset() * scale; |
| 69 double offset = (1 - group[i]->offset()) * scale; | 69 values.append(group[i]->cloneWithOffset(offset)); |
| 70 values.append(group[i]->cloneWithOffset(offset)); | |
| 71 } | |
| 72 } else { | |
| 73 for (size_t i = 0; i < group.size(); ++i) { | |
| 74 double offset = group[i]->offset() * scale; | |
| 75 values.append(group[i]->cloneWithOffset(offset)); | |
| 76 } | |
| 77 } | 70 } |
| 78 } | 71 } |
| 79 | 72 |
| 80 } | 73 } |
| 81 | 74 |
| 82 // ----------------------------------------------------------------------- | |
| 83 // TimingFunctionReverser methods | |
| 84 // ----------------------------------------------------------------------- | |
| 85 | |
| 86 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
onst LinearTimingFunction& timefunc) | |
| 87 { | |
| 88 return const_cast<LinearTimingFunction*>(&timefunc); | |
| 89 } | |
| 90 | |
| 91 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
onst CubicBezierTimingFunction& timefunc) | |
| 92 { | |
| 93 switch (timefunc.subType()) { | |
| 94 case CubicBezierTimingFunction::EaseIn: | |
| 95 return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease
Out); | |
| 96 case CubicBezierTimingFunction::EaseOut: | |
| 97 return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease
In); | |
| 98 case CubicBezierTimingFunction::EaseInOut: | |
| 99 return const_cast<CubicBezierTimingFunction*>(&timefunc); | |
| 100 case CubicBezierTimingFunction::Ease: // Ease is not symmetrical | |
| 101 case CubicBezierTimingFunction::Custom: | |
| 102 return CubicBezierTimingFunction::create(1 - timefunc.x2(), 1 - timefunc
.y2(), 1 - timefunc.x1(), 1 - timefunc.y1()); | |
| 103 default: | |
| 104 ASSERT_NOT_REACHED(); | |
| 105 return PassRefPtr<TimingFunction>(); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
onst TimingFunction& timefunc) | |
| 110 { | |
| 111 switch (timefunc.type()) { | |
| 112 case TimingFunction::LinearFunction: { | |
| 113 const LinearTimingFunction& linear = toLinearTimingFunction(timefunc); | |
| 114 return reverse(linear); | |
| 115 } | |
| 116 case TimingFunction::CubicBezierFunction: { | |
| 117 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(tim
efunc); | |
| 118 return reverse(cubic); | |
| 119 } | |
| 120 | |
| 121 // Steps function can not be reversed. | |
| 122 case TimingFunction::StepsFunction: | |
| 123 default: | |
| 124 ASSERT_NOT_REACHED(); | |
| 125 return PassRefPtr<TimingFunction>(); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation
Effect& effect, double minValue, double maxValue) const | 75 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation
Effect& effect, double minValue, double maxValue) const |
| 130 { | 76 { |
| 131 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 77 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 132 | 78 |
| 133 PropertySet properties = keyframeEffect.properties(); | 79 PropertySet properties = keyframeEffect.properties(); |
| 134 | 80 |
| 135 if (properties.isEmpty()) | 81 if (properties.isEmpty()) |
| 136 return true; | 82 return true; |
| 137 | 83 |
| 138 minValue = std::min(minValue, 0.0); | 84 minValue = std::min(minValue, 0.0); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 // All directions are supported. | 279 // All directions are supported. |
| 334 | 280 |
| 335 // Now attempt an actual conversion | 281 // Now attempt an actual conversion |
| 336 out.scaledDuration = timing.iterationDuration; | 282 out.scaledDuration = timing.iterationDuration; |
| 337 ASSERT(out.scaledDuration > 0); | 283 ASSERT(out.scaledDuration > 0); |
| 338 | 284 |
| 339 double scaledStartDelay = timing.startDelay; | 285 double scaledStartDelay = timing.startDelay; |
| 340 if (scaledStartDelay > 0 && scaledStartDelay > out.scaledDuration * timing.i
terationCount) | 286 if (scaledStartDelay > 0 && scaledStartDelay > out.scaledDuration * timing.i
terationCount) |
| 341 return false; | 287 return false; |
| 342 | 288 |
| 343 out.reverse = (timing.direction == Timing::PlaybackDirectionReverse | 289 out.direction = timing.direction; |
| 344 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
| 345 out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate | |
| 346 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
| 347 | 290 |
| 348 if (!std::isfinite(timing.iterationCount)) { | 291 if (!std::isfinite(timing.iterationCount)) { |
| 349 out.adjustedIterationCount = -1; | 292 out.adjustedIterationCount = -1; |
| 350 } else { | 293 } else { |
| 351 out.adjustedIterationCount = timing.iterationCount; | 294 out.adjustedIterationCount = timing.iterationCount; |
| 352 ASSERT(out.adjustedIterationCount > 0); | 295 ASSERT(out.adjustedIterationCount > 0); |
| 353 } | 296 } |
| 354 | 297 |
| 355 // Compositor's time offset is positive for seeking into the animation. | 298 // Compositor's time offset is positive for seeking into the animation. |
| 356 out.scaledTimeOffset = -scaledStartDelay + timeOffset; | 299 out.scaledTimeOffset = -scaledStartDelay + timeOffset; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 | 351 |
| 409 case TimingFunction::StepsFunction: | 352 case TimingFunction::StepsFunction: |
| 410 default: | 353 default: |
| 411 ASSERT_NOT_REACHED(); | 354 ASSERT_NOT_REACHED(); |
| 412 return; | 355 return; |
| 413 } | 356 } |
| 414 } | 357 } |
| 415 | 358 |
| 416 } // namespace anoymous | 359 } // namespace anoymous |
| 417 | 360 |
| 418 void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve&
curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing, bo
ol reverse) | 361 void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve&
curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing) |
| 419 { | 362 { |
| 420 for (size_t i = 0; i < keyframes.size(); i++) { | 363 for (size_t i = 0; i < keyframes.size(); i++) { |
| 421 RefPtr<TimingFunction> reversedTimingFunction; | |
| 422 const TimingFunction* keyframeTimingFunction = 0; | 364 const TimingFunction* keyframeTimingFunction = 0; |
| 423 if (i < keyframes.size() - 1) { // Ignore timing function of last frame. | 365 if (i < keyframes.size() - 1) { // Ignore timing function of last frame. |
| 424 if (keyframes.size() == 2 && keyframes[0]->easing().type() == Timing
Function::LinearFunction) { | 366 if (keyframes.size() == 2 && keyframes[0]->easing().type() == Timing
Function::LinearFunction) { |
| 425 if (reverse) { | 367 keyframeTimingFunction = timing.timingFunction.get(); |
| 426 reversedTimingFunction = CompositorAnimationsTimingFunctionR
everser::reverse(*timing.timingFunction.get()); | |
| 427 keyframeTimingFunction = reversedTimingFunction.get(); | |
| 428 } else { | |
| 429 keyframeTimingFunction = timing.timingFunction.get(); | |
| 430 } | |
| 431 } else { | 368 } else { |
| 432 if (reverse) { | 369 keyframeTimingFunction = &keyframes[i]->easing(); |
| 433 reversedTimingFunction = CompositorAnimationsTimingFunctionR
everser::reverse(keyframes[i + 1]->easing()); | |
| 434 keyframeTimingFunction = reversedTimingFunction.get(); | |
| 435 } else { | |
| 436 keyframeTimingFunction = &keyframes[i]->easing(); | |
| 437 } | |
| 438 } | 370 } |
| 439 } | 371 } |
| 440 | 372 |
| 441 // FIXME: This relies on StringKeyframes being eagerly evaluated, which
will | 373 // FIXME: This relies on StringKeyframes being eagerly evaluated, which
will |
| 442 // not happen eventually. Instead we should extract the CSSValue here | 374 // not happen eventually. Instead we should extract the CSSValue here |
| 443 // and convert using another set of toAnimatableXXXOperations functions. | 375 // and convert using another set of toAnimatableXXXOperations functions. |
| 444 const AnimatableValue* value = keyframes[i]->getAnimatableValue().get(); | 376 const AnimatableValue* value = keyframes[i]->getAnimatableValue().get(); |
| 445 | 377 |
| 446 switch (curve.type()) { | 378 switch (curve.type()) { |
| 447 case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { | 379 case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 ASSERT(animations.isEmpty()); | 411 ASSERT(animations.isEmpty()); |
| 480 CompositorTiming compositorTiming; | 412 CompositorTiming compositorTiming; |
| 481 bool timingValid = convertTimingForCompositor(timing, timeOffset, compositor
Timing); | 413 bool timingValid = convertTimingForCompositor(timing, timeOffset, compositor
Timing); |
| 482 ASSERT_UNUSED(timingValid, timingValid); | 414 ASSERT_UNUSED(timingValid, timingValid); |
| 483 | 415 |
| 484 PropertySet properties = effect.properties(); | 416 PropertySet properties = effect.properties(); |
| 485 ASSERT(!properties.isEmpty()); | 417 ASSERT(!properties.isEmpty()); |
| 486 for (PropertySet::iterator it = properties.begin(); it != properties.end();
++it) { | 418 for (PropertySet::iterator it = properties.begin(); it != properties.end();
++it) { |
| 487 | 419 |
| 488 PropertySpecificKeyframeVector values; | 420 PropertySpecificKeyframeVector values; |
| 489 getKeyframeValuesForProperty(&effect, *it, compositorTiming.scaledDurati
on, compositorTiming.reverse, values); | 421 getKeyframeValuesForProperty(&effect, *it, compositorTiming.scaledDurati
on, values); |
| 490 | 422 |
| 491 WebCompositorAnimation::TargetProperty targetProperty; | 423 WebCompositorAnimation::TargetProperty targetProperty; |
| 492 OwnPtr<WebCompositorAnimationCurve> curve; | 424 OwnPtr<WebCompositorAnimationCurve> curve; |
| 493 switch (*it) { | 425 switch (*it) { |
| 494 case CSSPropertyOpacity: { | 426 case CSSPropertyOpacity: { |
| 495 targetProperty = WebCompositorAnimation::TargetPropertyOpacity; | 427 targetProperty = WebCompositorAnimation::TargetPropertyOpacity; |
| 496 | 428 |
| 497 WebFloatAnimationCurve* floatCurve = Platform::current()->compositor
Support()->createFloatAnimationCurve(); | 429 WebFloatAnimationCurve* floatCurve = Platform::current()->compositor
Support()->createFloatAnimationCurve(); |
| 498 addKeyframesToCurve(*floatCurve, values, timing, compositorTiming.re
verse); | 430 addKeyframesToCurve(*floatCurve, values, timing); |
| 499 curve = adoptPtr(floatCurve); | 431 curve = adoptPtr(floatCurve); |
| 500 break; | 432 break; |
| 501 } | 433 } |
| 502 case CSSPropertyWebkitFilter: { | 434 case CSSPropertyWebkitFilter: { |
| 503 targetProperty = WebCompositorAnimation::TargetPropertyFilter; | 435 targetProperty = WebCompositorAnimation::TargetPropertyFilter; |
| 504 WebFilterAnimationCurve* filterCurve = Platform::current()->composit
orSupport()->createFilterAnimationCurve(); | 436 WebFilterAnimationCurve* filterCurve = Platform::current()->composit
orSupport()->createFilterAnimationCurve(); |
| 505 addKeyframesToCurve(*filterCurve, values, timing, compositorTiming.r
everse); | 437 addKeyframesToCurve(*filterCurve, values, timing); |
| 506 curve = adoptPtr(filterCurve); | 438 curve = adoptPtr(filterCurve); |
| 507 break; | 439 break; |
| 508 } | 440 } |
| 509 case CSSPropertyTransform: { | 441 case CSSPropertyTransform: { |
| 510 targetProperty = WebCompositorAnimation::TargetPropertyTransform; | 442 targetProperty = WebCompositorAnimation::TargetPropertyTransform; |
| 511 WebTransformAnimationCurve* transformCurve = Platform::current()->co
mpositorSupport()->createTransformAnimationCurve(); | 443 WebTransformAnimationCurve* transformCurve = Platform::current()->co
mpositorSupport()->createTransformAnimationCurve(); |
| 512 addKeyframesToCurve(*transformCurve, values, timing, compositorTimin
g.reverse); | 444 addKeyframesToCurve(*transformCurve, values, timing); |
| 513 curve = adoptPtr(transformCurve); | 445 curve = adoptPtr(transformCurve); |
| 514 break; | 446 break; |
| 515 } | 447 } |
| 516 default: | 448 default: |
| 517 ASSERT_NOT_REACHED(); | 449 ASSERT_NOT_REACHED(); |
| 518 continue; | 450 continue; |
| 519 } | 451 } |
| 520 ASSERT(curve.get()); | 452 ASSERT(curve.get()); |
| 521 | 453 |
| 522 OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()-
>compositorSupport()->createAnimation(*curve, targetProperty)); | 454 OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()-
>compositorSupport()->createAnimation(*curve, targetProperty)); |
| 523 | 455 |
| 524 if (!std::isnan(startTime)) | 456 if (!std::isnan(startTime)) |
| 525 animation->setStartTime(startTime); | 457 animation->setStartTime(startTime); |
| 526 | 458 |
| 527 animation->setIterations(compositorTiming.adjustedIterationCount); | 459 animation->setIterations(compositorTiming.adjustedIterationCount); |
| 528 animation->setTimeOffset(compositorTiming.scaledTimeOffset); | 460 animation->setTimeOffset(compositorTiming.scaledTimeOffset); |
| 529 animation->setAlternatesDirection(compositorTiming.alternate); | 461 |
| 462 switch (compositorTiming.direction) { |
| 463 case Timing::PlaybackDirectionNormal: |
| 464 animation->setDirection(blink::WebCompositorAnimation::DirectionNorm
al); |
| 465 break; |
| 466 case Timing::PlaybackDirectionReverse: |
| 467 animation->setDirection(blink::WebCompositorAnimation::DirectionReve
rse); |
| 468 break; |
| 469 case Timing::PlaybackDirectionAlternate: |
| 470 animation->setDirection(blink::WebCompositorAnimation::DirectionAlte
rnate); |
| 471 break; |
| 472 case Timing::PlaybackDirectionAlternateReverse: |
| 473 animation->setDirection(blink::WebCompositorAnimation::DirectionAlte
rnateReverse); |
| 474 break; |
| 475 default: |
| 476 ASSERT_NOT_REACHED(); |
| 477 } |
| 530 | 478 |
| 531 animations.append(animation.release()); | 479 animations.append(animation.release()); |
| 532 } | 480 } |
| 533 ASSERT(!animations.isEmpty()); | 481 ASSERT(!animations.isEmpty()); |
| 534 } | 482 } |
| 535 | 483 |
| 536 } // namespace blink | 484 } // namespace blink |
| OLD | NEW |