15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2011, Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollAnimatorNone.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <algorithm> 36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollableArea.h" 377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/CurrentTime.h" 387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/PassOwnPtr.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/TraceEvent.h" 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double kFrameRate = 60; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double kTickTime = 1 / kFrameRate; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double kMinimumTimerInterval = .001; 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (scrollableArea && scrollableArea->scrollAnimatorEnabled()) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptPtr(new ScrollAnimatorNone(scrollableArea)); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptPtr(new ScrollAnimator(scrollableArea)); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::Parameters::Parameters() 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_isEnabled(false) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::Parameters::Parameters(bool isEnabled, double animationTime, double repeatMinimumSustainTime, Curve attackCurve, double attackTime, Curve releaseCurve, double releaseTime, Curve coastTimeCurve, double maximumCoastTime) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_isEnabled(isEnabled) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_animationTime(animationTime) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_repeatMinimumSustainTime(repeatMinimumSustainTime) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_attackCurve(attackCurve) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_attackTime(attackTime) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_releaseCurve(releaseCurve) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_releaseTime(releaseTime) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_coastTimeCurve(coastTimeCurve) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_maximumCoastTime(maximumCoastTime) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::curveAt(Curve curve, double t) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (curve) { 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Linear: 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Quadratic: 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Cubic: 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t * t; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Quartic: 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t * t * t; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Bounce: 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Time base is chosen to keep the bounce points simpler: 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1 (half bounce coming in) + 1 + .5 + .25 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kTimeBase = 2.75; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kTimeBaseSquared = kTimeBase * kTimeBase; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 1 / kTimeBase) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kTimeBaseSquared * t * t; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 2 / kTimeBase) { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Invert a [-.5,.5] quadratic parabola, center it in [1,2]. 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double t1 = t - 1.5 / kTimeBase; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kParabolaAtEdge = 1 - .5 * .5; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kTimeBaseSquared * t1 * t1 + kParabolaAtEdge; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 2.5 / kTimeBase) { 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Invert a [-.25,.25] quadratic parabola, center it in [2,2.5]. 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double t2 = t - 2.25 / kTimeBase; 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kParabolaAtEdge = 1 - .25 * .25; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kTimeBaseSquared * t2 * t2 + kParabolaAtEdge; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Invert a [-.125,.125] quadratic parabola, center it in [2.5,2.75]. 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kParabolaAtEdge = 1 - .125 * .125; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) t -= 2.625 / kTimeBase; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kTimeBaseSquared * t * t + kParabolaAtEdge; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::attackCurve(Curve curve, double deltaTime, double curveT, double startPosition, double attackPosition) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double t = deltaTime / curveT; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double positionFactor = curveAt(curve, t); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return startPosition + positionFactor * (attackPosition - startPosition); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::releaseCurve(Curve curve, double deltaTime, double curveT, double releasePosition, double desiredPosition) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double t = deltaTime / curveT; 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double positionFactor = 1 - curveAt(curve, 1 - t); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return releasePosition + (positionFactor * (desiredPosition - releasePosition)); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::coastCurve(Curve curve, double factor) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 1 - curveAt(curve, 1 - factor); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::curveIntegralAt(Curve curve, double t) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (curve) { 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Linear: 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t / 2; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Quadratic: 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t * t / 3; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Cubic: 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t * t * t / 4; 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Quartic: 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return t * t * t * t * t / 5; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Bounce: 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kTimeBase = 2.75; 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kTimeBaseSquared = kTimeBase * kTimeBase; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kTimeBaseSquaredOverThree = kTimeBaseSquared / 3; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double area; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double t1 = min(t, 1 / kTimeBase); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) area = kTimeBaseSquaredOverThree * t1 * t1 * t1; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 1 / kTimeBase) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return area; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) t1 = min(t - 1 / kTimeBase, 1 / kTimeBase); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The integral of kTimeBaseSquared * (t1 - .5 / kTimeBase) * (t1 - .5 / kTimeBase) + kParabolaAtEdge 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kSecondInnerOffset = kTimeBaseSquared * .5 / kTimeBase; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kSecondInnerOffset) + 1); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) area += bounceArea; 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 2 / kTimeBase) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return area; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) t1 = min(t - 2 / kTimeBase, 0.5 / kTimeBase); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The integral of kTimeBaseSquared * (t1 - .25 / kTimeBase) * (t1 - .25 / kTimeBase) + kParabolaAtEdge 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kThirdInnerOffset = kTimeBaseSquared * .25 / kTimeBase; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kThirdInnerOffset) + 1); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) area += bounceArea; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (t < 2.5 / kTimeBase) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return area; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) t1 = t - 2.5 / kTimeBase; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The integral of kTimeBaseSquared * (t1 - .125 / kTimeBase) * (t1 - .125 / kTimeBase) + kParabolaAtEdge 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const double kFourthInnerOffset = kTimeBaseSquared * .125 / kTimeBase; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kFourthInnerOffset) + 1); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) area += bounceArea; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return area; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::attackArea(Curve curve, double startT, double endT) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double startValue = curveIntegralAt(curve, startT); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double endValue = curveIntegralAt(curve, endT); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return endValue - startValue; 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double ScrollAnimatorNone::PerAxisData::releaseArea(Curve curve, double startT, double endT) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double startValue = curveIntegralAt(curve, 1 - endT); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double endValue = curveIntegralAt(curve, 1 - startT); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return endValue - startValue; 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float* currentPosition, int visibleLength) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_currentPosition(currentPosition) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_visibleLength(visibleLength) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reset(); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::PerAxisData::reset() 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_currentVelocity = 0; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredPosition = 0; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredVelocity = 0; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startPosition = 0; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startTime = 0; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startVelocity = 0; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationTime = 0; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastAnimationTime = 0; 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackPosition = 0; 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackTime = 0; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackCurve = Quadratic; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releasePosition = 0; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseTime = 0; 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseCurve = Quadratic; 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 22609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool ScrollAnimatorNone::PerAxisData::updateDataFromParameters(float step, float delta, float scrollableSize, double currentTime, Parameters* parameters) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 22809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float pixelDelta = step * delta; 22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!m_startTime || !pixelDelta || (pixelDelta < 0) != (m_desiredPosition - *m_currentPosition < 0)) { 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredPosition = *m_currentPosition; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startTime = 0; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float newPosition = m_desiredPosition + pixelDelta; 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newPosition < 0 || newPosition > scrollableSize) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newPosition = max(min(newPosition, scrollableSize), 0.0f); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newPosition == m_desiredPosition) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredPosition = newPosition; 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_startTime) { 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackTime = parameters->m_attackTime; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackCurve = parameters->m_attackCurve; 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationTime = parameters->m_animationTime; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseTime = parameters->m_releaseTime; 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseCurve = parameters->m_releaseCurve; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Prioritize our way out of over constraint. 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_attackTime + m_releaseTime > m_animationTime) { 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_releaseTime > m_animationTime) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseTime = m_animationTime; 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackTime = m_animationTime - m_releaseTime; 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_startTime) { 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: This should be the time from the event that got us here. 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startTime = currentTime - kTickTime / 2; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startPosition = *m_currentPosition; 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastAnimationTime = m_startTime; 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startVelocity = m_currentVelocity; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double remainingDelta = m_desiredPosition - *m_currentPosition; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double attackAreaLeft = 0; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double deltaTime = m_lastAnimationTime - m_startTime; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double attackTimeLeft = max(0., m_attackTime - deltaTime); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double timeLeft = m_animationTime - deltaTime; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double minTimeLeft = m_releaseTime + min(parameters->m_repeatMinimumSustainTime, m_animationTime - m_releaseTime - attackTimeLeft); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (timeLeft < minTimeLeft) { 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationTime = deltaTime + minTimeLeft; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timeLeft = minTimeLeft; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (parameters->m_maximumCoastTime > (parameters->m_repeatMinimumSustainTime + parameters->m_releaseTime)) { 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double targetMaxCoastVelocity = m_visibleLength * .25 * kFrameRate; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This needs to be as minimal as possible while not being intrusive to page up/down. 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double minCoastDelta = m_visibleLength; 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fabs(remainingDelta) > minCoastDelta) { 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double maxCoastDelta = parameters->m_maximumCoastTime * targetMaxCoastVelocity; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double coastFactor = min(1., (fabs(remainingDelta) - minCoastDelta) / (maxCoastDelta - minCoastDelta)); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We could play with the curve here - linear seems a little soft. Initial testing makes me want to feed into the sustain time more aggressively. 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double coastMinTimeLeft = min(parameters->m_maximumCoastTime, minTimeLeft + coastCurve(parameters->m_coastTimeCurve, coastFactor) * (parameters->m_maximumCoastTime - minTimeLeft)); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double additionalTime = max(0., coastMinTimeLeft - minTimeLeft); 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (additionalTime) { 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double additionalReleaseTime = min(additionalTime, parameters->m_releaseTime / (parameters->m_releaseTime + parameters->m_repeatMinimumSustainTime) * additionalTime); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releaseTime = parameters->m_releaseTime + additionalReleaseTime; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationTime = deltaTime + coastMinTimeLeft; 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timeLeft = coastMinTimeLeft; 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double releaseTimeLeft = min(timeLeft, m_releaseTime); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double sustainTimeLeft = max(0., timeLeft - releaseTimeLeft - attackTimeLeft); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attackTimeLeft) { 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double attackSpot = deltaTime / m_attackTime; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) attackAreaLeft = attackArea(m_attackCurve, attackSpot, 1) * m_attackTime; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double releaseSpot = (m_releaseTime - releaseTimeLeft) / m_releaseTime; 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double releaseAreaLeft = releaseArea(m_releaseCurve, releaseSpot, 1) * m_releaseTime; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredVelocity = remainingDelta / (attackAreaLeft + sustainTimeLeft + releaseAreaLeft); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_releasePosition = m_desiredPosition - m_desiredVelocity * releaseAreaLeft; 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attackAreaLeft) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackPosition = m_startPosition + m_desiredVelocity * attackAreaLeft; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attackPosition = m_releasePosition - (m_animationTime - m_releaseTime - m_attackTime) * m_desiredVelocity; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sustainTimeLeft) { 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double roundOff = m_releasePosition - ((attackAreaLeft ? m_attackPosition : *m_currentPosition) + m_desiredVelocity * sustainTimeLeft); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_desiredVelocity += roundOff / sustainTimeLeft; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 32710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochinline double ScrollAnimatorNone::PerAxisData::newScrollAnimationPosition(double deltaTime) 32810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch{ 32910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (deltaTime < m_attackTime) 33010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return attackCurve(m_attackCurve, deltaTime, m_attackTime, m_startPosition, m_attackPosition); 33110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (deltaTime < (m_animationTime - m_releaseTime)) 33210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_attackPosition + (deltaTime - m_attackTime) * m_desiredVelocity; 33310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch // release is based on targeting the exact final position. 33410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch double releaseDeltaT = deltaTime - (m_animationTime - m_releaseTime); 33510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return releaseCurve(m_releaseCurve, releaseDeltaT, m_releaseTime, m_releasePosition, m_desiredPosition); 33610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch} 33710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: Add in jank detection trace events into this function. 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime) 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double lastScrollInterval = currentTime - m_lastAnimationTime; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastScrollInterval < kMinimumTimerInterval) 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastAnimationTime = currentTime; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double deltaTime = currentTime - m_startTime; 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (deltaTime > m_animationTime) { 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *m_currentPosition = m_desiredPosition; 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reset(); 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 35410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch double newPosition = newScrollAnimationPosition(deltaTime); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Normalize velocity to a per second amount. Could be used to check for jank. 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastScrollInterval > 0) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_currentVelocity = (newPosition - *m_currentPosition) / lastScrollInterval; 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *m_currentPosition = newPosition; 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::PerAxisData::updateVisibleLength(int visibleLength) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_visibleLength = visibleLength; 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::ScrollAnimatorNone(ScrollableArea* scrollableArea) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : ScrollAnimator(scrollableArea) 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_horizontalData(this, &m_currentPosX, scrollableArea->visibleWidth()) 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_verticalData(this, &m_currentPosY, scrollableArea->visibleHeight()) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_startTime(0) 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_animationActive(false) 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::~ScrollAnimatorNone() 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopAnimationTimerIfNeeded(); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScrollAnimatorNone::Parameters ScrollAnimatorNone::parametersForScrollGranularity(ScrollGranularity granularity) const 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (granularity) { 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByDocument: 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Parameters(true, 20 * kTickTime, 10 * kTickTime, Cubic, 10 * kTickTime, Cubic, 10 * kTickTime, Linear, 1); 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByLine: 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Parameters(true, 10 * kTickTime, 7 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Linear, 1); 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByPage: 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Parameters(true, 15 * kTickTime, 10 * kTickTime, Cubic, 5 * kTickTime, Cubic, 5 * kTickTime, Linear, 1); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByPixel: 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Parameters(true, 11 * kTickTime, 2 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Quadratic, 1.25); 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Parameters(); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_scrollableArea->scrollAnimatorEnabled()) 40209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ScrollAnimator::scroll(orientation, granularity, step, delta); 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TRACE_EVENT0("webkit", "ScrollAnimatorNone::scroll"); 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: get the type passed in. MouseWheel could also be by line, but should still have different 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // animation parameters than the keyboard. 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Parameters parameters; 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (granularity) { 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByDocument: 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByLine: 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByPage: 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByPixel: 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parameters = parametersForScrollGranularity(granularity); 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollByPrecisePixel: 41709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ScrollAnimator::scroll(orientation, granularity, step, delta); 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the individual input setting is disabled, bail. 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parameters.m_isEnabled) 42209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ScrollAnimator::scroll(orientation, granularity, step, delta); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is an animatable scroll. Set the animation in motion using the appropriate parameters. 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orientation)); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PerAxisData& data = (orientation == VerticalScrollbar) ? m_verticalData : m_horizontalData; 42809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool needToScroll = data.updateDataFromParameters(step, delta, scrollableSize, WTF::monotonicallyIncreasingTime(), ¶meters); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needToScroll && !animationTimerActive()) { 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_startTime = data.m_startTime; 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animationWillStart(); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animationTimerFired(); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return needToScroll; 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopAnimationTimerIfNeeded(); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_horizontalData.reset(); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *m_horizontalData.m_currentPosition = offset.x(); 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_horizontalData.m_desiredPosition = offset.x(); 444aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch m_currentPosX = offset.x(); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_verticalData.reset(); 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *m_verticalData.m_currentPosition = offset.y(); 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_verticalData.m_desiredPosition = offset.y(); 449aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch m_currentPosY = offset.y(); 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 451aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch notifyPositionChanged(); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::cancelAnimations() 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationActive = false; 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::serviceScrollAnimations() 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_animationActive) 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animationTimerFired(); 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::willEndLiveResize() 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateVisibleLengths(); 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::didAddVerticalScrollbar(Scrollbar*) 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateVisibleLengths(); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::didAddHorizontalScrollbar(Scrollbar*) 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateVisibleLengths(); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::updateVisibleLengths() 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_horizontalData.updateVisibleLength(scrollableArea()->visibleWidth()); 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_verticalData.updateVisibleLength(scrollableArea()->visibleHeight()); 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::animationTimerFired() 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TRACE_EVENT0("webkit", "ScrollAnimatorNone::animationTimerFired"); 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double currentTime = WTF::monotonicallyIncreasingTime(); 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool continueAnimation = false; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime)) 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continueAnimation = true; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime)) 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continueAnimation = true; 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (continueAnimation) 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startNextTimer(); 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationActive = false; 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TRACE_EVENT0("webkit", "ScrollAnimatorNone::notifyPositionChanged"); 504aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch notifyPositionChanged(); 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!continueAnimation) 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animationDidFinish(); 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::startNextTimer() 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (scrollableArea()->scheduleAnimation()) 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationActive = true; 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScrollAnimatorNone::animationTimerActive() 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_animationActive; 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScrollAnimatorNone::stopAnimationTimerIfNeeded() 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationTimerActive()) 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationActive = false; 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 528