bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize) { bool canBlend = !lastValue; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (!canBlend) { WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize); canBlend = lastOperations.canBlendWith(operations); } if (canBlend) { curve->add(WebTransformKeyframe(keyTime, operations), timingFunctionType); return true; } return false; }
bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize) { bool canBlend = !lastValue; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (!canBlend) { WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize); canBlend = lastOperations.canBlendWith(operations); } if (canBlend) { curve->add(WebTransformKeyframe(keyTime, operations), x1, y1, x2, y2); return true; } return false; }
void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, const TimingFunction& timingFunction) { for (size_t i = 0; i < keyframes.size(); i++) { const TimingFunction* keyframeTimingFunction = 0; if (i + 1 < keyframes.size()) { // Last keyframe has no timing function switch (timingFunction.type()) { case TimingFunction::LinearFunction: case TimingFunction::CubicBezierFunction: keyframeTimingFunction = &timingFunction; break; case TimingFunction::ChainedFunction: { const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction); // ChainedTimingFunction criteria was checked in isCandidate, // assert it is valid. ASSERT(keyframes.size() == chained.m_segments.size() + 1); keyframeTimingFunction = chained.m_segments[i].m_timingFunction.get(); break; } case TimingFunction::StepsFunction: default: ASSERT_NOT_REACHED(); } } ASSERT(!keyframes[i]->value()->dependsOnUnderlyingValue()); RefPtr<AnimatableValue> value = keyframes[i]->value()->compositeOnto(0); switch (curve.type()) { case blink::WebAnimationCurve::AnimationCurveTypeFilter: { OwnPtr<blink::WebFilterOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createFilterOperations()); bool converted = toWebFilterOperations(toAnimatableFilterOperations(value.get())->operations(), ops.get()); ASSERT_UNUSED(converted, converted); blink::WebFilterKeyframe filterKeyframe(keyframes[i]->offset(), ops.release()); blink::WebFilterAnimationCurve* filterCurve = static_cast<blink::WebFilterAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*filterCurve, filterKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeFloat: { blink::WebFloatKeyframe floatKeyframe(keyframes[i]->offset(), toAnimatableDouble(value.get())->toDouble()); blink::WebFloatAnimationCurve* floatCurve = static_cast<blink::WebFloatAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeTransform: { OwnPtr<blink::WebTransformOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createTransformOperations()); toWebTransformOperations(toAnimatableTransform(value.get())->transformOperations(), FloatSize(), ops.get()); blink::WebTransformKeyframe transformKeyframe(keyframes[i]->offset(), ops.release()); blink::WebTransformAnimationCurve* transformCurve = static_cast<blink::WebTransformAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, keyframeTimingFunction); break; } default: ASSERT_NOT_REACHED(); } } }
bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize) { if (causesRotationOfAtLeast180Degrees(value, lastValue)) return false; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (operations.apply().isInvertible()) { curve->add(WebTransformKeyframe(keyTime, operations), x1, y1, x2, y2); return true; } return false; }
bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize) { if (causesRotationOfAtLeast180Degrees(value, lastValue)) return false; WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize); if (operations.apply().isInvertible()) { curve->add(WebTransformKeyframe(keyTime, operations), timingFunctionType); return true; } return false; }
TEST(AnimationTranslationUtilTest, transformsWork) { TransformOperations ops; WebTransformOperationsMock outOps; EXPECT_CALL(outOps, appendTranslate(2, 0, 0)); EXPECT_CALL(outOps, appendRotate(0.1, 0.2, 0.3, 200000.4)); EXPECT_CALL(outOps, appendScale(50.2, 100, -4)); ops.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(0, Fixed), TransformOperation::TranslateX)); ops.operations().append(RotateTransformOperation::create(0.1, 0.2, 0.3, 200000.4, TransformOperation::Rotate3D)); ops.operations().append(ScaleTransformOperation::create(50.2, 100, -4, TransformOperation::Scale3D)); toWebTransformOperations(ops, &outOps); }
void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing) { auto* lastKeyframe = keyframes.last().get(); for (const auto& keyframe : keyframes) { const TimingFunction* keyframeTimingFunction = 0; if (keyframe != lastKeyframe) { // Ignore timing function of last frame. keyframeTimingFunction = &keyframe->easing(); } // FIXME: This relies on StringKeyframes being eagerly evaluated, which will // not happen eventually. Instead we should extract the CSSValue here // and convert using another set of toAnimatableXXXOperations functions. const AnimatableValue* value = keyframe->getAnimatableValue().get(); switch (curve.type()) { case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { OwnPtr<WebFilterOperations> ops = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); toWebFilterOperations(toAnimatableFilterOperations(value)->operations(), ops.get()); WebFilterKeyframe filterKeyframe(keyframe->offset(), ops.release()); WebFilterAnimationCurve* filterCurve = static_cast<WebFilterAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*filterCurve, filterKeyframe, keyframeTimingFunction); break; } case WebCompositorAnimationCurve::AnimationCurveTypeFloat: { WebFloatKeyframe floatKeyframe(keyframe->offset(), toAnimatableDouble(value)->toDouble()); WebFloatAnimationCurve* floatCurve = static_cast<WebFloatAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction); break; } case WebCompositorAnimationCurve::AnimationCurveTypeTransform: { OwnPtr<WebTransformOperations> ops = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations()); toWebTransformOperations(toAnimatableTransform(value)->transformOperations(), ops.get()); WebTransformKeyframe transformKeyframe(keyframe->offset(), ops.release()); WebTransformAnimationCurve* transformCurve = static_cast<WebTransformAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, keyframeTimingFunction); break; } default: ASSERT_NOT_REACHED(); } } }