float ScrollAnimator::computeDeltaToConsume( ScrollbarOrientation orientation, float pixelDelta) const { FloatPoint pos = desiredTargetPosition(); float currentPos = (orientation == HorizontalScrollbar) ? pos.x() : pos.y(); float newPos = clampScrollPosition(orientation, currentPos + pixelDelta); return (currentPos == newPos) ? 0.0f : (newPos - currentPos); }
ScrollResultOneDimensional ScrollAnimator::userScroll( ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta) { if (!m_scrollableArea->scrollAnimatorEnabled()) return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); TRACE_EVENT0("blink", "ScrollAnimator::scroll"); if (granularity == ScrollByPrecisePixel) return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); float usedPixelDelta = computeDeltaToConsume(orientation, step * delta); FloatPoint pixelDelta = (orientation == VerticalScrollbar ? FloatPoint(0, usedPixelDelta) : FloatPoint(usedPixelDelta, 0)); FloatPoint targetPos = desiredTargetPosition(); targetPos.moveBy(pixelDelta); if (m_animationCurve) { if ((targetPos - m_targetOffset).isZero()) { // Report unused delta only if there is no animation running. See // comment below regarding scroll latching. return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } m_targetOffset = targetPos; ASSERT(m_runState == RunState::RunningOnMainThread || m_runState == RunState::RunningOnCompositor || m_runState == RunState::RunningOnCompositorButNeedsUpdate); if (m_runState == RunState::RunningOnCompositor || m_runState == RunState::RunningOnCompositorButNeedsUpdate) { if (registerAndScheduleAnimation()) m_runState = RunState::RunningOnCompositorButNeedsUpdate; return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } // Running on the main thread, simply update the target offset instead // of sending to the compositor. m_animationCurve->updateTarget(m_timeFunction() - m_startTime, targetPos); return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } if ((targetPos - currentPosition()).isZero()) { // Report unused delta only if there is no animation and we are not // starting one. This ensures we latch for the duration of the // animation rather than animating multiple scrollers at the same time. return ScrollResultOneDimensional(/* didScroll */ false, delta); } m_targetOffset = targetPos; m_startTime = m_timeFunction(); if (registerAndScheduleAnimation()) m_runState = RunState::WaitingToSendToCompositor; return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); }