void Player::setStartTime(double startTime) { ASSERT(!isNull(startTime)); ASSERT(!hasStartTime()); m_startTime = startTime; update(); }
bool AnimationPlayer::update(TimingUpdateReason reason) { if (!m_timeline) return false; PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending); m_outdated = false; bool idle = playStateInternal() == Idle; if (m_content) { double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); // Special case for end-exclusivity when playing backwards. if (inheritedTime == 0 && m_playbackRate < 0) inheritedTime = -1; m_content->updateInheritedTime(inheritedTime, reason); } if ((idle || finished()) && !m_finished) { if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) { const AtomicString& eventType = EventTypeNames::finish; if (executionContext() && hasEventListeners(eventType)) { double eventCurrentTime = currentTimeInternal() * 1000; m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); m_pendingFinishedEvent->setTarget(this); m_pendingFinishedEvent->setCurrentTarget(this); m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent); } m_finished = true; } } ASSERT(!m_outdated); return !m_finished; }
void AnimationPlayer::setStartTimeInternal(double newStartTime) { ASSERT(!m_paused); ASSERT(std::isfinite(newStartTime)); ASSERT(newStartTime != m_startTime); bool hadStartTime = hasStartTime(); double previousCurrentTime = currentTimeInternal(); m_startTime = newStartTime; if (m_held && m_playbackRate) { // If held, the start time would still be derrived from the hold time. // Force a new, limited, current time. m_held = false; double currentTime = calculateCurrentTime(); if (m_playbackRate > 0 && currentTime > sourceEnd()) { currentTime = sourceEnd(); } else if (m_playbackRate < 0 && currentTime < 0) { currentTime = 0; } setCurrentTimeInternal(currentTime, TimingUpdateOnDemand); } updateCurrentTimingState(TimingUpdateOnDemand); double newCurrentTime = currentTimeInternal(); if (previousCurrentTime != newCurrentTime) { setOutdated(); } else if (!hadStartTime && m_timeline) { // Even though this player is not outdated, time to effect change is // infinity until start time is set. m_timeline->wake(); } }
bool AnimationPlayer::update(TimingUpdateReason reason) { if (!m_timeline) return false; updateCurrentTimingState(reason); m_outdated = false; if (m_content) { double inheritedTime = isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); m_content->updateInheritedTime(inheritedTime, reason); } if (finished() && !m_finished) { if (reason == TimingUpdateForAnimationFrame && hasStartTime()) { const AtomicString& eventType = EventTypeNames::finish; if (executionContext() && hasEventListeners(eventType)) { m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, currentTime(), timeline()->currentTime()); m_pendingFinishedEvent->setTarget(this); m_pendingFinishedEvent->setCurrentTarget(this); m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent); } m_finished = true; } } ASSERT(!m_outdated); return !m_finished || !finished(); }
double Animation::timeToEffectChange() { ASSERT(!m_outdated); if (!hasStartTime()) return std::numeric_limits<double>::infinity(); double currentTime = calculateCurrentTime(); if (m_held) { if (limited(currentTime)) { if (m_playbackRate > 0 && m_endClip + effectEnd() > currentTime) return m_endClip + effectEnd() - currentTime; if (m_playbackRate < 0 && m_startClip <= currentTime) return m_startClip - currentTime; } return std::numeric_limits<double>::infinity(); } if (!m_content) return -currentTimeInternal() / m_playbackRate; double result = m_playbackRate > 0 ? m_content->timeToForwardsEffectChange() / m_playbackRate : m_content->timeToReverseEffectChange() / -m_playbackRate; return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationEffect::PhaseActive ? 0 : clipTimeToEffectChange(result); }
bool Player::maybeStartAnimationOnCompositor() { // FIXME: Support starting compositor animations that have a fixed // start time. ASSERT(!hasStartTime()); if (!m_content || !m_content->isAnimation()) return false; return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(); }
double AnimationPlayer::timeToEffectChange() { ASSERT(!m_outdated); if (m_held || !hasStartTime()) return std::numeric_limits<double>::infinity(); if (!m_content) return -currentTimeInternal() / m_playbackRate; if (m_playbackRate > 0) return m_content->timeToForwardsEffectChange() / m_playbackRate; return m_content->timeToReverseEffectChange() / -m_playbackRate; }
double AnimationPlayer::timeToEffectChange() { ASSERT(!m_outdated); if (m_held || !hasStartTime()) return std::numeric_limits<double>::infinity(); if (!m_content) return -currentTimeInternal() / m_playbackRate; double result = m_playbackRate > 0 ? m_content->timeToForwardsEffectChange() / m_playbackRate : m_content->timeToReverseEffectChange() / -m_playbackRate; return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationNode::PhaseActive ? 0 : result; }
bool Animation::update(TimingUpdateReason reason) { if (!m_timeline) return false; PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending); clearOutdated(); bool idle = playStateInternal() == Idle; if (m_content) { double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); if (!isNull(inheritedTime)) { double timeForClipping = m_held && (!limited(inheritedTime) || isNull(m_startTime)) // Use hold time when there is no start time. ? inheritedTime // Use calculated current time when the animation is limited. : calculateCurrentTime(); if (clipped(timeForClipping)) inheritedTime = nullValue(); } // Special case for end-exclusivity when playing backwards. if (inheritedTime == 0 && m_playbackRate < 0) inheritedTime = -1; m_content->updateInheritedTime(inheritedTime, reason); } if ((idle || limited()) && !m_finished) { if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) { if (idle) { // TODO(dstockwell): Fire the cancel event. } else { const AtomicString& eventType = EventTypeNames::finish; if (executionContext() && hasEventListeners(eventType)) { double eventCurrentTime = currentTimeInternal() * 1000; m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); m_pendingFinishedEvent->setTarget(this); m_pendingFinishedEvent->setCurrentTarget(this); m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent); } } m_finished = true; } } ASSERT(!m_outdated); return !m_finished || std::isfinite(timeToEffectChange()); }
void AnimationPlayer::setPlaybackRateInternal(double playbackRate) { ASSERT(std::isfinite(playbackRate)); ASSERT(playbackRate != m_playbackRate); if (!finished() && !paused() && hasStartTime()) m_currentTimePending = true; double storedCurrentTime = currentTimeInternal(); if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && playbackRate <= 0)) m_finished = false; m_playbackRate = playbackRate; m_startTime = std::numeric_limits<double>::quiet_NaN(); setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); }