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 |