bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime, const IntSize& boxSize) { ASSERT(valueList.property() == AnimatedPropertyWebkitTransform); TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)", keyframesName.latin1().data(), beginTime); KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform); for (unsigned int i = 0; i < valueList.size(); i++) { TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i); PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction())); TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(), originalValue->value(), timingFunction); operationsList->insert(value); } RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation, operationsList, beginTime); if (keyframesName.isEmpty()) anim->setName(propertyIdToString(valueList.property())); else anim->setName(keyframesName); m_contentLayer->addAnimation(anim.release()); needsNotifyClient(); return true; }
// Tests that the default timing function is indeed ease. TEST(WebFloatAnimationCurveTest, DefaultTimingFunction) { scoped_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve); curve->add(CompositorFloatKeyframe(0, 0)); curve->add(CompositorFloatKeyframe(1, 1), CompositorAnimationCurve::TimingFunctionTypeLinear); scoped_ptr<cc::TimingFunction> timingFunction( cc::EaseTimingFunction::Create()); for (int i = 0; i <= 4; ++i) { const double time = i * 0.25; EXPECT_FLOAT_EQ(timingFunction->GetValue(time), curve->getValue(time)); } }
// Tests that the default timing function is indeed ease. TEST(WebFloatAnimationCurveTest, DefaultTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); curve->addKeyframe(CompositorFloatKeyframe( 0, 0, *CubicBezierTimingFunction::preset( CubicBezierTimingFunction::EaseType::EASE))); curve->addKeyframe( CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset( CubicBezierTimingFunction::EaseType::EASE)); for (int i = 0; i <= 4; ++i) { const double time = i * 0.25; EXPECT_FLOAT_EQ(timingFunction->GetValue(time), curve->getValue(time)); } }
// Tests that an ease in timing function works as expected. TEST(WebFloatAnimationCurveTest, CustomBezierTimingFunction) { scoped_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve); double x1 = 0.3; double y1 = 0.2; double x2 = 0.8; double y2 = 0.7; curve->add(CompositorFloatKeyframe(0, 0), x1, y1, x2, y2); curve->add(CompositorFloatKeyframe(1, 1), CompositorAnimationCurve::TimingFunctionTypeLinear); scoped_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)); for (int i = 0; i <= 4; ++i) { const double time = i * 0.25; EXPECT_FLOAT_EQ(timingFunction->GetValue(time), curve->getValue(time)); } }
// Tests that an ease in timing function works as expected. TEST(WebFloatAnimationCurveTest, CustomBezierTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); double x1 = 0.3; double y1 = 0.2; double x2 = 0.8; double y2 = 0.7; RefPtr<CubicBezierTimingFunction> cubic = CubicBezierTimingFunction::create(x1, y1, x2, y2); curve->addKeyframe(CompositorFloatKeyframe(0, 0, *cubic)); curve->addKeyframe( CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)); for (int i = 0; i <= 4; ++i) { const double time = i * 0.25; EXPECT_FLOAT_EQ(timingFunction->GetValue(time), curve->getValue(time)); } }
bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime) { bool isKeyframe = valueList.size() > 2; TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)", isKeyframe, keyframesName.latin1().data(), beginTime); switch (valueList.property()) { case AnimatedPropertyInvalid: break; case AnimatedPropertyWebkitTransform: break; case AnimatedPropertyBackgroundColor: break; case AnimatedPropertyOpacity: { MLOG("ANIMATEDPROPERTYOPACITY"); KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity); for (unsigned int i = 0; i < valueList.size(); i++) { FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i); PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction())); FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(), originalValue->value(), timingFunction); operationsList->insert(value); } RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation, operationsList, beginTime); if (keyframesName.isEmpty()) anim->setName(propertyIdToString(valueList.property())); else anim->setName(keyframesName); m_contentLayer->addAnimation(anim.release()); needsNotifyClient(); return true; } break; } return false; }
PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::clone() const { // We need to do a deep copy the m_value may contain ref pointers to TransformOperation objects. TransformOperations operations; for (size_t j = 0; j < m_value.size(); ++j) { TransformOperation::OperationType operationType = m_value.operations()[j]->getOperationType(); switch (operationType) { case TransformOperation::SCALE_X: case TransformOperation::SCALE_Y: case TransformOperation::SCALE_Z: case TransformOperation::SCALE_3D: case TransformOperation::SCALE: { ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(ScaleTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType)); break; } case TransformOperation::TRANSLATE_X: case TransformOperation::TRANSLATE_Y: case TransformOperation::TRANSLATE_Z: case TransformOperation::TRANSLATE_3D: case TransformOperation::TRANSLATE: { TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(TranslateTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType)); break; } case TransformOperation::ROTATE_X: case TransformOperation::ROTATE_Y: case TransformOperation::ROTATE_3D: case TransformOperation::ROTATE: { RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(RotateTransformOperation::create(transform->x(), transform->y(), transform->z(), transform->angle(), operationType)); break; } case TransformOperation::SKEW_X: case TransformOperation::SKEW_Y: case TransformOperation::SKEW: { SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(SkewTransformOperation::create(transform->angleX(), transform->angleY(), operationType)); break; } case TransformOperation::MATRIX: { MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(m_value.operations()[j].get()); TransformationMatrix m = transform->matrix(); operations.operations().append(MatrixTransformOperation::create(m.a(), m.b(), m.c(), m.d(), m.e(), m.f())); break; } case TransformOperation::MATRIX_3D: { Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(Matrix3DTransformOperation::create(transform->matrix())); break; } case TransformOperation::PERSPECTIVE: { PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(m_value.operations()[j].get()); operations.operations().append(PerspectiveTransformOperation::create(transform->perspective())); break; } case TransformOperation::IDENTITY: { operations.operations().append(IdentityTransformOperation::create()); break; } case TransformOperation::NONE: // Do nothing. break; } // switch } // for each operation return CCTransformKeyframe::create(time(), operations, timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr); }
PassOwnPtr<CCFloatKeyframe> CCFloatKeyframe::clone() const { return CCFloatKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr); }