void ScrollAnimatorNone::animationTimerFired() { TRACE_EVENT0("webkit", "ScrollAnimatorNone::animationTimerFired"); double currentTime = WTF::monotonicallyIncreasingTime(); double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime); currentTime += deltaToNextFrame; bool continueAnimation = false; if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime)) continueAnimation = true; if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime)) continueAnimation = true; if (continueAnimation) startNextTimer(); else m_animationActive = false; TRACE_EVENT0("webkit", "ScrollAnimatorNone::notifyPositionChanged"); notifyPositionChanged(FloatSize()); if (!continueAnimation) animationDidFinish(); }
void ScrollAnimatorNone::animationTimerFired() { #if PLATFORM(CHROMIUM) TRACE_EVENT("ScrollAnimatorNone::animationTimerFired", this, 0); #endif double currentTime = WTF::monotonicallyIncreasingTime(); double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime); currentTime += deltaToNextFrame; bool continueAnimation = false; if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime)) continueAnimation = true; if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime)) continueAnimation = true; if (m_gestureAnimation) { if (m_gestureAnimation->animate(currentTime)) continueAnimation = true; else m_gestureAnimation.clear(); } if (continueAnimation) startNextTimer(); else m_animationActive = false; #if PLATFORM(CHROMIUM) TRACE_EVENT("ScrollAnimatorNone::notifyPositionChanged", this, 0); #endif notifyPositionChanged(); }
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { FloatSize delta = FloatSize(offset.x() - m_currentPosX, offset.y() - m_currentPosY); m_currentPosX = offset.x(); m_currentPosY = offset.y(); notifyPositionChanged(delta); }
void ScrollAnimator::tickAnimation(double monotonicTime) { if (m_runState != RunState::RunningOnMainThread) return; TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation"); double elapsedTime = monotonicTime - m_startTime; bool isFinished = (elapsedTime > m_animationCurve->duration()); FloatPoint offset = isFinished ? m_animationCurve->targetValue() : m_animationCurve->getValue(elapsedTime); offset = FloatPoint(m_scrollableArea->clampScrollPosition(offset)); m_currentPosX = offset.x(); m_currentPosY = offset.y(); if (isFinished) resetAnimationState(); else scrollableArea()->scheduleAnimation(); TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged"); notifyPositionChanged(); }
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { m_currentPosX = offset.x(); m_currentPosY = offset.y(); resetAnimationState(); notifyPositionChanged(); }
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { if (m_currentPosX != offset.x() || m_currentPosY != offset.y()) { m_currentPosX = offset.x(); m_currentPosY = offset.y(); notifyPositionChanged(); } }
void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime) { if (m_runState != RunState::RunningOnMainThread) return; if (!m_startTime) m_startTime = monotonicTime; double elapsedTime = monotonicTime - m_startTime; bool isFinished = (elapsedTime > m_animationCurve->duration()); FloatPoint offset = m_animationCurve->getValue(elapsedTime); notifyPositionChanged(IntPoint(offset.x(), offset.y())); if (isFinished) { resetAnimationState(); } else if (!m_scrollableArea->scheduleAnimation()) { notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y())); resetAnimationState(); } }
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { m_currentPosX = offset.x(); m_currentPosY = offset.y(); // Must be called after setting the position since canceling the animation resets // the desired position to the current. cancelAnimations(); notifyPositionChanged(); }
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier) { float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY; float newPos = std::max(std::min(*currentPos + (step * multiplier), static_cast<float>(m_scrollableArea->scrollSize(orientation))), 0.0f); if (*currentPos == newPos) return false; *currentPos = newPos; notifyPositionChanged(); return true; }
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float delta) { float& currentPos = (orientation == HorizontalScrollbar) ? m_currentPosX : m_currentPosY; float newPos = clampScrollPosition(orientation, currentPos + step * delta); if (currentPos == newPos) return false; currentPos = newPos; notifyPositionChanged(); return true; }
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier) { float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY; float newPos = m_scrollableArea->clampScrollPosition(orientation, *currentPos + step * multiplier); float delta = *currentPos - newPos; if (*currentPos == newPos) return false; *currentPos = newPos; notifyPositionChanged(orientation == HorizontalScrollbar ? FloatSize(delta, 0) : FloatSize(0, delta)); return true; }
void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { stopAnimationTimerIfNeeded(); m_horizontalData.reset(); *m_horizontalData.m_currentPosition = offset.x(); m_horizontalData.m_desiredPosition = offset.x(); m_verticalData.reset(); *m_verticalData.m_currentPosition = offset.y(); m_verticalData.m_desiredPosition = offset.y(); notifyPositionChanged(); }
void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer) { double currentTime = WTF::monotonicallyIncreasingTime(); double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime); bool continueAnimation = false; if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame)) continueAnimation = true; if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame)) continueAnimation = true; if (continueAnimation) { double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame); timer->startOneShot(nextTimerInterval); } notifyPositionChanged(); }
void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset) { m_startTime = 0.0; m_targetOffset = offset; m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->createScrollOffsetAnimationCurve( m_targetOffset, WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut, WebScrollOffsetAnimationCurve::ScrollDurationDeltaBased)); m_scrollableArea->registerForAnimation(); if (!m_scrollableArea->scheduleAnimation()) { resetAnimationState(); notifyPositionChanged(IntPoint(offset.x(), offset.y())); } m_runState = RunState::WaitingToSendToCompositor; }
void ScrollAnimatorWin::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { stopAnimationTimerIfNeeded(&m_horizontalData); stopAnimationTimerIfNeeded(&m_verticalData); *m_horizontalData.m_currentPos = offset.x(); m_horizontalData.m_desiredPos = offset.x(); m_horizontalData.m_currentVelocity = 0; m_horizontalData.m_desiredVelocity = 0; *m_verticalData.m_currentPos = offset.y(); m_verticalData.m_desiredPos = offset.y(); m_verticalData.m_currentVelocity = 0; m_verticalData.m_desiredVelocity = 0; notifyPositionChanged(); }
ScrollResult ScrollAnimatorBase::userScroll(ScrollGranularity, const FloatSize& delta) { FloatSize consumedDelta = computeDeltaToConsume(delta); FloatPoint newPos = m_currentPos + consumedDelta; if (m_currentPos == newPos) return ScrollResult(false, false, delta.width(), delta.height()); m_currentPos = newPos; notifyPositionChanged(); return ScrollResult( consumedDelta.width(), consumedDelta.height(), delta.width() - consumedDelta.width(), delta.height() - consumedDelta.height()); }
void ProgrammaticScrollAnimator::updateCompositorAnimations() { if (m_compositorAnimationId && m_runState != RunState::RunningOnCompositor) { // If the current run state is WaitingToSendToCompositor but we have a // non-zero compositor animation id, there's a currently running // compositor animation that needs to be removed here before the new // animation is added below. ASSERT(m_runState == RunState::WaitingToCancelOnCompositor || m_runState == RunState::WaitingToSendToCompositor); removeAnimation(); m_compositorAnimationId = 0; m_compositorAnimationGroupId = 0; if (m_runState == RunState::WaitingToCancelOnCompositor) { resetAnimationState(); return; } } if (m_runState == RunState::WaitingToSendToCompositor) { bool sentToCompositor = false; if (!m_scrollableArea->shouldScrollOnMainThread()) { OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*m_animationCurve, WebCompositorAnimation::TargetPropertyScrollOffset)); int animationId = animation->id(); int animationGroupId = animation->group(); if (addAnimation(animation.release())) { sentToCompositor = true; m_runState = RunState::RunningOnCompositor; m_compositorAnimationId = animationId; m_compositorAnimationGroupId = animationGroupId; } } if (!sentToCompositor) { m_runState = RunState::RunningOnMainThread; m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition())); if (!m_scrollableArea->scheduleAnimation()) { notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y())); resetAnimationState(); } } } }
void ProgrammaticScrollAnimator::layerForCompositedScrollingDidChange(WebCompositorAnimationTimeline* timeline) { reattachCompositorPlayerIfNeeded(timeline); // If the composited scrolling layer is lost during a composited animation, // continue the animation on the main thread. if (m_runState == RunState::RunningOnCompositor && !m_scrollableArea->layerForScrolling()) { m_runState = RunState::RunningOnMainThread; m_compositorAnimationId = 0; m_compositorAnimationGroupId = 0; m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition())); m_scrollableArea->registerForAnimation(); if (!m_scrollableArea->scheduleAnimation()) { resetAnimationState(); notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y())); } } }
void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer) { #if PLATFORM(CHROMIUM) TRACE_EVENT("ScrollAnimatorNone::animationTimerFired", this, 0); #endif double currentTime = WTF::monotonicallyIncreasingTime(); double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime); bool continueAnimation = false; if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame)) continueAnimation = true; if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame)) continueAnimation = true; if (m_zoomData.m_isAnimating) { #if PLATFORM(CHROMIUM) TRACE_EVENT("ScrollAnimatorNone::notifyZoomChanged", this, 0); #endif if (m_zoomData.m_startTime && m_zoomData.animateZoom(currentTime + deltaToNextFrame)) { continueAnimation = true; notifyZoomChanged(ZoomAnimationContinuing); } else { notifyZoomChanged(ZoomAnimationFinishing); m_zoomData.m_isAnimating = false; } } if (continueAnimation) { double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame); timer->startOneShot(nextTimerInterval); } #if PLATFORM(CHROMIUM) TRACE_EVENT("ScrollAnimatorNone::notifyPositionChanged", this, 0); #endif notifyPositionChanged(); }
void ScrollAnimator::animationTimerFired() { TRACE_EVENT0("blink", "ScrollAnimator::animationTimerFired"); double currentTime = WTF::monotonicallyIncreasingTime(); bool continueAnimation = false; if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime)) continueAnimation = true; if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime)) continueAnimation = true; if (continueAnimation) startNextTimer(); else m_animationActive = false; TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged"); notifyPositionChanged(); if (!continueAnimation) animationDidFinish(); }
void ScrollAnimatorWin::animateScroll(PerAxisData* data) { // Note on smooth scrolling perf versus non-smooth scrolling perf: // The total time to perform a complete scroll is given by // t = t0 + 0.5tA - tD + tS // Where // t0 = The time to perform the scroll without smooth scrolling // tA = The acceleration time, // ScrollbarTheme::theme()->autoscrollTimerDelay() (see below) // tD = |animationTimerDelay| // tS = A value less than or equal to the time required to perform a // single scroll increment, i.e. the work done due to calling // client()->valueChanged() (~0 for simple pages, larger for complex // pages). // // Because tA and tD are fairly small, the total lag (as users perceive it) // is negligible for simple pages and roughly tS for complex pages. Without // knowing in advance how large tS is it's hard to do better than this. // Perhaps we could try to remember previous values and forward-compensate. // We want to update the scroll position based on the time it's been since // our last update. This may be longer than our ideal time, especially if // the page is complex or the system is slow. // // To avoid feeling laggy, if we've just started smooth scrolling we pretend // we've already accelerated for one ideal interval, so that we'll scroll at // least some distance immediately. double lastScrollInterval = data->m_currentVelocity ? (WTF::currentTime() - data->m_lastAnimationTime) : animationTimerDelay; // Figure out how far we've actually traveled and update our current // velocity. float distanceTraveled; if (data->m_currentVelocity < data->m_desiredVelocity) { // We accelerate at a constant rate until we reach the desired velocity. float accelerationRate = data->m_desiredVelocity / accelerationTime(); // Figure out whether contant acceleration has caused us to reach our // target velocity. float potentialVelocityChange = accelerationRate * lastScrollInterval; float potentialNewVelocity = data->m_currentVelocity + potentialVelocityChange; if (potentialNewVelocity > data->m_desiredVelocity) { // We reached the target velocity at some point between our last // update and now. The distance traveled can be calculated in two // pieces: the distance traveled while accelerating, and the // distance traveled after reaching the target velocity. float actualVelocityChange = data->m_desiredVelocity - data->m_currentVelocity; float accelerationInterval = actualVelocityChange / accelerationRate; // The distance traveled under constant acceleration is the area // under a line segment with a constant rising slope. Break this // into a triangular portion atop a rectangular portion and sum. distanceTraveled = ((data->m_currentVelocity + (actualVelocityChange / 2)) * accelerationInterval); // The distance traveled at the target velocity is simply // (target velocity) * (remaining time after accelerating). distanceTraveled += (data->m_desiredVelocity * (lastScrollInterval - accelerationInterval)); data->m_currentVelocity = data->m_desiredVelocity; } else { // Constant acceleration through the entire time interval. distanceTraveled = (data->m_currentVelocity + (potentialVelocityChange / 2)) * lastScrollInterval; data->m_currentVelocity = potentialNewVelocity; } } else { // We've already reached the target velocity, so the distance we've // traveled is simply (current velocity) * (elapsed time). distanceTraveled = data->m_currentVelocity * lastScrollInterval; // If our desired velocity has decreased, drop the current velocity too. data->m_currentVelocity = data->m_desiredVelocity; } // Now update the scroll position based on the distance traveled. if (distanceTraveled >= fabs(data->m_desiredPos - *data->m_currentPos)) { // We've traveled far enough to reach the desired position. Stop smooth // scrolling. *data->m_currentPos = data->m_desiredPos; data->m_currentVelocity = 0; data->m_desiredVelocity = 0; } else { // Not yet at the target position. Travel towards it and set up the // next update. if (*data->m_currentPos > data->m_desiredPos) distanceTraveled = -distanceTraveled; *data->m_currentPos += distanceTraveled; data->m_animationTimer.startOneShot(animationTimerDelay); data->m_lastAnimationTime = WTF::currentTime(); } notifyPositionChanged(); }
void ProgrammaticScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { cancelAnimation(); notifyPositionChanged(offset); }
void ScrollAnimatorBase::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { m_currentPos = offset; notifyPositionChanged(); }