⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 282697 in webkit


Ignore:
Timestamp:
Sep 17, 2021, 2:43:47 PM (5 years ago)
Author:
Simon Fraser
Message:

Make ScrollAnimation a little more generic
​https://bugs.webkit.org/show_bug.cgi?id=230385

Reviewed by Tim Horton.

Prepare for new ScrollAnimation subclasses by making it a little more generic. Rather
than the function callbacks, use a virtual client class, implemented by ScrollAnimator
and ScrollingTreeScrollingNodeDelegateNicosia. Remove the generic 'scroll' methods
from the base class, since they only apply to ScrollAnimationSmooth (clients need
to keep derived class pointers, and most already do).

Remove ambiguity around the currentPosition by requiring it for every 'start' call.
Remove ambiguity around setCurrentPosition() by removing it. Clients just call stop().
Remove ambiguity around retargeting by making it explicit.

Do per-axis setup when starting animations, not when creating one, so the animation starts
out stateless.

  • Sources.txt: Build platform/ScrollAnimationKinetic.cpp for macOS, mostly to catch

build errors (it's currently unused).

  • WebCore.xcodeproj/project.pbxproj:
  • page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:

(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::resetCurrentPosition):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationKinetic):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationSmooth):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation):

  • page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h:
  • platform/ScrollAnimation.h:

(WebCore::ScrollAnimation::ScrollAnimation):
(WebCore::ScrollAnimation::updateScrollExtents):
(WebCore::ScrollAnimation::serviceAnimation):
(WebCore::ScrollAnimation::~ScrollAnimation): Deleted.
(WebCore::ScrollAnimation::scroll): Deleted.
(WebCore::ScrollAnimation::updateVisibleLengths): Deleted.
(WebCore::ScrollAnimation::setCurrentPosition): Deleted.

  • platform/ScrollAnimationKinetic.cpp:

(WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
(WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationKinetic::animationTimerFired):
(WebCore::ScrollAnimationKinetic::start): Deleted.

  • platform/ScrollAnimationKinetic.h:
  • platform/ScrollAnimationSmooth.cpp:

(WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
(WebCore::ScrollAnimationSmooth::startAnimatedScroll):
(WebCore::ScrollAnimationSmooth::startAnimatedScrollToDestination):
(WebCore::ScrollAnimationSmooth::stop):
(WebCore::ScrollAnimationSmooth::updateScrollExtents):
(WebCore::ScrollAnimationSmooth::initializeAxesData):
(WebCore::ScrollAnimationSmooth::animationTimerFired):
(WebCore::ScrollAnimationSmooth::PerAxisData::PerAxisData): Deleted.
(WebCore::ScrollAnimationSmooth::scroll): Deleted.
(WebCore::ScrollAnimationSmooth::updateVisibleLengths): Deleted.
(WebCore::ScrollAnimationSmooth::setCurrentPosition): Deleted.

  • platform/ScrollAnimationSmooth.h: Rename some "time" variables to "duration" for clarity
  • platform/ScrollAnimator.cpp:

(WebCore::ScrollAnimator::ScrollAnimator):
(WebCore::ScrollAnimator::scroll):
(WebCore::ScrollAnimator::scrollToPositionWithoutAnimation):
(WebCore::ScrollAnimator::scrollToPositionWithAnimation):
(WebCore::ScrollAnimator::retargetRunningAnimation):
(WebCore::ScrollAnimator::contentsResized const):
(WebCore::ScrollAnimator::willEndLiveResize):
(WebCore::ScrollAnimator::didAddVerticalScrollbar):
(WebCore::ScrollAnimator::didAddHorizontalScrollbar):
(WebCore::ScrollAnimator::scrollAnimationDidUpdate):
(WebCore::ScrollAnimator::scrollAnimationDidEnd):
(WebCore::ScrollAnimator::scrollExtentsForAnimation):
(): Deleted.
(WebCore::m_keyboardScrollingAnimator): Deleted.

  • platform/ScrollAnimator.h:
  • platform/generic/ScrollAnimatorGeneric.cpp:

(WebCore::ScrollAnimatorGeneric::ScrollAnimatorGeneric):
(WebCore::ScrollAnimatorGeneric::handleWheelEvent):
(WebCore::ScrollAnimatorGeneric::updatePosition):
(WebCore::ScrollAnimatorGeneric::scrollAnimationDidUpdate):

  • platform/generic/ScrollAnimatorGeneric.h:
Location:
trunk/Source/WebCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r282696 r282697  
     12021-09-17  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make ScrollAnimation a little more generic
     4        https://bugs.webkit.org/show_bug.cgi?id=230385
     5
     6        Reviewed by Tim Horton.
     7
     8        Prepare for new ScrollAnimation subclasses by making it a little more generic. Rather
     9        than the function callbacks, use a virtual client class, implemented by ScrollAnimator
     10        and ScrollingTreeScrollingNodeDelegateNicosia. Remove the generic 'scroll' methods
     11        from the base class, since they only apply to ScrollAnimationSmooth (clients need
     12        to keep derived class pointers, and most already do).
     13       
     14        Remove ambiguity around the currentPosition by requiring it for every 'start' call.
     15        Remove ambiguity around setCurrentPosition() by removing it. Clients just call stop().
     16        Remove ambiguity around retargeting by making it explicit.
     17       
     18        Do per-axis setup when starting animations, not when creating one, so the animation starts
     19        out stateless.
     20
     21        * Sources.txt: Build platform/ScrollAnimationKinetic.cpp for macOS, mostly to catch
     22        build errors (it's currently unused).
     23        * WebCore.xcodeproj/project.pbxproj:
     24        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
     25        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::resetCurrentPosition):
     26        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationKinetic):
     27        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationSmooth):
     28        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
     29        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate):
     30        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd):
     31        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation):
     32        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h:
     33        * platform/ScrollAnimation.h:
     34        (WebCore::ScrollAnimation::ScrollAnimation):
     35        (WebCore::ScrollAnimation::updateScrollExtents):
     36        (WebCore::ScrollAnimation::serviceAnimation):
     37        (WebCore::ScrollAnimation::~ScrollAnimation): Deleted.
     38        (WebCore::ScrollAnimation::scroll): Deleted.
     39        (WebCore::ScrollAnimation::updateVisibleLengths): Deleted.
     40        (WebCore::ScrollAnimation::setCurrentPosition): Deleted.
     41        * platform/ScrollAnimationKinetic.cpp:
     42        (WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
     43        (WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
     44        (WebCore::ScrollAnimationKinetic::animationTimerFired):
     45        (WebCore::ScrollAnimationKinetic::start): Deleted.
     46        * platform/ScrollAnimationKinetic.h:
     47        * platform/ScrollAnimationSmooth.cpp:
     48        (WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
     49        (WebCore::ScrollAnimationSmooth::startAnimatedScroll):
     50        (WebCore::ScrollAnimationSmooth::startAnimatedScrollToDestination):
     51        (WebCore::ScrollAnimationSmooth::stop):
     52        (WebCore::ScrollAnimationSmooth::updateScrollExtents):
     53        (WebCore::ScrollAnimationSmooth::initializeAxesData):
     54        (WebCore::ScrollAnimationSmooth::animationTimerFired):
     55        (WebCore::ScrollAnimationSmooth::PerAxisData::PerAxisData): Deleted.
     56        (WebCore::ScrollAnimationSmooth::scroll): Deleted.
     57        (WebCore::ScrollAnimationSmooth::updateVisibleLengths): Deleted.
     58        (WebCore::ScrollAnimationSmooth::setCurrentPosition): Deleted.
     59        * platform/ScrollAnimationSmooth.h: Rename some "time" variables to "duration" for clarity
     60        * platform/ScrollAnimator.cpp:
     61        (WebCore::ScrollAnimator::ScrollAnimator):
     62        (WebCore::ScrollAnimator::scroll):
     63        (WebCore::ScrollAnimator::scrollToPositionWithoutAnimation):
     64        (WebCore::ScrollAnimator::scrollToPositionWithAnimation):
     65        (WebCore::ScrollAnimator::retargetRunningAnimation):
     66        (WebCore::ScrollAnimator::contentsResized const):
     67        (WebCore::ScrollAnimator::willEndLiveResize):
     68        (WebCore::ScrollAnimator::didAddVerticalScrollbar):
     69        (WebCore::ScrollAnimator::didAddHorizontalScrollbar):
     70        (WebCore::ScrollAnimator::scrollAnimationDidUpdate):
     71        (WebCore::ScrollAnimator::scrollAnimationDidEnd):
     72        (WebCore::ScrollAnimator::scrollExtentsForAnimation):
     73        (): Deleted.
     74        (WebCore::m_keyboardScrollingAnimator): Deleted.
     75        * platform/ScrollAnimator.h:
     76        * platform/generic/ScrollAnimatorGeneric.cpp:
     77        (WebCore::ScrollAnimatorGeneric::ScrollAnimatorGeneric):
     78        (WebCore::ScrollAnimatorGeneric::handleWheelEvent):
     79        (WebCore::ScrollAnimatorGeneric::updatePosition):
     80        (WebCore::ScrollAnimatorGeneric::scrollAnimationDidUpdate):
     81        * platform/generic/ScrollAnimatorGeneric.h:
     82
    1832021-09-17  Cameron McCormack  <heycam@apple.com>
    284
  • trunk/Source/WebCore/Sources.txt

    r282525 r282697  
    18121812platform/RuntimeApplicationChecks.cpp
    18131813platform/SSLKeyGenerator.cpp
     1814platform/ScrollAnimationKinetic.cpp
    18141815platform/ScrollAnimationSmooth.cpp
    18151816platform/ScrollAnimator.cpp
  • trunk/Source/WebCore/SourcesGTK.txt

    r282643 r282697  
    7070page/scrolling/nicosia/ScrollingTreeStickyNode.cpp
    7171
    72 platform/ScrollAnimationKinetic.cpp
    7372platform/UserAgentQuirks.cpp
    7473
  • trunk/Source/WebCore/SourcesWPE.txt

    r274750 r282697  
    5959page/scrolling/nicosia/ScrollingTreeStickyNode.cpp
    6060
    61 platform/ScrollAnimationKinetic.cpp
    6261platform/UserAgentQuirks.cpp
    6362
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r282525 r282697  
    353353                0F9DAA0F1FD1C66A0079C5B2 /* DOMGCOutputConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9DAA0E1FD1C6640079C5B2 /* DOMGCOutputConstraint.h */; };
    354354                0FA24D7A162DF91900A3F4C0 /* GraphicsLayerUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA24D78162DF91900A3F4C0 /* GraphicsLayerUpdater.h */; settings = {ATTRIBUTES = (Private, ); }; };
     355                0FA61B0E26F43213001AADB6 /* ScrollAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    355356                0FB6252F18DE1B1500A07C05 /* GeometryUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB6252D18DE1B1500A07C05 /* GeometryUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
    356357                0FB8890F167D30160010CDA5 /* ScrollingStateStickyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB8890D167D30160010CDA5 /* ScrollingStateStickyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    … …  
    63256326                0FA24D77162DF91900A3F4C0 /* GraphicsLayerUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsLayerUpdater.cpp; sourceTree = "<group>"; };
    63266327                0FA24D78162DF91900A3F4C0 /* GraphicsLayerUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayerUpdater.h; sourceTree = "<group>"; };
     6328                0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimation.h; sourceTree = "<group>"; };
    63276329                0FB0689425243B90001E8E75 /* DisplayTextBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayTextBox.cpp; sourceTree = "<group>"; };
    63286330                0FB0689625243B90001E8E75 /* DisplayTextBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayTextBox.h; sourceTree = "<group>"; };
    … …  
    2804428046                                BC8AE34C12EA096A00EB3AE6 /* ScrollableArea.cpp */,
    2804528047                                BC8AE34D12EA096A00EB3AE6 /* ScrollableArea.h */,
     28048                                0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */,
    2804628049                                0FC692BC257C0F410098E3F9 /* ScrollAnimationKinetic.cpp */,
    2804728050                                0FC692BA257C0F400098E3F9 /* ScrollAnimationKinetic.h */,
    … …  
    3313333136                                652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */,
    3313433137                                460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */,
    33135                                 410BCF5626F0CD8C0040B124 /* RTCLocalSessionDescriptionInit.h in Headers */,
    3313633138                                65E0E9441133C89F00B4CB10 /* JSDOMWrapper.h in Headers */,
    3313733139                                7C45C9D31E3FCBD700AAB558 /* JSDOMWrapperCache.h in Headers */,
    … …  
    3474334745                                313591081E7DDC7300F30630 /* RTCIceTransportPolicy.h in Headers */,
    3474434746                                313591091E7DDC7300F30630 /* RTCIceTransportState.h in Headers */,
     34747                                410BCF5626F0CD8C0040B124 /* RTCLocalSessionDescriptionInit.h in Headers */,
    3474534748                                41C14BC626DE6DE800685BF5 /* RTCNetworkManager.h in Headers */,
    3474634749                                073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */,
    … …  
    3481534818                                BC8AE34F12EA096A00EB3AE6 /* ScrollableArea.h in Headers */,
    3481634819                                5D925B680F64D4DD00B847F0 /* ScrollAlignment.h in Headers */,
     34820                                0FA61B0E26F43213001AADB6 /* ScrollAnimation.h in Headers */,
    3481734821                                CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
    3481834822                                0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */,
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp

    r280171 r282697  
    6262#if ENABLE(SMOOTH_SCROLLING)
    6363    if (m_smoothAnimation)
    64         m_smoothAnimation->setCurrentPosition(scrollingNode().currentScrollPosition());
     64        m_smoothAnimation->stop();
    6565#endif
    6666}
    … …  
    7070#if ENABLE(SMOOTH_SCROLLING)
    7171    if (m_smoothAnimation)
    72         m_smoothAnimation->updateVisibleLengths();
     72        m_smoothAnimation->updateScrollExtents();
    7373#endif
    7474}
    … …  
    8080        return;
    8181
    82     m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(
    83         [this]() -> ScrollExtents {
    84             return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()), IntSize(scrollableAreaSize()) };
    85         },
    86         [this](FloatPoint&& position) {
    87 #if ENABLE(SMOOTH_SCROLLING)
    88             if (m_smoothAnimation)
    89                 m_smoothAnimation->setCurrentPosition(position);
    90 #endif
    91             auto updateScope = createUpdateScope();
    92             scrollingNode().scrollTo(position);
    93         });
     82    m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(*this);
    9483}
    9584#endif
    … …  
    10190        return;
    10291
    103     m_smoothAnimation = makeUnique<ScrollAnimationSmooth>(
    104         [this]() -> ScrollExtents {
    105             return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()), IntSize(scrollableAreaSize()) };
    106         },
    107         currentScrollPosition(),
    108         [this](FloatPoint&& position) {
    109             auto updateScope = createUpdateScope();
    110             scrollingNode().scrollTo(position);
    111         },
    112         [] { });
     92    m_smoothAnimation = makeUnique<ScrollAnimationSmooth>(*this);
    11393}
    11494#endif
    … …  
    126106    m_kineticAnimation->stop();
    127107    if (wheelEvent.isEndOfNonMomentumScroll()) {
    128         m_kineticAnimation->start(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
     108        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
    129109        m_kineticAnimation->clearScrollHistory();
    130110        return WheelEventHandlingResult::handled();
    131111    }
    132112    if (wheelEvent.isTransitioningToMomentumScroll()) {
    133         m_kineticAnimation->start(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
     113        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
    134114        m_kineticAnimation->clearScrollHistory();
    135115        return WheelEventHandlingResult::handled();
    … …  
    183163    if (m_scrollAnimatorEnabled && !wheelEvent.hasPreciseScrollingDeltas()) {
    184164        ensureScrollAnimationSmooth();
    185         m_smoothAnimation->scroll(HorizontalScrollbar, ScrollByPixel, 1, deltaX);
    186         m_smoothAnimation->scroll(VerticalScrollbar, ScrollByPixel, 1, deltaY);
     165        m_smoothAnimation->startAnimatedScroll(HorizontalScrollbar, ScrollByPixel, currentScrollPosition(), 1, deltaX);
     166        m_smoothAnimation->startAnimatedScroll(VerticalScrollbar, ScrollByPixel, currentScrollPosition(), 1, deltaY);
    187167        return WheelEventHandlingResult::handled();
    188168    }
    … …  
    217197}
    218198
     199void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
     200{
     201#if ENABLE(SMOOTH_SCROLLING)
     202    if (&animation == m_kineticAnimation.get()) {
     203        if (m_smoothAnimation)
     204            m_smoothAnimation->stop();
     205    }
     206#endif
     207    auto updateScope = createUpdateScope();
     208    scrollingNode().scrollTo(position);
     209}
     210
     211void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd(ScrollAnimation&)
     212{
     213}
     214
     215ScrollExtents ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation(ScrollAnimation&)
     216{
     217    return {
     218        IntPoint(minimumScrollPosition()),
     219        IntPoint(maximumScrollPosition()),
     220        IntSize(scrollableAreaSize())
     221    };
     222}
     223
    219224} // namespace WebCore
    220225
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h

    r274495 r282697  
    3232
    3333#include "NicosiaPlatformLayer.h"
     34#include "ScrollAnimation.h"
    3435#include "ScrollingStateOverflowScrollingNode.h"
    3536#include "ThreadedScrollingTree.h"
    … …  
    4546namespace WebCore {
    4647
    47 class ScrollingTreeScrollingNodeDelegateNicosia : public ScrollingTreeScrollingNodeDelegate {
     48class ScrollingTreeScrollingNodeDelegateNicosia : public ScrollingTreeScrollingNodeDelegate, public ScrollAnimationClient {
    4849public:
    4950    explicit ScrollingTreeScrollingNodeDelegateNicosia(ScrollingTreeScrollingNode&, bool scrollAnimatorEnabled);
    … …  
    6768#endif
    6869
     70    // ScrollAnimationClient
     71    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) final;
     72    void scrollAnimationDidEnd(ScrollAnimation&) final;
     73    ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
     74
    6975#if ENABLE(KINETIC_SCROLLING)
    7076    std::unique_ptr<ScrollAnimationKinetic> m_kineticAnimation;
    7177#endif
    7278#if ENABLE(SMOOTH_SCROLLING)
    73     std::unique_ptr<ScrollAnimation> m_smoothAnimation;
     79    std::unique_ptr<ScrollAnimationSmooth> m_smoothAnimation;
    7480#endif
    7581};
  • trunk/Source/WebCore/platform/ScrollAnimation.h

    r268522 r282697  
    11/*
    22 * Copyright (C) 2016 Igalia S.L.
     3 * Copyright (C) 2021 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
    … …  
    2425 */
    2526
    26 #ifndef ScrollAnimation_h
    27 #define ScrollAnimation_h
     27#pragma once
    2828
    2929#include "ScrollTypes.h"
     30#include <wtf/FastMalloc.h>
    3031
    3132namespace WebCore {
    3233
    3334class FloatPoint;
    34 class ScrollableArea;
    35 enum class ScrollClamping : bool;
     35class ScrollAnimation;
    3636
    3737struct ScrollExtents {
    … …  
    4141};
    4242
     43class ScrollAnimationClient {
     44public:
     45    virtual ~ScrollAnimationClient() = default;
     46
     47    virtual void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) = 0;
     48    virtual void scrollAnimationDidEnd(ScrollAnimation&) = 0;
     49    virtual ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) = 0;
     50};
     51
    4352class ScrollAnimation {
    4453    WTF_MAKE_FAST_ALLOCATED;
    4554public:
    46     virtual ~ScrollAnimation() { };
    47     virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float /* step */, float /* multiplier */) { return true; };
    48     virtual void scroll(const FloatPoint&) { };
     55    ScrollAnimation(ScrollAnimationClient& client)
     56        : m_client(client)
     57    { }
     58    virtual ~ScrollAnimation() = default;
     59
     60    virtual bool retargetActiveAnimation(const FloatPoint& newDestination) = 0;
    4961    virtual void stop() = 0;
    50     virtual void updateVisibleLengths() { };
    51     virtual void setCurrentPosition(const FloatPoint&) { };
     62    virtual bool isActive() const = 0;
     63    virtual void updateScrollExtents() { };
     64   
     65    // FIXME: No-op. Need to use this instead of subclasses having timers.
    5266    virtual void serviceAnimation() { };
    53     virtual bool isActive() const = 0;
     67
     68protected:
     69    ScrollAnimationClient& m_client;
    5470};
    5571
    5672} // namespace WebCore
    57 
    58 #endif // ScrollAnimation_h
  • trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp

    r278253 r282697  
    11/*
    22 * Copyright (C) 2016 Igalia S.L.
     3 * Copyright (C) 2021 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
    … …  
    113114}
    114115
    115 ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollExtentsCallback&& scrollExtentsFunction, NotifyPositionChangedCallback&& notifyPositionChangedFunction)
    116     : m_scrollExtentsFunction(WTFMove(scrollExtentsFunction))
    117     , m_notifyPositionChangedFunction(WTFMove(notifyPositionChangedFunction))
     116ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollAnimationClient& client)
     117    : ScrollAnimation(client)
    118118    , m_animationTimer(RunLoop::current(), this, &ScrollAnimationKinetic::animationTimerFired)
    119119{
    … …  
    164164        accumDelta += FloatPoint(scrollEvent.deltaX(), scrollEvent.deltaY());
    165165
     166    // FIXME: It's odd that computeVelocity() has the side effect of clearing history.
    166167    m_scrollHistory.clear();
    167168
    … …  
    169170}
    170171
    171 void ScrollAnimationKinetic::start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll)
     172bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll)
    172173{
    173174    stop();
    … …  
    177178        m_horizontalData = std::nullopt;
    178179        m_verticalData = std::nullopt;
    179         return;
     180        return false;
    180181    }
    181182
    182183    auto delta = deltaToNextFrame();
    183     auto extents = m_scrollExtentsFunction();
     184    auto extents = m_client.scrollExtentsForAnimation(*this);
    184185
    185186    auto accumulateVelocity = [&](double velocity, std::optional<PerAxisData> axisData) -> double {
    … …  
    215216    m_startTime = MonotonicTime::now() - tickTime / 2.;
    216217    animationTimerFired();
     218    return true;
     219}
     220
     221bool ScrollAnimationKinetic::retargetActiveAnimation(const FloatPoint&)
     222{
     223    if (!isActive())
     224        return false;
     225   
     226    // FIXME: Implement retargeting.
     227    return false;
    217228}
    218229
    … …  
    234245    double y = m_verticalData ? m_verticalData.value().position() : m_position.y();
    235246    m_position = FloatPoint(x, y);
    236     m_notifyPositionChangedFunction(FloatPoint(m_position));
     247    m_client.scrollAnimationDidUpdate(*this, FloatPoint(m_position));
    237248}
    238249
  • trunk/Source/WebCore/platform/ScrollAnimationKinetic.h

    r278340 r282697  
    11/*
    22 * Copyright (C) 2016 Igalia S.L.
     3 * Copyright (C) 2021 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
    … …  
    5859
    5960public:
    60     using ScrollExtentsCallback = WTF::Function<ScrollExtents(void)>;
    61     using NotifyPositionChangedCallback = WTF::Function<void(FloatPoint&&)>;
     61    ScrollAnimationKinetic(ScrollAnimationClient&);
     62    virtual ~ScrollAnimationKinetic();
    6263
    63     ScrollAnimationKinetic(ScrollExtentsCallback&&, NotifyPositionChangedCallback&&);
    64     virtual ~ScrollAnimationKinetic();
     64    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
     65
     66    bool retargetActiveAnimation(const FloatPoint& newDestination) final;
     67    void stop() final;
     68    bool isActive() const final;
    6569
    6670    void appendToScrollHistory(const PlatformWheelEvent&);
    6771    void clearScrollHistory();
     72
    6873    FloatPoint computeVelocity();
    69 
    70     void start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
    71     void stop() override;
    72     bool isActive() const override;
    7374
    7475private:
    7576    void animationTimerFired();
    7677    Seconds deltaToNextFrame();
    77 
    78     ScrollExtentsCallback m_scrollExtentsFunction;
    79     NotifyPositionChangedCallback m_notifyPositionChangedFunction;
    8078
    8179    std::optional<PerAxisData> m_horizontalData;
  • trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp

    r280515 r282697  
    11/*
    22 * Copyright (C) 2016 Igalia S.L.
    3  * Copyright (C) 2015 Apple Inc. All rights reserved.
     3 * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
    44 * Copyright (c) 2011, Google Inc. All rights reserved.
    55 *
    … …  
    4343static const double smoothFactorForProgrammaticScroll = 1;
    4444
    45 ScrollAnimationSmooth::PerAxisData::PerAxisData(ScrollbarOrientation orientation, const FloatPoint& position, ScrollExtentsCallback& extentsCallback)
    46 {
    47     auto extents = extentsCallback();
    48     switch (orientation) {
    49     case HorizontalScrollbar:
    50         currentPosition = position.x();
    51         visibleLength = extents.visibleSize.width();
    52         break;
    53     case VerticalScrollbar:
    54         currentPosition = position.y();
    55         visibleLength = extents.visibleSize.height();
    56         break;
    57     }
    58 
    59     desiredPosition = currentPosition;
    60 }
    61 
    62 ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollExtentsCallback&& scrollExtentsFunction, const FloatPoint& position, NotifyPositionChangedCallback&& notifyPositionChangedFunction, NotifyAnimationStoppedCallback&& notifyAnimationStoppedFunction)
    63     : m_scrollExtentsFunction(WTFMove(scrollExtentsFunction))
    64     , m_notifyPositionChangedFunction(WTFMove(notifyPositionChangedFunction))
    65     , m_notifyAnimationStoppedFunction(WTFMove(notifyAnimationStoppedFunction))
    66     , m_horizontalData(HorizontalScrollbar, position, m_scrollExtentsFunction)
    67     , m_verticalData(VerticalScrollbar, position, m_scrollExtentsFunction)
     45ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollAnimationClient& client)
     46    : ScrollAnimation(client)
    6847    , m_animationTimer(RunLoop::current(), this, &ScrollAnimationSmooth::animationTimerFired)
    6948{
    … …  
    7352}
    7453
    75 bool ScrollAnimationSmooth::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
     54ScrollAnimationSmooth::~ScrollAnimationSmooth() = default;
     55
     56bool ScrollAnimationSmooth::startAnimatedScroll(ScrollbarOrientation orientation, ScrollGranularity granularity, const FloatPoint& fromPosition, float step, float multiplier)
    7657{
    7758    float minScrollPosition;
    7859    float maxScrollPosition;
    79     auto extents = m_scrollExtentsFunction();
     60    auto extents = m_client.scrollExtentsForAnimation(*this);
     61    initializeAxesData(extents, fromPosition);
     62
    8063    if (orientation == HorizontalScrollbar) {
    8164        minScrollPosition = extents.minimumScrollPosition.x();
    … …  
    9477}
    9578
    96 void ScrollAnimationSmooth::scroll(const FloatPoint& position)
    97 {
    98     ScrollGranularity granularity = ScrollByPage;
    99     auto extents = m_scrollExtentsFunction();
    100     bool needToScroll = updatePerAxisData(m_horizontalData, granularity, position.x(), extents.minimumScrollPosition.x(), extents.maximumScrollPosition.x(), smoothFactorForProgrammaticScroll);
     79bool ScrollAnimationSmooth::startAnimatedScrollToDestination(const FloatPoint& fromPosition, const FloatPoint& destinationPosition)
     80{
     81    auto extents = m_client.scrollExtentsForAnimation(*this);
     82    initializeAxesData(extents, fromPosition);
     83   
     84    return startOrRetargetAnimation(extents, destinationPosition);
     85}
     86
     87bool ScrollAnimationSmooth::retargetActiveAnimation(const FloatPoint& newDestination)
     88{
     89    if (!isActive())
     90        return false;
     91
     92    auto extents = m_client.scrollExtentsForAnimation(*this);
     93    return startOrRetargetAnimation(extents, newDestination);
     94}
     95
     96bool ScrollAnimationSmooth::startOrRetargetAnimation(const ScrollExtents& extents, const FloatPoint& destinationPosition)
     97{
     98    auto granularity = ScrollByPage;
     99    bool needToScroll = updatePerAxisData(m_horizontalData, granularity, destinationPosition.x(), extents.minimumScrollPosition.x(), extents.maximumScrollPosition.x(), smoothFactorForProgrammaticScroll);
    101100    needToScroll |=
    102         updatePerAxisData(m_verticalData, granularity, position.y(), extents.minimumScrollPosition.y(), extents.maximumScrollPosition.y(), smoothFactorForProgrammaticScroll);
     101        updatePerAxisData(m_verticalData, granularity, destinationPosition.y(), extents.minimumScrollPosition.y(), extents.maximumScrollPosition.y(), smoothFactorForProgrammaticScroll);
    103102    if (needToScroll && !isActive()) {
    104         m_startTime = m_horizontalData.startTime;
     103        m_startTime = m_verticalData.startTime;
    105104        animationTimerFired();
    106105    }
    107 };
     106    return needToScroll;
     107}
    108108
    109109void ScrollAnimationSmooth::stop()
    110110{
    111111    m_animationTimer.stop();
    112     m_notifyAnimationStoppedFunction();
    113 }
    114 
    115 void ScrollAnimationSmooth::updateVisibleLengths()
    116 {
    117     auto extents = m_scrollExtentsFunction();
     112    m_client.scrollAnimationDidEnd(*this);
     113}
     114
     115void ScrollAnimationSmooth::updateScrollExtents()
     116{
     117    auto extents = m_client.scrollExtentsForAnimation(*this);
    118118    m_horizontalData.visibleLength = extents.visibleSize.width();
    119119    m_verticalData.visibleLength = extents.visibleSize.height();
    120120}
    121121
    122 void ScrollAnimationSmooth::setCurrentPosition(const FloatPoint& position)
    123 {
    124     stop();
    125     m_horizontalData = PerAxisData(position.x(), m_horizontalData.visibleLength);
    126     m_verticalData = PerAxisData(position.y(), m_verticalData.visibleLength);
    127 }
    128 
    129 ScrollAnimationSmooth::~ScrollAnimationSmooth() = default;
     122void ScrollAnimationSmooth::initializeAxesData(const ScrollExtents& extents, const FloatPoint& startPosition)
     123{
     124    m_horizontalData = PerAxisData(startPosition.x(), extents.visibleSize.width());
     125    m_verticalData = PerAxisData(startPosition.y(), extents.visibleSize.height());
     126}
    130127
    131128static inline double curveAt(ScrollAnimationSmooth::Curve curve, double t)
    … …  
    249246}
    250247
    251 static inline void getAnimationParametersForGranularity(ScrollGranularity granularity, Seconds& animationTime, Seconds& repeatMinimumSustainTime, Seconds& attackTime, Seconds& releaseTime, ScrollAnimationSmooth::Curve& coastTimeCurve, Seconds& maximumCoastTime)
     248static inline void getAnimationParametersForGranularity(ScrollGranularity granularity, Seconds& animationDuration, Seconds& repeatMinimumSustainTime, Seconds& attackDuration, Seconds& releaseDuration, ScrollAnimationSmooth::Curve& coastTimeCurve, Seconds& maximumCoastTime)
    252249{
    253250    switch (granularity) {
    254251    case ScrollByDocument:
    255         animationTime = tickTime * 10;
     252        animationDuration = tickTime * 10;
    256253        repeatMinimumSustainTime = tickTime * 10;
    257         attackTime = tickTime * 10;
    258         releaseTime = tickTime * 10;
     254        attackDuration = tickTime * 10;
     255        releaseDuration = tickTime * 10;
    259256        coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
    260257        maximumCoastTime = 1_s;
    261258        break;
    262259    case ScrollByLine:
    263         animationTime = tickTime * 10;
     260        animationDuration = tickTime * 10;
    264261        repeatMinimumSustainTime = tickTime * 7;
    265         attackTime = tickTime * 3;
    266         releaseTime = tickTime * 3;
     262        attackDuration = tickTime * 3;
     263        releaseDuration = tickTime * 3;
    267264        coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
    268265        maximumCoastTime = 1_s;
    269266        break;
    270267    case ScrollByPage:
    271         animationTime = tickTime * 15;
     268        animationDuration = tickTime * 15;
    272269        repeatMinimumSustainTime = tickTime * 10;
    273         attackTime = tickTime * 5;
    274         releaseTime = tickTime * 5;
     270        attackDuration = tickTime * 5;
     271        releaseDuration = tickTime * 5;
    275272        coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
    276273        maximumCoastTime = 1_s;
    277274        break;
    278275    case ScrollByPixel:
    279         animationTime = tickTime * 11;
     276        animationDuration = tickTime * 11;
    280277        repeatMinimumSustainTime = tickTime * 2;
    281         attackTime = tickTime * 3;
    282         releaseTime = tickTime * 3;
     278        attackDuration = tickTime * 3;
     279        releaseDuration = tickTime * 3;
    283280        coastTimeCurve = ScrollAnimationSmooth::Curve::Quadratic;
    284281        maximumCoastTime = 1250_ms;
    … …  
    300297        return false;
    301298
    302     Seconds animationTime, repeatMinimumSustainTime, attackTime, releaseTime, maximumCoastTime;
     299    Seconds animationDuration, repeatMinimumSustainTime, attackDuration, releaseDuration, maximumCoastTime;
    303300    Curve coastTimeCurve;
    304     getAnimationParametersForGranularity(granularity, animationTime, repeatMinimumSustainTime, attackTime, releaseTime, coastTimeCurve, maximumCoastTime);
    305 
    306     animationTime *= smoothFactor;
     301    getAnimationParametersForGranularity(granularity, animationDuration, repeatMinimumSustainTime, attackDuration, releaseDuration, coastTimeCurve, maximumCoastTime);
     302
     303    animationDuration *= smoothFactor;
    307304    repeatMinimumSustainTime *= smoothFactor;
    308     attackTime *= smoothFactor;
    309     releaseTime *= smoothFactor;
     305    attackDuration *= smoothFactor;
     306    releaseDuration *= smoothFactor;
    310307    maximumCoastTime *= smoothFactor;
    311308
    312309    data.desiredPosition = newPosition;
    313310    if (!data.startTime)
    314         data.attackTime = attackTime;
    315     data.animationTime = animationTime;
    316     data.releaseTime = releaseTime;
     311        data.attackDuration = attackDuration;
     312    data.animationDuration = animationDuration;
     313    data.releaseDuration = releaseDuration;
    317314
    318315    // Prioritize our way out of over constraint.
    319     if (data.attackTime + data.releaseTime > data.animationTime) {
    320         if (data.releaseTime > data.animationTime)
    321             data.releaseTime = data.animationTime;
    322         data.attackTime = data.animationTime - data.releaseTime;
     316    if (data.attackDuration + data.releaseDuration > data.animationDuration) {
     317        if (data.releaseDuration > data.animationDuration)
     318            data.releaseDuration = data.animationDuration;
     319        data.attackDuration = data.animationDuration - data.releaseDuration;
    323320    }
    324321
    … …  
    334331    double attackAreaLeft = 0;
    335332    Seconds deltaTime = data.lastAnimationTime - data.startTime;
    336     Seconds attackTimeLeft = std::max(0_s, data.attackTime - deltaTime);
    337     Seconds timeLeft = data.animationTime - deltaTime;
    338     Seconds minTimeLeft = data.releaseTime + std::min(repeatMinimumSustainTime, data.animationTime - data.releaseTime - attackTimeLeft);
     333    Seconds attackTimeLeft = std::max(0_s, data.attackDuration - deltaTime);
     334    Seconds timeLeft = data.animationDuration - deltaTime;
     335    Seconds minTimeLeft = data.releaseDuration + std::min(repeatMinimumSustainTime, data.animationDuration - data.releaseDuration - attackTimeLeft);
    339336    if (timeLeft < minTimeLeft) {
    340         data.animationTime = deltaTime + minTimeLeft;
     337        data.animationDuration = deltaTime + minTimeLeft;
    341338        timeLeft = minTimeLeft;
    342339    }
    343340
    344     if (maximumCoastTime > (repeatMinimumSustainTime + releaseTime)) {
     341    if (maximumCoastTime > (repeatMinimumSustainTime + releaseDuration)) {
    345342        double targetMaxCoastVelocity = data.visibleLength * .25 * frameRate;
    346343        // This needs to be as minimal as possible while not being intrusive to page up/down.
    … …  
    355352
    356353            if (Seconds additionalTime = std::max(0_s, coastMinTimeLeft - minTimeLeft)) {
    357                 Seconds additionalReleaseTime = std::min(additionalTime, additionalTime * (releaseTime / (releaseTime + repeatMinimumSustainTime)));
    358                 data.releaseTime = releaseTime + additionalReleaseTime;
    359                 data.animationTime = deltaTime + coastMinTimeLeft;
     354                Seconds additionalReleaseTime = std::min(additionalTime, additionalTime * (releaseDuration / (releaseDuration + repeatMinimumSustainTime)));
     355                data.releaseDuration = releaseDuration + additionalReleaseTime;
     356                data.animationDuration = deltaTime + coastMinTimeLeft;
    360357                timeLeft = coastMinTimeLeft;
    361358            }
    … …  
    363360    }
    364361
    365     Seconds releaseTimeLeft = std::min(timeLeft, data.releaseTime);
     362    Seconds releaseTimeLeft = std::min(timeLeft, data.releaseDuration);
    366363    Seconds sustainTimeLeft = std::max(0_s, timeLeft - releaseTimeLeft - attackTimeLeft);
    367364    if (attackTimeLeft) {
    368         double attackSpot = deltaTime / data.attackTime;
    369         attackAreaLeft = attackArea(Curve::Cubic, attackSpot, 1) * data.attackTime.value();
    370     }
    371 
    372     double releaseSpot = (data.releaseTime - releaseTimeLeft) / data.releaseTime;
    373     double releaseAreaLeft = releaseArea(Curve::Cubic, releaseSpot, 1) * data.releaseTime.value();
     365        double attackSpot = deltaTime / data.attackDuration;
     366        attackAreaLeft = attackArea(Curve::Cubic, attackSpot, 1) * data.attackDuration.value();
     367    }
     368
     369    double releaseSpot = (data.releaseDuration - releaseTimeLeft) / data.releaseDuration;
     370    double releaseAreaLeft = releaseArea(Curve::Cubic, releaseSpot, 1) * data.releaseDuration.value();
    374371
    375372    data.desiredVelocity = remainingDelta / (attackAreaLeft + sustainTimeLeft.value() + releaseAreaLeft);
    … …  
    378375        data.attackPosition = data.startPosition + data.desiredVelocity * attackAreaLeft;
    379376    else
    380         data.attackPosition = data.releasePosition - (data.animationTime - data.releaseTime - data.attackTime).value() * data.desiredVelocity;
     377        data.attackPosition = data.releasePosition - (data.animationDuration - data.releaseDuration - data.attackDuration).value() * data.desiredVelocity;
    381378
    382379    if (sustainTimeLeft) {
    … …  
    402399    double newPosition = data.currentPosition;
    403400
    404     if (deltaTime > data.animationTime) {
     401    if (deltaTime > data.animationDuration) {
    405402        data = PerAxisData(data.desiredPosition, data.visibleLength);
    406403        return false;
    407404    }
    408     if (deltaTime < data.attackTime)
    409         newPosition = attackCurve(Curve::Cubic, deltaTime.value(), data.attackTime.value(), data.startPosition, data.attackPosition);
    410     else if (deltaTime < (data.animationTime - data.releaseTime))
    411         newPosition = data.attackPosition + (deltaTime - data.attackTime).value() * data.desiredVelocity;
     405    if (deltaTime < data.attackDuration)
     406        newPosition = attackCurve(Curve::Cubic, deltaTime.value(), data.attackDuration.value(), data.startPosition, data.attackPosition);
     407    else if (deltaTime < (data.animationDuration - data.releaseDuration))
     408        newPosition = data.attackPosition + (deltaTime - data.attackDuration).value() * data.desiredVelocity;
    412409    else {
    413410        // release is based on targeting the exact final position.
    414         Seconds releaseDeltaT = deltaTime - (data.animationTime - data.releaseTime);
    415         newPosition = releaseCurve(Curve::Cubic, releaseDeltaT.value(), data.releaseTime.value(), data.releasePosition, data.desiredPosition);
     411        Seconds releaseDeltaT = deltaTime - (data.animationDuration - data.releaseDuration);
     412        newPosition = releaseCurve(Curve::Cubic, releaseDeltaT.value(), data.releaseDuration.value(), data.releasePosition, data.desiredPosition);
    416413    }
    417414
    … …  
    438435    if (continueAnimation)
    439436        startNextTimer(std::max(minimumTimerInterval, deltaToNextFrame));
    440     else
    441         m_notifyAnimationStoppedFunction();
    442 
    443     m_notifyPositionChangedFunction(FloatPoint(m_horizontalData.currentPosition, m_verticalData.currentPosition));
     437
     438    m_client.scrollAnimationDidUpdate(*this, { m_horizontalData.currentPosition, m_verticalData.currentPosition });
     439    if (!continueAnimation)
     440        m_client.scrollAnimationDidEnd(*this);
    444441}
    445442
  • trunk/Source/WebCore/platform/ScrollAnimationSmooth.h

    r280515 r282697  
    11/*
    22 * Copyright (C) 2016 Igalia S.L.
     3 * Copyright (C) 2021 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
    … …  
    3334
    3435class FloatPoint;
    35 class ScrollableArea;
    3636enum class ScrollClamping : bool;
    3737
    3838class ScrollAnimationSmooth final: public ScrollAnimation {
    3939public:
    40     using ScrollExtentsCallback = WTF::Function<ScrollExtents(void)>;
    41     using NotifyPositionChangedCallback = WTF::Function<void(FloatPoint&&)>;
    42     using NotifyAnimationStoppedCallback = WTF::Function<void(void)>;
    43 
    44     ScrollAnimationSmooth(ScrollExtentsCallback&&, const FloatPoint& position, NotifyPositionChangedCallback&&, NotifyAnimationStoppedCallback&&);
     40    ScrollAnimationSmooth(ScrollAnimationClient&);
    4541    virtual ~ScrollAnimationSmooth();
    4642
    … …  
    5349    };
    5450
     51    bool startAnimatedScroll(ScrollbarOrientation, ScrollGranularity, const FloatPoint& fromPosition, float step, float multiplier);
     52    bool startAnimatedScrollToDestination(const FloatPoint& fromPosition, const FloatPoint& destinationPosition);
     53
     54    bool retargetActiveAnimation(const FloatPoint& newDestination) final;
     55    void stop() final;
     56    void updateScrollExtents() final;
     57    bool isActive() const final;
     58
    5559private:
    56     bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;
    57     void scroll(const FloatPoint&) override;
    58     void stop() override;
    59     void updateVisibleLengths() override;
    60     void setCurrentPosition(const FloatPoint&) override;
    61     bool isActive() const override;
    62 
    6360    struct PerAxisData {
    64         PerAxisData() = delete;
    65 
    66         PerAxisData(ScrollbarOrientation, const FloatPoint& position, ScrollExtentsCallback&);
    67 
     61        PerAxisData() = default;
    6862        PerAxisData(float position, int length)
    6963            : currentPosition(position)
    … …  
    8377        double startVelocity { 0 };
    8478
    85         Seconds animationTime;
     79        Seconds animationDuration;
    8680        MonotonicTime lastAnimationTime;
    8781
    8882        double attackPosition { 0 };
    89         Seconds attackTime;
     83        Seconds attackDuration;
    9084        Curve attackCurve { Curve::Quadratic };
    9185
    9286        double releasePosition { 0 };
    93         Seconds releaseTime;
     87        Seconds releaseDuration;
    9488        Curve releaseCurve { Curve::Quadratic };
    9589
    … …  
    9791    };
    9892
     93    bool startOrRetargetAnimation(const ScrollExtents&, const FloatPoint& destination);
     94
    9995    bool updatePerAxisData(PerAxisData&, ScrollGranularity, float newPosition, float minScrollPosition, float maxScrollPosition, double smoothFactor = 1);
    10096    bool animateScroll(PerAxisData&, MonotonicTime currentTime);
     97   
     98    void initializeAxesData(const ScrollExtents&, const FloatPoint& startPosition);
    10199
    102100    void requestAnimationTimerFired();
    … …  
    104102    void animationTimerFired();
    105103
    106     ScrollExtentsCallback m_scrollExtentsFunction;
    107     NotifyPositionChangedCallback m_notifyPositionChangedFunction;
    108     NotifyAnimationStoppedCallback m_notifyAnimationStoppedFunction;
    109 
    110104    PerAxisData m_horizontalData;
    111105    PerAxisData m_verticalData;
    112106
    113107    MonotonicTime m_startTime;
     108    // FIXME: Should not have timer here, and instead use serviceAnimation().
    114109    RunLoop::Timer<ScrollAnimationSmooth> m_animationTimer;
    115110};
  • trunk/Source/WebCore/platform/ScrollAnimator.cpp

    r282480 r282697  
    5555    , m_scrollController(*this)
    5656    , m_scrollControllerAnimationTimer(*this, &ScrollAnimator::scrollControllerAnimationTimerFired)
    57     , m_scrollAnimation(makeUnique<ScrollAnimationSmooth>(
    58         [this]() -> ScrollExtents {
    59             return { m_scrollableArea.minimumScrollPosition(), m_scrollableArea.maximumScrollPosition(), m_scrollableArea.visibleSize() };
    60         },
    61         m_currentPosition,
    62         [this](FloatPoint&& position) {
    63             FloatSize delta = position - m_currentPosition;
    64             m_currentPosition = WTFMove(position);
    65             notifyPositionChanged(delta);
    66             updateActiveScrollSnapIndexForOffset();
    67         },
    68         [this] {
    69             m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
    70         }))
     57    , m_scrollAnimation(makeUnique<ScrollAnimationSmooth>(*this))
    7158    , m_keyboardScrollingAnimator(makeUnique<KeyboardScrollingAnimator>(*this, m_scrollController))
    7259{
    … …  
    10087
    10188#if ENABLE(SMOOTH_SCROLLING) && !PLATFORM(IOS_FAMILY)
    102     if (m_scrollableArea.scrollAnimatorEnabled() && !behavior.contains(ScrollBehavior::NeverAnimate)) {
    103         if (!m_scrollAnimation->isActive())
    104             m_scrollAnimation->setCurrentPosition(m_currentPosition);
    105         return m_scrollAnimation->scroll(orientation, granularity, step, multiplier);
    106     }
     89    if (m_scrollableArea.scrollAnimatorEnabled() && !behavior.contains(ScrollBehavior::NeverAnimate))
     90        return m_scrollAnimation->startAnimatedScroll(orientation, granularity, m_currentPosition, step, multiplier);
    10791#endif
    10892
    … …  
    125109        return false;
    126110
    127     m_scrollAnimation->setCurrentPosition(adjustedPosition);
     111    m_scrollAnimation->stop();
    128112    m_currentPosition = adjustedPosition;
    129113    notifyPositionChanged(adjustedPosition - currentPosition);
    … …  
    143127        return false;
    144128
    145     m_scrollAnimation->setCurrentPosition(m_currentPosition);
    146     m_scrollAnimation->scroll(newPosition);
     129    m_scrollAnimation->startAnimatedScrollToDestination(m_currentPosition, newPosition);
    147130    scrollableArea().setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
    148131    return true;
    … …  
    153136    ASSERT(scrollableArea().currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation);
    154137    ASSERT(m_scrollAnimation->isActive());
    155     m_scrollAnimation->scroll(newPosition);
     138    m_scrollAnimation->retargetActiveAnimation(newPosition);
    156139}
    157140
    … …  
    376359void ScrollAnimator::contentsResized() const
    377360{
    378     m_scrollAnimation->updateVisibleLengths();
     361    m_scrollAnimation->updateScrollExtents();
    379362}
    380363
    381364void ScrollAnimator::willEndLiveResize()
    382365{
    383     m_scrollAnimation->updateVisibleLengths();
     366    m_scrollAnimation->updateScrollExtents();
    384367}
    385368
    386369void ScrollAnimator::didAddVerticalScrollbar(Scrollbar*)
    387370{
    388     m_scrollAnimation->updateVisibleLengths();
     371    m_scrollAnimation->updateScrollExtents();
    389372}
    390373
    391374void ScrollAnimator::didAddHorizontalScrollbar(Scrollbar*)
    392375{
    393     m_scrollAnimation->updateVisibleLengths();
     376    m_scrollAnimation->updateScrollExtents();
    394377}
    395378
    … …  
    423406}
    424407
     408void ScrollAnimator::scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& position)
     409{
     410    FloatSize delta = position - m_currentPosition;
     411    m_currentPosition = position;
     412    notifyPositionChanged(delta);
     413    updateActiveScrollSnapIndexForOffset();
     414}
     415
     416void ScrollAnimator::scrollAnimationDidEnd(ScrollAnimation&)
     417{
     418    m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
     419}
     420
     421ScrollExtents ScrollAnimator::scrollExtentsForAnimation(ScrollAnimation&)
     422{
     423    return {
     424        m_scrollableArea.minimumScrollPosition(),
     425        m_scrollableArea.maximumScrollPosition(),
     426        m_scrollableArea.visibleSize()
     427    };
     428}
     429
    425430
    426431} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollAnimator.h

    r282480 r282697  
    3434#include "FloatPoint.h"
    3535#include "PlatformWheelEvent.h"
     36#include "ScrollAnimation.h"
    3637#include "ScrollingEffectsController.h"
    3738#include "Timer.h"
    … …  
    4546class KeyboardScrollingAnimator;
    4647class PlatformTouchEvent;
    47 class ScrollAnimation;
     48class ScrollAnimationSmooth;
    4849class ScrollableArea;
    4950class Scrollbar;
    … …  
    5253class ScrollingEffectsControllerTimer;
    5354
    54 class ScrollAnimator : private ScrollingEffectsControllerClient {
     55class ScrollAnimator : private ScrollingEffectsControllerClient, public ScrollAnimationClient {
    5556    WTF_MAKE_FAST_ALLOCATED;
    5657public:
    … …  
    134135    virtual String verticalScrollbarStateForTesting() const { return emptyString(); }
    135136
     137    // ScrollAnimationClient
     138    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) override;
     139    void scrollAnimationDidEnd(ScrollAnimation&) override;
     140    ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) override;
     141
    136142    void setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&& testMonitor) { m_wheelEventTestMonitor = testMonitor; }
    137143
    … …  
    180186    FloatPoint m_currentPosition;
    181187
    182     std::unique_ptr<ScrollAnimation> m_scrollAnimation;
     188    std::unique_ptr<ScrollAnimationSmooth> m_scrollAnimation;
    183189    std::unique_ptr<KeyboardScrollingAnimator> m_keyboardScrollingAnimator;
    184190};
  • trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp

    r277539 r282697  
    4949ScrollAnimatorGeneric::ScrollAnimatorGeneric(ScrollableArea& scrollableArea)
    5050    : ScrollAnimator(scrollableArea)
     51    , m_kineticAnimation(makeUnique<ScrollAnimationKinetic>(*this))
    5152    , m_overlayScrollbarAnimationTimer(*this, &ScrollAnimatorGeneric::overlayScrollbarAnimationTimerFired)
    5253{
    53     m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(
    54         [this]() -> ScrollExtents {
    55             return { m_scrollableArea.minimumScrollPosition(), m_scrollableArea.maximumScrollPosition(), m_scrollableArea.visibleSize() };
    56         },
    57         [this](FloatPoint&& position) {
    58             m_scrollAnimation->setCurrentPosition(position);
    59             updatePosition(WTFMove(position));
    60         });
    6154}
    6255
    … …  
    7770
    7871    if (event.isEndOfNonMomentumScroll()) {
    79         m_kineticAnimation->start(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
     72        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
    8073        return true;
    8174    }
    8275    if (event.isTransitioningToMomentumScroll()) {
    8376        m_kineticAnimation->clearScrollHistory();
    84         m_kineticAnimation->start(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
     77        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
    8578        return true;
    8679    }
    … …  
    9083}
    9184
    92 void ScrollAnimatorGeneric::updatePosition(FloatPoint&& position)
     85void ScrollAnimatorGeneric::updatePosition(const FloatPoint& position)
    9386{
    9487    FloatSize delta = position - m_currentPosition;
    95     m_currentPosition = WTFMove(position);
     88    m_currentPosition = position;
    9689    notifyPositionChanged(delta);
    9790    updateActiveScrollSnapIndexForOffset();
    … …  
    289282}
    290283
     284// FIXME: Can we just use the base class implementation?
     285void ScrollAnimatorGeneric::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
     286{
     287    if (&animation == m_kineticAnimation.get()) {
     288        // FIXME: Clarify how animations interact. There should never be more than one active at a time.
     289        m_scrollAnimation->stop();
     290        updatePosition(position);
     291        return;
     292    }
     293
     294    ScrollAnimator::scrollAnimationDidUpdate(animation, position);
     295}
     296
    291297} // namespace WebCore
    292298
  • trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h

    r276299 r282697  
    6262    void lockOverlayScrollbarStateToHidden(bool) override;
    6363
    64     void updatePosition(FloatPoint&&);
     64    // ScrollAnimationClient
     65    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) override;
     66
     67    void updatePosition(const FloatPoint&);
    6568
    6669    void overlayScrollbarAnimationTimerFired();
Note: See TracChangeset for help on using the changeset viewer.