void AnimationEffect::getComputedTiming(ComputedTimingProperties& computedTiming)
{
    // ComputedTimingProperties members.
    computedTiming.setEndTime(endTimeInternal() * 1000);
    computedTiming.setActiveDuration(activeDurationInternal() * 1000);

    if (ensureCalculated().isInEffect) {
        computedTiming.setLocalTime(ensureCalculated().localTime * 1000);
        computedTiming.setProgress(ensureCalculated().progress);
        computedTiming.setCurrentIteration(ensureCalculated().currentIteration);
    } else {
        computedTiming.setLocalTimeToNull();
        computedTiming.setProgressToNull();
        computedTiming.setCurrentIterationToNull();
    }

    // KeyframeEffectOptions members.
    computedTiming.setDelay(specifiedTiming().startDelay * 1000);
    computedTiming.setEndDelay(specifiedTiming().endDelay * 1000);
    computedTiming.setFill(Timing::fillModeString(resolvedFillMode(specifiedTiming().fillMode, isKeyframeEffect())));
    computedTiming.setIterationStart(specifiedTiming().iterationStart);
    computedTiming.setIterations(specifiedTiming().iterationCount);

    UnrestrictedDoubleOrString duration;
    duration.setUnrestrictedDouble(iterationDuration() * 1000);
    computedTiming.setDuration(duration);

    computedTiming.setPlaybackRate(specifiedTiming().playbackRate);
    computedTiming.setDirection(Timing::playbackDirectionString(specifiedTiming().direction));
    computedTiming.setEasing(specifiedTiming().timingFunction->toString());
}
Exemple #2
0
double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const
{
    const double start = startTimeInternal() + specifiedTiming().startDelay;
    const double end = start + activeDurationInternal();

    switch (phase()) {
    case PhaseBefore:
        ASSERT(start >= localTime);
        return forwards
            ? start - localTime
            : std::numeric_limits<double>::infinity();
    case PhaseActive:
        return 0;
    case PhaseAfter:
        ASSERT(localTime >= end);
        // If this Animation is still in effect then it will need to update
        // when its parent goes out of effect. We have no way of knowing when
        // that will be, however, so the parent will need to supply it.
        return forwards
            ? std::numeric_limits<double>::infinity()
            : localTime - end;
    default:
        ASSERT_NOT_REACHED();
        return std::numeric_limits<double>::infinity();
    }
}
Exemple #3
0
bool Animation::isCandidateForAnimationOnCompositor(double playerPlaybackRate) const
{
    if (!effect()
        || !m_target
        || (m_target->renderStyle() && m_target->renderStyle()->hasMotionPath()))
        return false;

    return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specifiedTiming(), *effect(), playerPlaybackRate);
}
bool KeyframeEffect::isCandidateForAnimationOnCompositor(double animationPlaybackRate) const
{
    if (!model()
        || !m_target
        || (m_target->computedStyle() && m_target->computedStyle()->hasMotionPath()))
        return false;

    return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specifiedTiming(), *m_target, animation(), *model(), animationPlaybackRate);
}
bool KeyframeEffect::isCandidateForAnimationOnCompositor(double animationPlaybackRate) const
{
    // Do not put transforms on compositor if more than one of them are defined
    // in computed style because they need to be explicitly ordered
    if (!model()
        || !m_target
        || (m_target->computedStyle() && m_target->computedStyle()->hasMotionPath())
        || hasMultipleTransformProperties())
        return false;

    return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specifiedTiming(), *m_target, animation(), *model(), animationPlaybackRate);
}
double KeyframeEffectReadOnly::calculateTimeToEffectChange(
    bool forwards,
    double localTime,
    double timeToNextIteration) const {
  const double startTime = specifiedTiming().startDelay;
  const double endTimeMinusEndDelay = startTime + activeDurationInternal();
  const double endTime = endTimeMinusEndDelay + specifiedTiming().endDelay;
  const double afterTime = std::min(endTimeMinusEndDelay, endTime);

  switch (getPhase()) {
    case PhaseNone:
      return std::numeric_limits<double>::infinity();
    case PhaseBefore:
      DCHECK_GE(startTime, localTime);
      return forwards ? startTime - localTime
                      : std::numeric_limits<double>::infinity();
    case PhaseActive:
      if (forwards) {
        // Need service to apply fill / fire events.
        const double timeToEnd = afterTime - localTime;
        if (requiresIterationEvents()) {
          return std::min(timeToEnd, timeToNextIteration);
        }
        return timeToEnd;
      }
      return 0;
    case PhaseAfter:
      DCHECK_GE(localTime, afterTime);
      // If this KeyframeEffect is still in effect then it will need to update
      // when its parent goes out of effect. We have no way of knowing when
      // that will be, however, so the parent will need to supply it.
      return forwards ? std::numeric_limits<double>::infinity()
                      : localTime - afterTime;
    default:
      NOTREACHED();
      return std::numeric_limits<double>::infinity();
  }
}
Exemple #7
0
double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const
{
    const double start = startTimeInternal() + specifiedTiming().startDelay;
    const double end = start + activeDurationInternal();

    switch (phase()) {
    case PhaseBefore:
        ASSERT(start >= localTime);
        return forwards
            ? start - localTime
            : std::numeric_limits<double>::infinity();
    case PhaseActive:
        if (forwards && hasActiveAnimationsOnCompositor()) {
            ASSERT(specifiedTiming().playbackRate == 1);
            // Need service to apply fill / fire events.
            const double timeToEnd = end - localTime;
            if (hasEvents()) {
                return std::min(timeToEnd, timeToNextIteration);
            } else {
                return timeToEnd;
            }
        }
        return 0;
    case PhaseAfter:
        ASSERT(localTime >= end);
        // If this Animation is still in effect then it will need to update
        // when its parent goes out of effect. We have no way of knowing when
        // that will be, however, so the parent will need to supply it.
        return forwards
            ? std::numeric_limits<double>::infinity()
            : localTime - end;
    default:
        ASSERT_NOT_REACHED();
        return std::numeric_limits<double>::infinity();
    }
}
bool KeyframeEffectReadOnly::maybeStartAnimationOnCompositor(
    int group,
    double startTime,
    double currentTime,
    double animationPlaybackRate) {
  DCHECK(!hasActiveAnimationsOnCompositor());
  if (!isCandidateForAnimationOnCompositor(animationPlaybackRate))
    return false;
  if (!CompositorAnimations::canStartAnimationOnCompositor(*m_target))
    return false;
  CompositorAnimations::startAnimationOnCompositor(
      *m_target, group, startTime, currentTime, specifiedTiming(), *animation(),
      *model(), m_compositorAnimationIds, animationPlaybackRate);
  DCHECK(!m_compositorAnimationIds.isEmpty());
  return true;
}
Exemple #9
0
bool Animation::maybeStartAnimationOnCompositor(double startTime, double currentTime)
{
    ASSERT(!hasActiveAnimationsOnCompositor());
    if (!isCandidateForAnimationOnCompositor())
        return false;
    if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target))
        return false;
    if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target, startTime, currentTime, specifiedTiming(), *effect(), m_compositorAnimationIds))
        return false;
    ASSERT(!m_compositorAnimationIds.isEmpty());
    return true;
}
Exemple #10
0
bool Animation::isCandidateForAnimationOnCompositor() const
{
    if (!effect() || !m_target)
        return false;
    return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specifiedTiming(), *effect());
}