TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) { Vector<Dictionary> jsKeyframes; v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); setV8ObjectPropertyAsString(keyframe1, "width", "100px"); setV8ObjectPropertyAsString(keyframe1, "offset", "0"); setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out"); setV8ObjectPropertyAsString(keyframe2, "width", "0px"); setV8ObjectPropertyAsString(keyframe2, "offset", "1"); setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)"); jsKeyframes.append(Dictionary(keyframe1, m_isolate)); jsKeyframes.append(Dictionary(keyframe2, m_isolate)); String value1; ASSERT_TRUE(jsKeyframes[0].get("width", value1)); ASSERT_EQ("100px", value1); String value2; ASSERT_TRUE(jsKeyframes[1].get("width", value2)); ASSERT_EQ("0px", value2); RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0, exceptionState); Element* target = animation->target(); EXPECT_EQ(*element.get(), *target); const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect())->getFrames(); EXPECT_EQ(0, keyframes[0]->offset()); EXPECT_EQ(1, keyframes[1]->offset()); const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->propertyValue(CSSPropertyWidth); const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->propertyValue(CSSPropertyWidth); ASSERT(keyframe1Width); ASSERT(keyframe2Width); EXPECT_EQ("100px", keyframe1Width->cssText()); EXPECT_EQ("0px", keyframe2Width->cssText()); EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), *keyframes[0]->easing()); EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *keyframes[1]->easing()); }
blink::Animation* InspectorAnimationAgent::animationClone( blink::Animation* animation) { const String id = String::number(animation->sequenceNumber()); if (!m_idToAnimationClone.get(id)) { KeyframeEffect* oldEffect = toKeyframeEffect(animation->effect()); ASSERT(oldEffect->model()->isKeyframeEffectModel()); KeyframeEffectModelBase* oldModel = toKeyframeEffectModelBase(oldEffect->model()); EffectModel* newModel = nullptr; // Clone EffectModel. // TODO(samli): Determine if this is an animations bug. if (oldModel->isStringKeyframeEffectModel()) { StringKeyframeEffectModel* oldStringKeyframeModel = toStringKeyframeEffectModel(oldModel); KeyframeVector oldKeyframes = oldStringKeyframeModel->getFrames(); StringKeyframeVector newKeyframes; for (auto& oldKeyframe : oldKeyframes) newKeyframes.append(toStringKeyframe(oldKeyframe.get())); newModel = StringKeyframeEffectModel::create(newKeyframes); } else if (oldModel->isAnimatableValueKeyframeEffectModel()) { AnimatableValueKeyframeEffectModel* oldAnimatableValueKeyframeModel = toAnimatableValueKeyframeEffectModel(oldModel); KeyframeVector oldKeyframes = oldAnimatableValueKeyframeModel->getFrames(); AnimatableValueKeyframeVector newKeyframes; for (auto& oldKeyframe : oldKeyframes) newKeyframes.append(toAnimatableValueKeyframe(oldKeyframe.get())); newModel = AnimatableValueKeyframeEffectModel::create(newKeyframes); } KeyframeEffect* newEffect = KeyframeEffect::create( oldEffect->target(), newModel, oldEffect->specifiedTiming()); m_isCloning = true; blink::Animation* clone = blink::Animation::create(newEffect, animation->timeline()); m_isCloning = false; m_idToAnimationClone.set(id, clone); m_idToAnimation.set(String::number(clone->sequenceNumber()), clone); clone->play(); clone->setStartTime(animation->startTime()); animation->setEffectSuppressed(true); } return m_idToAnimationClone.get(id); }
static PassRefPtr<TypeBuilder::Animation::KeyframesRule> buildObjectForAnimationKeyframes(const KeyframeEffect* effect) { if (!effect || !effect->model() || !effect->model()->isKeyframeEffectModel()) return nullptr; const KeyframeEffectModelBase* model = toKeyframeEffectModelBase(effect->model()); Vector<RefPtr<Keyframe>> normalizedKeyframes = KeyframeEffectModelBase::normalizedKeyframesForInspector(model->getFrames()); RefPtr<TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle> > keyframes = TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle>::create(); for (const auto& keyframe : normalizedKeyframes) { // Ignore CSS Transitions if (!keyframe.get()->isStringKeyframe()) continue; const StringKeyframe* stringKeyframe = toStringKeyframe(keyframe.get()); keyframes->addItem(buildObjectForStringKeyframe(stringKeyframe)); } RefPtr<TypeBuilder::Animation::KeyframesRule> keyframesObject = TypeBuilder::Animation::KeyframesRule::create() .setKeyframes(keyframes); return keyframesObject.release(); }
static std::unique_ptr<protocol::Animation::KeyframesRule> buildObjectForAnimationKeyframes(const KeyframeEffect* effect) { if (!effect || !effect->model() || !effect->model()->isKeyframeEffectModel()) return nullptr; const KeyframeEffectModelBase* model = toKeyframeEffectModelBase(effect->model()); Vector<RefPtr<Keyframe>> normalizedKeyframes = KeyframeEffectModelBase::normalizedKeyframesForInspector( model->getFrames()); std::unique_ptr<protocol::Array<protocol::Animation::KeyframeStyle>> keyframes = protocol::Array<protocol::Animation::KeyframeStyle>::create(); for (const auto& keyframe : normalizedKeyframes) { // Ignore CSS Transitions if (!keyframe.get()->isStringKeyframe()) continue; const StringKeyframe* stringKeyframe = toStringKeyframe(keyframe.get()); keyframes->addItem(buildObjectForStringKeyframe(stringKeyframe)); } return protocol::Animation::KeyframesRule::create() .setKeyframes(std::move(keyframes)) .build(); }