void InspectorAnimationAgent::setPaused( ErrorString* errorString, std::unique_ptr<protocol::Array<String>> animationIds, bool paused) { for (size_t i = 0; i < animationIds->length(); ++i) { String animationId = animationIds->get(i); blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; blink::Animation* clone = animationClone(animation); if (!clone) { *errorString = "Failed to clone detached animation"; return; } if (paused && !clone->paused()) { // Ensure we restore a current time if the animation is limited. double currentTime = clone->timeline()->currentTime() - clone->startTime(); clone->pause(); clone->setCurrentTime(currentTime); } else if (!paused && clone->paused()) { clone->unpause(); } } }
void InspectorAnimationAgent::seekAnimations(ErrorString* errorString, const RefPtr<JSONArray>& animationIds, double currentTime) { for (const auto& id : *animationIds) { String animationId; if (!(id->asString(&animationId))) { *errorString = "Invalid argument type"; return; } Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; m_isCloning = true; Animation* clone = animationClone(animation); m_isCloning = false; clone->play(); clone->setCurrentTime(currentTime); } }
void InspectorAnimationAgent::seekAnimations( ErrorString* errorString, std::unique_ptr<protocol::Array<String>> animationIds, double currentTime) { for (size_t i = 0; i < animationIds->length(); ++i) { String animationId = animationIds->get(i); blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; blink::Animation* clone = animationClone(animation); if (!clone) { *errorString = "Failed to clone a detached animation."; return; } if (!clone->paused()) clone->play(); clone->setCurrentTime(currentTime); } }
void InspectorAnimationAgent::setTiming(ErrorString* errorString, const String& animationId, double duration, double delay) { blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; animation = animationClone(animation); NonThrowableExceptionState exceptionState; String type = m_idToAnimationType.get(animationId); if (type == AnimationType::CSSTransition) { KeyframeEffect* effect = toKeyframeEffect(animation->effect()); KeyframeEffectModelBase* model = toKeyframeEffectModelBase(effect->model()); const AnimatableValueKeyframeEffectModel* oldModel = toAnimatableValueKeyframeEffectModel(model); // Refer to CSSAnimations::calculateTransitionUpdateForProperty() for the // structure of transitions. const KeyframeVector& frames = oldModel->getFrames(); ASSERT(frames.size() == 3); KeyframeVector newFrames; for (int i = 0; i < 3; i++) newFrames.append(toAnimatableValueKeyframe(frames[i]->clone().get())); // Update delay, represented by the distance between the first two // keyframes. newFrames[1]->setOffset(delay / (delay + duration)); model->setFrames(newFrames); AnimationEffectTiming* timing = effect->timing(); UnrestrictedDoubleOrString unrestrictedDuration; unrestrictedDuration.setUnrestrictedDouble(duration + delay); timing->setDuration(unrestrictedDuration, exceptionState); } else { AnimationEffectTiming* timing = toAnimationEffectTiming(animation->effect()->timing()); UnrestrictedDoubleOrString unrestrictedDuration; unrestrictedDuration.setUnrestrictedDouble(duration); timing->setDuration(unrestrictedDuration, exceptionState); timing->setDelay(delay); } }