Ejemplo n.º 1
0
PassRefPtr<TypeBuilder::Animation::Animation> InspectorAnimationAgent::buildObjectForAnimation(Animation& animation)
{
    const Element* element = toKeyframeEffect(animation.effect())->target();
    CSSAnimations& cssAnimations = element->elementAnimations()->cssAnimations();
    RefPtr<TypeBuilder::Animation::KeyframesRule> keyframeRule = nullptr;
    AnimationType animationType;

    if (cssAnimations.isTransitionAnimationForInspector(animation)) {
        // CSS Transitions
        animationType = AnimationType::CSSTransition;
    } else {
        // Keyframe based animations
        keyframeRule = buildObjectForAnimationKeyframes(toKeyframeEffect(animation.effect()));
        animationType = cssAnimations.isAnimationForInspector(animation) ? AnimationType::CSSAnimation : AnimationType::WebAnimation;
    }

    String id = String::number(animation.sequenceNumber());
    m_idToAnimation.set(id, &animation);
    m_idToAnimationType.set(id, animationType);

    RefPtr<TypeBuilder::Animation::AnimationEffect> animationEffectObject = buildObjectForAnimationEffect(toKeyframeEffect(animation.effect()), animationType == AnimationType::CSSTransition);
    if (keyframeRule)
        animationEffectObject->setKeyframesRule(keyframeRule);

    RefPtr<TypeBuilder::Animation::Animation> animationObject = TypeBuilder::Animation::Animation::create()
        .setId(id)
        .setPausedState(animation.paused())
        .setPlayState(animation.playState())
        .setPlaybackRate(animation.playbackRate())
        .setStartTime(normalizedStartTime(animation))
        .setCurrentTime(animation.currentTime())
        .setSource(animationEffectObject.release())
        .setType(animationType);
    return animationObject.release();
}
Ejemplo n.º 2
0
void Animation::attachCompositedLayers()
{
    if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() || !m_compositorPlayer)
        return;

    ASSERT(m_content);
    ASSERT(m_content->isKeyframeEffect());

    if (toKeyframeEffect(m_content.get())->canAttachCompositedLayers())
        toKeyframeEffect(m_content.get())->attachCompositedLayers();
}
void ElementAnimations::updateAnimationFlags(ComputedStyle& style)
{
    for (const auto& entry : m_animations) {
        const Animation& animation = *entry.key;
        ASSERT(animation.effect());
        // FIXME: Needs to consider AnimationGroup once added.
        ASSERT(animation.effect()->isAnimation());
        const KeyframeEffect& effect = *toKeyframeEffect(animation.effect());
        if (effect.isCurrent()) {
            if (effect.affects(PropertyHandle(CSSPropertyOpacity)))
                style.setHasCurrentOpacityAnimation(true);
            if (effect.affects(PropertyHandle(CSSPropertyTransform))
                || effect.affects(PropertyHandle(CSSPropertyRotate))
                || effect.affects(PropertyHandle(CSSPropertyScale))
                || effect.affects(PropertyHandle(CSSPropertyTranslate)))
                style.setHasCurrentTransformAnimation(true);
            if (effect.affects(PropertyHandle(CSSPropertyWebkitFilter)))
                style.setHasCurrentFilterAnimation(true);
        }
    }

    if (style.hasCurrentOpacityAnimation())
        style.setIsRunningOpacityAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyOpacity));
    if (style.hasCurrentTransformAnimation())
        style.setIsRunningTransformAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyTransform));
    if (style.hasCurrentFilterAnimation())
        style.setIsRunningFilterAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyWebkitFilter));
}
Ejemplo n.º 4
0
bool Animation::hasActiveAnimationsOnCompositor()
{
    if (!m_content || !m_content->isKeyframeEffect())
        return false;

    return toKeyframeEffect(m_content.get())->hasActiveAnimationsOnCompositor();
}
Ejemplo n.º 5
0
void InspectorAnimationAgent::resolveAnimation(ErrorString* errorString, const String& animationId, RefPtr<TypeBuilder::Runtime::RemoteObject>& result)
{
    Animation* animation = assertAnimation(errorString, animationId);
    if (!animation)
        return;
    if (m_idToAnimationClone.get(animationId))
        animation = m_idToAnimationClone.get(animationId);
    const Element* element = toKeyframeEffect(animation->effect())->target();
    Document* document = element->ownerDocument();
    LocalFrame* frame = document ? document->frame() : nullptr;
    if (!frame) {
        *errorString = "Element not associated with a document.";
        return;
    }

    ScriptState* scriptState = ScriptState::forMainWorld(frame);
    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
    if (injectedScript.isEmpty())
        return;

    ScriptState::Scope scope(scriptState);
    v8::Isolate* isolate = scriptState->isolate();
    ScriptValue scriptValue = ScriptValue(scriptState, toV8(animation, scriptState->context()->Global(), isolate));
    injectedScript.releaseObjectGroup("animation");
    result = injectedScript.wrapObject(scriptValue, "animation");
}
Ejemplo n.º 6
0
void Animation::cancelAnimationOnCompositor()
{
    if (hasActiveAnimationsOnCompositor())
        toKeyframeEffect(m_content.get())->cancelAnimationOnCompositor();

    destroyCompositorPlayer();
}
Ejemplo n.º 7
0
void InspectorAnimationAgent::resolveAnimation(
    ErrorString* errorString,
    const String& animationId,
    std::unique_ptr<v8_inspector::protocol::Runtime::API::RemoteObject>*
        result) {
  blink::Animation* animation = assertAnimation(errorString, animationId);
  if (!animation)
    return;
  if (m_idToAnimationClone.get(animationId))
    animation = m_idToAnimationClone.get(animationId);
  const Element* element = toKeyframeEffect(animation->effect())->target();
  Document* document = element->ownerDocument();
  LocalFrame* frame = document ? document->frame() : nullptr;
  ScriptState* scriptState = frame ? ScriptState::forMainWorld(frame) : nullptr;
  if (!scriptState) {
    *errorString = "Element not associated with a document.";
    return;
  }

  ScriptState::Scope scope(scriptState);
  static const char kAnimationObjectGroup[] = "animation";
  m_v8Session->releaseObjectGroup(
      toV8InspectorStringView(kAnimationObjectGroup));
  *result = m_v8Session->wrapObject(
      scriptState->context(),
      toV8(animation, scriptState->context()->Global(), scriptState->isolate()),
      toV8InspectorStringView(kAnimationObjectGroup));
  if (!*result)
    *errorString = "Element not associated with a document.";
}
Ejemplo n.º 8
0
bool Animation::isCandidateForAnimationOnCompositor() const
{
    if (!canStartAnimationOnCompositor())
        return false;

    return toKeyframeEffect(m_content.get())->isCandidateForAnimationOnCompositor(m_playbackRate);
}
Ejemplo n.º 9
0
void InspectorAnimationAgent::setTiming(ErrorString* errorString, const String& animationId, double duration, double delay)
{
    Animation* animation = assertAnimation(errorString, animationId);
    if (!animation)
        return;

    AnimationType 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 = animation->effect()->timing();
        UnrestrictedDoubleOrString unrestrictedDuration;
        unrestrictedDuration.setUnrestrictedDouble(duration + delay);
        timing->setDuration(unrestrictedDuration);
    } else if (type == AnimationType::WebAnimation) {
        AnimationEffectTiming* timing = animation->effect()->timing();
        UnrestrictedDoubleOrString unrestrictedDuration;
        unrestrictedDuration.setUnrestrictedDouble(duration);
        timing->setDuration(unrestrictedDuration);
        timing->setDelay(delay);
    }
}
Ejemplo n.º 10
0
bool Animation::affects(const Element& element, CSSPropertyID property) const
{
    if (!m_content || !m_content->isKeyframeEffect())
        return false;

    const KeyframeEffect* effect = toKeyframeEffect(m_content.get());
    return (effect->target() == &element) && effect->affects(PropertyHandle(property));
}
Ejemplo n.º 11
0
std::unique_ptr<protocol::Animation::Animation>
InspectorAnimationAgent::buildObjectForAnimation(blink::Animation& animation) {
  const Element* element = toKeyframeEffect(animation.effect())->target();
  CSSAnimations& cssAnimations = element->elementAnimations()->cssAnimations();
  std::unique_ptr<protocol::Animation::KeyframesRule> keyframeRule = nullptr;
  String animationType;

  if (cssAnimations.isTransitionAnimationForInspector(animation)) {
    // CSS Transitions
    animationType = AnimationType::CSSTransition;
  } else {
    // Keyframe based animations
    keyframeRule =
        buildObjectForAnimationKeyframes(toKeyframeEffect(animation.effect()));
    animationType = cssAnimations.isAnimationForInspector(animation)
                        ? AnimationType::CSSAnimation
                        : AnimationType::WebAnimation;
  }

  String id = String::number(animation.sequenceNumber());
  m_idToAnimation.set(id, &animation);
  m_idToAnimationType.set(id, animationType);

  std::unique_ptr<protocol::Animation::AnimationEffect> animationEffectObject =
      buildObjectForAnimationEffect(
          toKeyframeEffect(animation.effect()),
          animationType == AnimationType::CSSTransition);
  animationEffectObject->setKeyframesRule(std::move(keyframeRule));

  std::unique_ptr<protocol::Animation::Animation> animationObject =
      protocol::Animation::Animation::create()
          .setId(id)
          .setName(animation.id())
          .setPausedState(animation.paused())
          .setPlayState(animation.playState())
          .setPlaybackRate(animation.playbackRate())
          .setStartTime(normalizedStartTime(animation))
          .setCurrentTime(animation.currentTime())
          .setSource(std::move(animationEffectObject))
          .setType(animationType)
          .build();
  if (animationType != AnimationType::WebAnimation)
    animationObject->setCssId(createCSSId(animation));
  return animationObject;
}
Ejemplo n.º 12
0
void Animation::pauseForTesting(double pauseTime)
{
    RELEASE_ASSERT(!paused());
    setCurrentTimeInternal(pauseTime, TimingUpdateOnDemand);
    if (hasActiveAnimationsOnCompositor())
        toKeyframeEffect(m_content.get())->pauseAnimationForTestingOnCompositor(currentTimeInternal());
    m_isPausedForTesting = true;
    pause();
}
Ejemplo n.º 13
0
void CSSAnimations::calculateCompositorAnimationUpdate(CSSAnimationUpdate& update, const Element* animatingElement, Element& element, const ComputedStyle& style)
{
    ElementAnimations* elementAnimations = animatingElement ? animatingElement->elementAnimations() : nullptr;

    // We only update compositor animations in response to changes in the base style.
    if (!elementAnimations || elementAnimations->isAnimationStyleChange())
        return;

    if (!animatingElement->layoutObject() || !animatingElement->layoutObject()->style())
        return;

    const ComputedStyle& oldStyle = *animatingElement->layoutObject()->style();
    if (!oldStyle.shouldCompositeForCurrentAnimations())
        return;

    CSSAnimations& cssAnimations = elementAnimations->cssAnimations();
    for (auto& runningAnimation : cssAnimations.m_animations.values()) {
        Animation& animation = *runningAnimation->animation;
        if (animation.effect() && animation.effect()->isKeyframeEffect()) {
            EffectModel* model = toKeyframeEffect(animation.effect())->model();
            if (model && model->isKeyframeEffectModel()) {
                KeyframeEffectModelBase* keyframeEffect = toKeyframeEffectModelBase(model);
                if (keyframeEffect->hasSyntheticKeyframes() && keyframeEffect->snapshotNeutralCompositorKeyframes(element, oldStyle, style))
                    update.updateCompositorKeyframes(&animation);
            }
        }
    }

    if (oldStyle.hasCurrentTransformAnimation() && oldStyle.effectiveZoom() != style.effectiveZoom()) {
        for (auto& entry : elementAnimations->animations()) {
            Animation& animation = *entry.key;
            if (animation.effect() && animation.effect()->isKeyframeEffect()) {
                EffectModel* model = toKeyframeEffect(animation.effect())->model();
                if (model && model->isKeyframeEffectModel()) {
                    KeyframeEffectModelBase* keyframeEffect = toKeyframeEffectModelBase(model);
                    if (keyframeEffect->affects(PropertyHandle(CSSPropertyTransform)) && keyframeEffect->snapshotAllCompositorKeyframes(element, &style))
                        update.updateCompositorKeyframes(&animation);
                }
            }
        }
    }
}
Ejemplo n.º 14
0
Animation* InspectorAnimationAgent::animationClone(Animation* animation)
{
    const String id = String::number(animation->sequenceNumber());
    if (!m_idToAnimationClone.get(id)) {
        KeyframeEffect* oldEffect = toKeyframeEffect(animation->effect());
        KeyframeEffect* newEffect = KeyframeEffect::create(oldEffect->target(), oldEffect->model(), oldEffect->specifiedTiming());
        Animation* clone = Animation::create(newEffect, animation->timeline());
        m_idToAnimationClone.set(id, clone);
        m_idToAnimation.set(String::number(clone->sequenceNumber()), clone);
    }
    return m_idToAnimationClone.get(id);
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
bool Animation::maybeStartAnimationOnCompositor()
{
    if (!canStartAnimationOnCompositor())
        return false;

    bool reversed = m_playbackRate < 0;

    double startTime = timeline()->zeroTime() + startTimeInternal();
    if (reversed) {
        startTime -= effectEnd() / fabs(m_playbackRate);
    }

    double timeOffset = 0;
    if (std::isnan(startTime)) {
        timeOffset = reversed ? effectEnd() - currentTimeInternal() : currentTimeInternal();
        timeOffset = timeOffset / fabs(m_playbackRate);
    }
    ASSERT(m_compositorGroup != 0);
    return toKeyframeEffect(m_content.get())->maybeStartAnimationOnCompositor(m_compositorGroup, startTime, timeOffset, m_playbackRate);
}
Ejemplo n.º 17
0
String InspectorAnimationAgent::createCSSId(blink::Animation& animation) {
  String type =
      m_idToAnimationType.get(String::number(animation.sequenceNumber()));
  ASSERT(type != AnimationType::WebAnimation);

  KeyframeEffect* effect = toKeyframeEffect(animation.effect());
  Vector<CSSPropertyID> cssProperties;
  if (type == AnimationType::CSSAnimation) {
    for (CSSPropertyID property : animationProperties)
      cssProperties.append(property);
  } else {
    for (CSSPropertyID property : transitionProperties)
      cssProperties.append(property);
    cssProperties.append(cssPropertyID(animation.id()));
  }

  Element* element = effect->target();
  HeapVector<Member<CSSStyleDeclaration>> styles =
      m_cssAgent->matchingStyles(element);
  std::unique_ptr<WebCryptoDigestor> digestor =
      createDigestor(HashAlgorithmSha1);
  addStringToDigestor(digestor.get(), type);
  addStringToDigestor(digestor.get(), animation.id());
  for (CSSPropertyID property : cssProperties) {
    CSSStyleDeclaration* style =
        m_cssAgent->findEffectiveDeclaration(property, styles);
    // Ignore inline styles.
    if (!style || !style->parentStyleSheet() || !style->parentRule() ||
        style->parentRule()->type() != CSSRule::kStyleRule)
      continue;
    addStringToDigestor(digestor.get(), getPropertyNameString(property));
    addStringToDigestor(digestor.get(),
                        m_cssAgent->styleSheetId(style->parentStyleSheet()));
    addStringToDigestor(digestor.get(),
                        toCSSStyleRule(style->parentRule())->selectorText());
  }
  DigestValue digestResult;
  finishDigestor(digestor.get(), digestResult);
  return base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
}
Ejemplo n.º 18
0
void CSSAnimations::maybeApplyPendingUpdate(Element* element)
{
    m_previousActiveInterpolationsForAnimations.clear();
    if (m_pendingUpdate.isEmpty())
        return;

    m_previousActiveInterpolationsForAnimations.swap(m_pendingUpdate.activeInterpolationsForAnimations());

    // FIXME: cancelling, pausing, unpausing animations all query compositingState, which is not necessarily up to date here
    // since we call this from recalc style.
    // https://code.google.com/p/chromium/issues/detail?id=339847
    DisableCompositingQueryAsserts disabler;

    for (const AtomicString& animationName : m_pendingUpdate.cancelledAnimationNames()) {
        Animation* animation = m_animations.take(animationName)->animation;
        animation->cancel();
        animation->update(TimingUpdateOnDemand);
    }

    for (const AtomicString& animationName : m_pendingUpdate.animationsWithPauseToggled()) {
        Animation* animation = m_animations.get(animationName)->animation.get();
        if (animation->paused())
            animation->unpause();
        else
            animation->pause();
        if (animation->outdated())
            animation->update(TimingUpdateOnDemand);
    }

    for (const auto& animation : m_pendingUpdate.updatedCompositorKeyframes())
        animation->setCompositorPending(true);

    for (const auto& entry : m_pendingUpdate.animationsWithUpdates()) {
        KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect());

        effect->setModel(entry.effect->model());
        effect->updateSpecifiedTiming(entry.effect->specifiedTiming());

        m_animations.find(entry.name)->value->update(entry);
    }

    for (const auto& entry : m_pendingUpdate.newAnimations()) {
        const InertEffect* inertAnimation = entry.effect.get();
        AnimationEventDelegate* eventDelegate = new AnimationEventDelegate(element, entry.name);
        KeyframeEffect* effect = KeyframeEffect::create(element, inertAnimation->model(), inertAnimation->specifiedTiming(), KeyframeEffect::DefaultPriority, eventDelegate);
        effect->setName(inertAnimation->name());
        Animation* animation = element->document().timeline().play(effect);
        if (inertAnimation->paused())
            animation->pause();
        animation->update(TimingUpdateOnDemand);

        m_animations.set(entry.name, new RunningAnimation(animation, entry));
    }

    // Transitions that are run on the compositor only update main-thread state
    // lazily. However, we need the new state to know what the from state shoud
    // be when transitions are retargeted. Instead of triggering complete style
    // recalculation, we find these cases by searching for new transitions that
    // have matching cancelled animation property IDs on the compositor.
    HeapHashMap<CSSPropertyID, std::pair<Member<KeyframeEffect>, double>> retargetedCompositorTransitions;
    for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) {
        ASSERT(m_transitions.contains(id));

        Animation* animation = m_transitions.take(id).animation;
        KeyframeEffect* effect = toKeyframeEffect(animation->effect());
        if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTransitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->limited())
            retargetedCompositorTransitions.add(id, std::pair<KeyframeEffect*, double>(effect, animation->startTimeInternal()));
        animation->cancel();
        // after cancelation, transitions must be downgraded or they'll fail
        // to be considered when retriggering themselves. This can happen if
        // the transition is captured through getAnimations then played.
        if (animation->effect() && animation->effect()->isKeyframeEffect())
            toKeyframeEffect(animation->effect())->downgradeToNormal();
        animation->update(TimingUpdateOnDemand);
    }

    for (CSSPropertyID id : m_pendingUpdate.finishedTransitions()) {
        // This transition can also be cancelled and finished at the same time
        if (m_transitions.contains(id)) {
            Animation* animation = m_transitions.take(id).animation;
            // Transition must be downgraded
            if (animation->effect() && animation->effect()->isKeyframeEffect())
                toKeyframeEffect(animation->effect())->downgradeToNormal();
        }
    }

    for (const auto& entry : m_pendingUpdate.newTransitions()) {
        const CSSAnimationUpdate::NewTransition& newTransition = entry.value;

        RunningTransition runningTransition;
        runningTransition.from = newTransition.from;
        runningTransition.to = newTransition.to;

        CSSPropertyID id = newTransition.id;
        InertEffect* inertAnimation = newTransition.effect.get();
        TransitionEventDelegate* eventDelegate = new TransitionEventDelegate(element, id);

        EffectModel* model = inertAnimation->model();

        if (retargetedCompositorTransitions.contains(id)) {
            const std::pair<Member<KeyframeEffect>, double>& oldTransition = retargetedCompositorTransitions.get(id);
            KeyframeEffect* oldAnimation = oldTransition.first;
            double oldStartTime = oldTransition.second;
            double inheritedTime = isNull(oldStartTime) ? 0 : element->document().timeline().currentTimeInternal() - oldStartTime;

            AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKeyframeEffectModel(inertAnimation->model());
            const KeyframeVector& frames = oldEffect->getFrames();

            AnimatableValueKeyframeVector newFrames;
            newFrames.append(toAnimatableValueKeyframe(frames[0]->clone().get()));
            newFrames.append(toAnimatableValueKeyframe(frames[1]->clone().get()));
            newFrames.append(toAnimatableValueKeyframe(frames[2]->clone().get()));
            newFrames[0]->clearPropertyValue(id);
            newFrames[1]->clearPropertyValue(id);

            InertEffect* inertAnimationForSampling = InertEffect::create(oldAnimation->model(), oldAnimation->specifiedTiming(), false, inheritedTime);
            OwnPtr<Vector<RefPtr<Interpolation>>> sample = nullptr;
            inertAnimationForSampling->sample(sample);
            if (sample && sample->size() == 1) {
                newFrames[0]->setPropertyValue(id, toLegacyStyleInterpolation(sample->at(0).get())->currentValue());
                newFrames[1]->setPropertyValue(id, toLegacyStyleInterpolation(sample->at(0).get())->currentValue());
                model = AnimatableValueKeyframeEffectModel::create(newFrames);
            }
        }

        KeyframeEffect* transition = KeyframeEffect::create(element, model, inertAnimation->specifiedTiming(), KeyframeEffect::TransitionPriority, eventDelegate);
        transition->setName(inertAnimation->name());
        Animation* animation = element->document().timeline().play(transition);
        // Set the current time as the start time for retargeted transitions
        if (retargetedCompositorTransitions.contains(id))
            animation->setStartTime(element->document().timeline().currentTime());
        animation->update(TimingUpdateOnDemand);
        runningTransition.animation = animation;
        m_transitions.set(id, runningTransition);
        ASSERT(id != CSSPropertyInvalid);
        Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id));
    }
    clearPendingUpdate();
}
Ejemplo n.º 19
0
void Animation::restartAnimationOnCompositor()
{
    if (hasActiveAnimationsOnCompositor())
        toKeyframeEffect(m_content.get())->restartAnimationOnCompositor();
}
Ejemplo n.º 20
0
void Animation::cancelIncompatibleAnimationsOnCompositor()
{
    if (m_content && m_content->isKeyframeEffect())
        toKeyframeEffect(m_content.get())->cancelIncompatibleAnimationsOnCompositor();
}