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

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

Issue 225183014: Handle direction control in compositor Animations (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: same patch with a manual test added Created 6 years, 3 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/animation/CompositorAnimations.h ('k') | Source/core/animation/CompositorAnimationsImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698