Changeset 172659 in webkit


Ignore:
Timestamp:
Aug 15, 2014 4:35:21 PM (10 years ago)
Author:
commit-queue@webkit.org
Message:

Fix gliding in AxisScrollSnapAnimator for Mac
https://bugs.webkit.org/show_bug.cgi?id=135971

Patch by Wenson Hsieh <Wenson Hsieh> on 2014-08-15
Reviewed by Dean Jackson.

Previously, momentum events that are handled immediately after finishing a glide animation cause a second, extremely
slow glide animation to trigger. To fix this, I added a new state DestinationReached. During this state, additional
momentum events that are handled after the glide animation completes will not fill up the momentum window and trigger
a second glide event.

  • platform/mac/AxisScrollSnapAnimator.h:
  • platform/mac/AxisScrollSnapAnimator.mm:

(WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator):
(WebCore::AxisScrollSnapAnimator::handleWheelEvent):
(WebCore::AxisScrollSnapAnimator::scrollSnapAnimationUpdate):
(WebCore::AxisScrollSnapAnimator::endScrollSnapAnimation):
(WebCore::AxisScrollSnapAnimator::computeGlideDelta):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r172657 r172659  
     12014-08-15  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Fix gliding in AxisScrollSnapAnimator for Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=135971
     5
     6        Reviewed by Dean Jackson.
     7
     8        Previously, momentum events that are handled immediately after finishing a glide animation cause a second, extremely
     9        slow glide animation to trigger. To fix this, I added a new state DestinationReached. During this state, additional
     10        momentum events that are handled after the glide animation completes will not fill up the momentum window and trigger
     11        a second glide event.
     12
     13        * platform/mac/AxisScrollSnapAnimator.h:
     14        * platform/mac/AxisScrollSnapAnimator.mm:
     15        (WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator):
     16        (WebCore::AxisScrollSnapAnimator::handleWheelEvent):
     17        (WebCore::AxisScrollSnapAnimator::scrollSnapAnimationUpdate):
     18        (WebCore::AxisScrollSnapAnimator::endScrollSnapAnimation):
     19        (WebCore::AxisScrollSnapAnimator::computeGlideDelta):
     20
    1212014-08-15  Eric Carlson  <eric.carlson@apple.com>
    222
  • trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h

    r172616 r172659  
    3939    Snapping,
    4040    Gliding,
    41     Idle
     41    DestinationReached,
     42    UserInteraction
    4243};
    4344
     
    7273private:
    7374    void beginScrollSnapAnimation(ScrollSnapState);
    74     void endScrollSnapAnimation();
     75    void endScrollSnapAnimation(ScrollSnapState);
    7576
    7677    float computeSnapDelta() const;
  • trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm

    r172649 r172659  
    8787    , m_snapOffsets(snapOffsets)
    8888    , m_axis(axis)
    89     , m_currentState(ScrollSnapState::Idle)
     89    , m_currentState(ScrollSnapState::DestinationReached)
    9090    , m_initialOffset(0)
    9191    , m_targetOffset(0)
     
    109109    case WheelEventStatus::UserScrollBegin:
    110110    case WheelEventStatus::UserScrolling:
    111         endScrollSnapAnimation();
     111        endScrollSnapAnimation(ScrollSnapState::UserInteraction);
    112112        break;
    113113
     
    118118    case WheelEventStatus::InertialScrollBegin:
    119119        // Begin tracking wheel deltas for glide prediction.
    120         endScrollSnapAnimation();
     120        endScrollSnapAnimation(ScrollSnapState::UserInteraction);
    121121        pushInitialWheelDelta(wheelDelta);
    122122        m_beginTrackingWheelDeltaOffset = m_client->scrollOffsetInAxis(m_axis);
     
    124124
    125125    case WheelEventStatus::InertialScrolling:
    126         if (m_currentState != ScrollSnapState::Gliding) {
    127             // FIXME: Investigate why small wheel deltas pushed into the window without the < -1, > 1 check.
    128             if (m_numWheelDeltasTracked < wheelDeltaWindowSize && (wheelDelta < -1 || wheelDelta > 1))
     126        // This check for DestinationReached ensures that we don't receive another set of momentum events after ending the last glide.
     127        if (m_currentState != ScrollSnapState::Gliding && m_currentState != ScrollSnapState::DestinationReached) {
     128            if (m_numWheelDeltasTracked < wheelDeltaWindowSize)
    129129                pushInitialWheelDelta(wheelDelta);
    130130
     
    156156    if (delta)
    157157        m_client->immediateScrollInAxis(m_axis, delta);
    158     else {
    159         endScrollSnapAnimation();
    160         m_currentState = ScrollSnapState::Idle;
    161     }
     158    else
     159        endScrollSnapAnimation(ScrollSnapState::DestinationReached);
    162160}
    163161
     
    190188}
    191189
    192 void AxisScrollSnapAnimator::endScrollSnapAnimation()
    193 {
     190void AxisScrollSnapAnimator::endScrollSnapAnimation(ScrollSnapState newState)
     191{
     192    ASSERT(newState == ScrollSnapState::DestinationReached || newState == ScrollSnapState::UserInteraction);
    194193    if (m_currentState == ScrollSnapState::Gliding)
    195194        clearInitialWheelDeltaWindow();
    196195
    197     m_currentState = ScrollSnapState::Idle;
     196    m_currentState = newState;
    198197    m_client->stopScrollSnapTimer();
    199198}
     
    246245
    247246    float progress = ((float)(offset - m_initialOffset)) / (m_targetOffset - m_initialOffset);
    248     float shift = ceil(m_glideMagnitude * (1 + cos(piFloat * progress + m_glidePhaseShift)));
     247    // FIXME: We might want to investigate why -m_glidePhaseShift results in the behavior we want.
     248    float shift = ceil(m_glideMagnitude * (1 + cos(piFloat * progress - m_glidePhaseShift)));
    249249    shift = m_initialOffset < m_targetOffset ? std::max<float>(shift, 1) : std::min<float>(shift, -1);
    250250    if ((m_initialOffset < m_targetOffset && offset + shift > m_targetOffset) || (m_initialOffset > m_targetOffset && offset + shift < m_targetOffset))
Note: See TracChangeset for help on using the changeset viewer.