| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2011, Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 | |
| 33 #include "platform/scroll/ScrollAnimatorNone.h" | |
| 34 | |
| 35 #include <algorithm> | |
| 36 #include "platform/scroll/ScrollableArea.h" | |
| 37 #include "wtf/CurrentTime.h" | |
| 38 #include "wtf/PassOwnPtr.h" | |
| 39 | |
| 40 #include "platform/TraceEvent.h" | |
| 41 | |
| 42 namespace blink { | |
| 43 | |
| 44 const double kFrameRate = 60; | |
| 45 const double kTickTime = 1 / kFrameRate; | |
| 46 const double kMinimumTimerInterval = .001; | |
| 47 | |
| 48 PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea
) | |
| 49 { | |
| 50 if (scrollableArea && scrollableArea->scrollAnimatorEnabled()) | |
| 51 return adoptPtr(new ScrollAnimatorNone(scrollableArea)); | |
| 52 return adoptPtr(new ScrollAnimator(scrollableArea)); | |
| 53 } | |
| 54 | |
| 55 ScrollAnimatorNone::Parameters::Parameters() | |
| 56 : m_isEnabled(false) | |
| 57 { | |
| 58 } | |
| 59 | |
| 60 ScrollAnimatorNone::Parameters::Parameters(bool isEnabled, double animationTime,
double repeatMinimumSustainTime, Curve attackCurve, double attackTime, Curve re
leaseCurve, double releaseTime, Curve coastTimeCurve, double maximumCoastTime) | |
| 61 : m_isEnabled(isEnabled) | |
| 62 , m_animationTime(animationTime) | |
| 63 , m_repeatMinimumSustainTime(repeatMinimumSustainTime) | |
| 64 , m_attackCurve(attackCurve) | |
| 65 , m_attackTime(attackTime) | |
| 66 , m_releaseCurve(releaseCurve) | |
| 67 , m_releaseTime(releaseTime) | |
| 68 , m_coastTimeCurve(coastTimeCurve) | |
| 69 , m_maximumCoastTime(maximumCoastTime) | |
| 70 { | |
| 71 } | |
| 72 | |
| 73 double ScrollAnimatorNone::PerAxisData::curveAt(Curve curve, double t) | |
| 74 { | |
| 75 switch (curve) { | |
| 76 case Linear: | |
| 77 return t; | |
| 78 case Quadratic: | |
| 79 return t * t; | |
| 80 case Cubic: | |
| 81 return t * t * t; | |
| 82 case Quartic: | |
| 83 return t * t * t * t; | |
| 84 case Bounce: | |
| 85 // Time base is chosen to keep the bounce points simpler: | |
| 86 // 1 (half bounce coming in) + 1 + .5 + .25 | |
| 87 const double kTimeBase = 2.75; | |
| 88 const double kTimeBaseSquared = kTimeBase * kTimeBase; | |
| 89 if (t < 1 / kTimeBase) | |
| 90 return kTimeBaseSquared * t * t; | |
| 91 if (t < 2 / kTimeBase) { | |
| 92 // Invert a [-.5,.5] quadratic parabola, center it in [1,2]. | |
| 93 double t1 = t - 1.5 / kTimeBase; | |
| 94 const double kParabolaAtEdge = 1 - .5 * .5; | |
| 95 return kTimeBaseSquared * t1 * t1 + kParabolaAtEdge; | |
| 96 } | |
| 97 if (t < 2.5 / kTimeBase) { | |
| 98 // Invert a [-.25,.25] quadratic parabola, center it in [2,2.5]. | |
| 99 double t2 = t - 2.25 / kTimeBase; | |
| 100 const double kParabolaAtEdge = 1 - .25 * .25; | |
| 101 return kTimeBaseSquared * t2 * t2 + kParabolaAtEdge; | |
| 102 } | |
| 103 // Invert a [-.125,.125] quadratic parabola, center it in [2.5,2.75]
. | |
| 104 const double kParabolaAtEdge = 1 - .125 * .125; | |
| 105 t -= 2.625 / kTimeBase; | |
| 106 return kTimeBaseSquared * t * t + kParabolaAtEdge; | |
| 107 } | |
| 108 ASSERT_NOT_REACHED(); | |
| 109 return 0; | |
| 110 } | |
| 111 | |
| 112 double ScrollAnimatorNone::PerAxisData::attackCurve(Curve curve, double deltaTim
e, double curveT, double startPosition, double attackPosition) | |
| 113 { | |
| 114 double t = deltaTime / curveT; | |
| 115 double positionFactor = curveAt(curve, t); | |
| 116 return startPosition + positionFactor * (attackPosition - startPosition); | |
| 117 } | |
| 118 | |
| 119 double ScrollAnimatorNone::PerAxisData::releaseCurve(Curve curve, double deltaTi
me, double curveT, double releasePosition, double desiredPosition) | |
| 120 { | |
| 121 double t = deltaTime / curveT; | |
| 122 double positionFactor = 1 - curveAt(curve, 1 - t); | |
| 123 return releasePosition + (positionFactor * (desiredPosition - releasePositio
n)); | |
| 124 } | |
| 125 | |
| 126 double ScrollAnimatorNone::PerAxisData::coastCurve(Curve curve, double factor) | |
| 127 { | |
| 128 return 1 - curveAt(curve, 1 - factor); | |
| 129 } | |
| 130 | |
| 131 double ScrollAnimatorNone::PerAxisData::curveIntegralAt(Curve curve, double t) | |
| 132 { | |
| 133 switch (curve) { | |
| 134 case Linear: | |
| 135 return t * t / 2; | |
| 136 case Quadratic: | |
| 137 return t * t * t / 3; | |
| 138 case Cubic: | |
| 139 return t * t * t * t / 4; | |
| 140 case Quartic: | |
| 141 return t * t * t * t * t / 5; | |
| 142 case Bounce: | |
| 143 const double kTimeBase = 2.75; | |
| 144 const double kTimeBaseSquared = kTimeBase * kTimeBase; | |
| 145 const double kTimeBaseSquaredOverThree = kTimeBaseSquared / 3; | |
| 146 double area; | |
| 147 double t1 = std::min(t, 1 / kTimeBase); | |
| 148 area = kTimeBaseSquaredOverThree * t1 * t1 * t1; | |
| 149 if (t < 1 / kTimeBase) | |
| 150 return area; | |
| 151 | |
| 152 t1 = std::min(t - 1 / kTimeBase, 1 / kTimeBase); | |
| 153 // The integral of kTimeBaseSquared * (t1 - .5 / kTimeBase) * (t1 - .5 /
kTimeBase) + kParabolaAtEdge | |
| 154 const double kSecondInnerOffset = kTimeBaseSquared * .5 / kTimeBase; | |
| 155 double bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kSecond
InnerOffset) + 1); | |
| 156 area += bounceArea; | |
| 157 if (t < 2 / kTimeBase) | |
| 158 return area; | |
| 159 | |
| 160 t1 = std::min(t - 2 / kTimeBase, 0.5 / kTimeBase); | |
| 161 // The integral of kTimeBaseSquared * (t1 - .25 / kTimeBase) * (t1 - .25
/ kTimeBase) + kParabolaAtEdge | |
| 162 const double kThirdInnerOffset = kTimeBaseSquared * .25 / kTimeBase; | |
| 163 bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kThirdInnerOf
fset) + 1); | |
| 164 area += bounceArea; | |
| 165 if (t < 2.5 / kTimeBase) | |
| 166 return area; | |
| 167 | |
| 168 t1 = t - 2.5 / kTimeBase; | |
| 169 // The integral of kTimeBaseSquared * (t1 - .125 / kTimeBase) * (t1 - .1
25 / kTimeBase) + kParabolaAtEdge | |
| 170 const double kFourthInnerOffset = kTimeBaseSquared * .125 / kTimeBase; | |
| 171 bounceArea = t1 * (t1 * (kTimeBaseSquaredOverThree * t1 - kFourthInnerOf
fset) + 1); | |
| 172 area += bounceArea; | |
| 173 return area; | |
| 174 } | |
| 175 ASSERT_NOT_REACHED(); | |
| 176 return 0; | |
| 177 } | |
| 178 | |
| 179 double ScrollAnimatorNone::PerAxisData::attackArea(Curve curve, double startT, d
ouble endT) | |
| 180 { | |
| 181 double startValue = curveIntegralAt(curve, startT); | |
| 182 double endValue = curveIntegralAt(curve, endT); | |
| 183 return endValue - startValue; | |
| 184 } | |
| 185 | |
| 186 double ScrollAnimatorNone::PerAxisData::releaseArea(Curve curve, double startT,
double endT) | |
| 187 { | |
| 188 double startValue = curveIntegralAt(curve, 1 - endT); | |
| 189 double endValue = curveIntegralAt(curve, 1 - startT); | |
| 190 return endValue - startValue; | |
| 191 } | |
| 192 | |
| 193 ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float*
currentPosition, int visibleLength) | |
| 194 : m_currentPosition(currentPosition) | |
| 195 , m_visibleLength(visibleLength) | |
| 196 { | |
| 197 reset(); | |
| 198 } | |
| 199 | |
| 200 void ScrollAnimatorNone::PerAxisData::reset() | |
| 201 { | |
| 202 m_currentVelocity = 0; | |
| 203 | |
| 204 m_desiredPosition = 0; | |
| 205 m_desiredVelocity = 0; | |
| 206 | |
| 207 m_startPosition = 0; | |
| 208 m_startTime = 0; | |
| 209 m_startVelocity = 0; | |
| 210 | |
| 211 m_animationTime = 0; | |
| 212 m_lastAnimationTime = 0; | |
| 213 | |
| 214 m_attackPosition = 0; | |
| 215 m_attackTime = 0; | |
| 216 m_attackCurve = Quadratic; | |
| 217 | |
| 218 m_releasePosition = 0; | |
| 219 m_releaseTime = 0; | |
| 220 m_releaseCurve = Quadratic; | |
| 221 } | |
| 222 | |
| 223 | |
| 224 bool ScrollAnimatorNone::PerAxisData::updateDataFromParameters(float step, float
delta, float scrollableSize, double currentTime, Parameters* parameters) | |
| 225 { | |
| 226 float pixelDelta = step * delta; | |
| 227 if (!m_startTime || !pixelDelta || (pixelDelta < 0) != (m_desiredPosition -
*m_currentPosition < 0)) { | |
| 228 m_desiredPosition = *m_currentPosition; | |
| 229 m_startTime = 0; | |
| 230 } | |
| 231 float newPosition = m_desiredPosition + pixelDelta; | |
| 232 | |
| 233 if (newPosition < 0 || newPosition > scrollableSize) | |
| 234 newPosition = std::max(std::min(newPosition, scrollableSize), 0.0f); | |
| 235 | |
| 236 if (newPosition == m_desiredPosition) | |
| 237 return false; | |
| 238 | |
| 239 m_desiredPosition = newPosition; | |
| 240 | |
| 241 if (!m_startTime) { | |
| 242 m_attackTime = parameters->m_attackTime; | |
| 243 m_attackCurve = parameters->m_attackCurve; | |
| 244 } | |
| 245 m_animationTime = parameters->m_animationTime; | |
| 246 m_releaseTime = parameters->m_releaseTime; | |
| 247 m_releaseCurve = parameters->m_releaseCurve; | |
| 248 | |
| 249 // Prioritize our way out of over constraint. | |
| 250 if (m_attackTime + m_releaseTime > m_animationTime) { | |
| 251 if (m_releaseTime > m_animationTime) | |
| 252 m_releaseTime = m_animationTime; | |
| 253 m_attackTime = m_animationTime - m_releaseTime; | |
| 254 } | |
| 255 | |
| 256 if (!m_startTime) { | |
| 257 // FIXME: This should be the time from the event that got us here. | |
| 258 m_startTime = currentTime - kTickTime / 2; | |
| 259 m_startPosition = *m_currentPosition; | |
| 260 m_lastAnimationTime = m_startTime; | |
| 261 } | |
| 262 m_startVelocity = m_currentVelocity; | |
| 263 | |
| 264 double remainingDelta = m_desiredPosition - *m_currentPosition; | |
| 265 | |
| 266 double attackAreaLeft = 0; | |
| 267 | |
| 268 double deltaTime = m_lastAnimationTime - m_startTime; | |
| 269 double attackTimeLeft = std::max(0., m_attackTime - deltaTime); | |
| 270 double timeLeft = m_animationTime - deltaTime; | |
| 271 double minTimeLeft = m_releaseTime + std::min(parameters->m_repeatMinimumSus
tainTime, m_animationTime - m_releaseTime - attackTimeLeft); | |
| 272 if (timeLeft < minTimeLeft) { | |
| 273 m_animationTime = deltaTime + minTimeLeft; | |
| 274 timeLeft = minTimeLeft; | |
| 275 } | |
| 276 | |
| 277 if (parameters->m_maximumCoastTime > (parameters->m_repeatMinimumSustainTime
+ parameters->m_releaseTime)) { | |
| 278 double targetMaxCoastVelocity = m_visibleLength * .25 * kFrameRate; | |
| 279 // This needs to be as minimal as possible while not being intrusive to
page up/down. | |
| 280 double minCoastDelta = m_visibleLength; | |
| 281 | |
| 282 if (fabs(remainingDelta) > minCoastDelta) { | |
| 283 double maxCoastDelta = parameters->m_maximumCoastTime * targetMaxCoa
stVelocity; | |
| 284 double coastFactor = std::min(1., (fabs(remainingDelta) - minCoastDe
lta) / (maxCoastDelta - minCoastDelta)); | |
| 285 | |
| 286 // We could play with the curve here - linear seems a little soft. I
nitial testing makes me want to feed into the sustain time more aggressively. | |
| 287 double coastMinTimeLeft = std::min(parameters->m_maximumCoastTime, m
inTimeLeft + coastCurve(parameters->m_coastTimeCurve, coastFactor) * (parameters
->m_maximumCoastTime - minTimeLeft)); | |
| 288 | |
| 289 double additionalTime = std::max(0., coastMinTimeLeft - minTimeLeft)
; | |
| 290 if (additionalTime) { | |
| 291 double additionalReleaseTime = std::min(additionalTime, paramete
rs->m_releaseTime / (parameters->m_releaseTime + parameters->m_repeatMinimumSust
ainTime) * additionalTime); | |
| 292 m_releaseTime = parameters->m_releaseTime + additionalReleaseTim
e; | |
| 293 m_animationTime = deltaTime + coastMinTimeLeft; | |
| 294 timeLeft = coastMinTimeLeft; | |
| 295 } | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 double releaseTimeLeft = std::min(timeLeft, m_releaseTime); | |
| 300 double sustainTimeLeft = std::max(0., timeLeft - releaseTimeLeft - attackTim
eLeft); | |
| 301 | |
| 302 if (attackTimeLeft) { | |
| 303 double attackSpot = deltaTime / m_attackTime; | |
| 304 attackAreaLeft = attackArea(m_attackCurve, attackSpot, 1) * m_attackTime
; | |
| 305 } | |
| 306 | |
| 307 double releaseSpot = (m_releaseTime - releaseTimeLeft) / m_releaseTime; | |
| 308 double releaseAreaLeft = releaseArea(m_releaseCurve, releaseSpot, 1) * m_re
leaseTime; | |
| 309 | |
| 310 m_desiredVelocity = remainingDelta / (attackAreaLeft + sustainTimeLeft + rel
easeAreaLeft); | |
| 311 m_releasePosition = m_desiredPosition - m_desiredVelocity * releaseAreaLeft; | |
| 312 if (attackAreaLeft) | |
| 313 m_attackPosition = m_startPosition + m_desiredVelocity * attackAreaLeft; | |
| 314 else | |
| 315 m_attackPosition = m_releasePosition - (m_animationTime - m_releaseTime
- m_attackTime) * m_desiredVelocity; | |
| 316 | |
| 317 if (sustainTimeLeft) { | |
| 318 double roundOff = m_releasePosition - ((attackAreaLeft ? m_attackPositio
n : *m_currentPosition) + m_desiredVelocity * sustainTimeLeft); | |
| 319 m_desiredVelocity += roundOff / sustainTimeLeft; | |
| 320 } | |
| 321 | |
| 322 return true; | |
| 323 } | |
| 324 | |
| 325 inline double ScrollAnimatorNone::PerAxisData::newScrollAnimationPosition(double
deltaTime) | |
| 326 { | |
| 327 if (deltaTime < m_attackTime) | |
| 328 return attackCurve(m_attackCurve, deltaTime, m_attackTime, m_startPositi
on, m_attackPosition); | |
| 329 if (deltaTime < (m_animationTime - m_releaseTime)) | |
| 330 return m_attackPosition + (deltaTime - m_attackTime) * m_desiredVelocity
; | |
| 331 // release is based on targeting the exact final position. | |
| 332 double releaseDeltaT = deltaTime - (m_animationTime - m_releaseTime); | |
| 333 return releaseCurve(m_releaseCurve, releaseDeltaT, m_releaseTime, m_releaseP
osition, m_desiredPosition); | |
| 334 } | |
| 335 | |
| 336 // FIXME: Add in jank detection trace events into this function. | |
| 337 bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime) | |
| 338 { | |
| 339 double lastScrollInterval = currentTime - m_lastAnimationTime; | |
| 340 if (lastScrollInterval < kMinimumTimerInterval) | |
| 341 return true; | |
| 342 | |
| 343 m_lastAnimationTime = currentTime; | |
| 344 | |
| 345 double deltaTime = currentTime - m_startTime; | |
| 346 | |
| 347 if (deltaTime > m_animationTime) { | |
| 348 *m_currentPosition = m_desiredPosition; | |
| 349 reset(); | |
| 350 return false; | |
| 351 } | |
| 352 double newPosition = newScrollAnimationPosition(deltaTime); | |
| 353 // Normalize velocity to a per second amount. Could be used to check for jan
k. | |
| 354 if (lastScrollInterval > 0) | |
| 355 m_currentVelocity = (newPosition - *m_currentPosition) / lastScrollInter
val; | |
| 356 *m_currentPosition = newPosition; | |
| 357 | |
| 358 return true; | |
| 359 } | |
| 360 | |
| 361 void ScrollAnimatorNone::PerAxisData::updateVisibleLength(int visibleLength) | |
| 362 { | |
| 363 m_visibleLength = visibleLength; | |
| 364 } | |
| 365 | |
| 366 ScrollAnimatorNone::ScrollAnimatorNone(ScrollableArea* scrollableArea) | |
| 367 : ScrollAnimator(scrollableArea) | |
| 368 , m_horizontalData(this, &m_currentPosX, scrollableArea->visibleWidth()) | |
| 369 , m_verticalData(this, &m_currentPosY, scrollableArea->visibleHeight()) | |
| 370 , m_startTime(0) | |
| 371 , m_animationActive(false) | |
| 372 { | |
| 373 } | |
| 374 | |
| 375 ScrollAnimatorNone::~ScrollAnimatorNone() | |
| 376 { | |
| 377 stopAnimationTimerIfNeeded(); | |
| 378 } | |
| 379 | |
| 380 ScrollAnimatorNone::Parameters ScrollAnimatorNone::parametersForScrollGranularit
y(ScrollGranularity granularity) const | |
| 381 { | |
| 382 switch (granularity) { | |
| 383 case ScrollByDocument: | |
| 384 return Parameters(true, 20 * kTickTime, 10 * kTickTime, Cubic, 10 * kTic
kTime, Cubic, 10 * kTickTime, Linear, 1); | |
| 385 case ScrollByLine: | |
| 386 return Parameters(true, 10 * kTickTime, 7 * kTickTime, Cubic, 3 * kTickT
ime, Cubic, 3 * kTickTime, Linear, 1); | |
| 387 case ScrollByPage: | |
| 388 return Parameters(true, 15 * kTickTime, 10 * kTickTime, Cubic, 5 * kTick
Time, Cubic, 5 * kTickTime, Linear, 1); | |
| 389 case ScrollByPixel: | |
| 390 return Parameters(true, 11 * kTickTime, 2 * kTickTime, Cubic, 3 * kTickT
ime, Cubic, 3 * kTickTime, Quadratic, 1.25); | |
| 391 default: | |
| 392 ASSERT_NOT_REACHED(); | |
| 393 } | |
| 394 return Parameters(); | |
| 395 } | |
| 396 | |
| 397 bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranular
ity granularity, float step, float delta) | |
| 398 { | |
| 399 if (!m_scrollableArea->scrollAnimatorEnabled()) | |
| 400 return ScrollAnimator::scroll(orientation, granularity, step, delta); | |
| 401 | |
| 402 TRACE_EVENT0("blink", "ScrollAnimatorNone::scroll"); | |
| 403 | |
| 404 // FIXME: get the type passed in. MouseWheel could also be by line, but shou
ld still have different | |
| 405 // animation parameters than the keyboard. | |
| 406 Parameters parameters; | |
| 407 switch (granularity) { | |
| 408 case ScrollByDocument: | |
| 409 case ScrollByLine: | |
| 410 case ScrollByPage: | |
| 411 case ScrollByPixel: | |
| 412 parameters = parametersForScrollGranularity(granularity); | |
| 413 break; | |
| 414 case ScrollByPrecisePixel: | |
| 415 return ScrollAnimator::scroll(orientation, granularity, step, delta); | |
| 416 } | |
| 417 | |
| 418 // If the individual input setting is disabled, bail. | |
| 419 if (!parameters.m_isEnabled) | |
| 420 return ScrollAnimator::scroll(orientation, granularity, step, delta); | |
| 421 | |
| 422 // This is an animatable scroll. Set the animation in motion using the appro
priate parameters. | |
| 423 float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orien
tation)); | |
| 424 | |
| 425 PerAxisData& data = (orientation == VerticalScrollbar) ? m_verticalData : m_
horizontalData; | |
| 426 bool needToScroll = data.updateDataFromParameters(step, delta, scrollableSiz
e, WTF::monotonicallyIncreasingTime(), ¶meters); | |
| 427 if (needToScroll && !animationTimerActive()) { | |
| 428 m_startTime = data.m_startTime; | |
| 429 animationWillStart(); | |
| 430 animationTimerFired(); | |
| 431 } | |
| 432 return needToScroll; | |
| 433 } | |
| 434 | |
| 435 void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset
) | |
| 436 { | |
| 437 stopAnimationTimerIfNeeded(); | |
| 438 | |
| 439 m_horizontalData.reset(); | |
| 440 *m_horizontalData.m_currentPosition = offset.x(); | |
| 441 m_horizontalData.m_desiredPosition = offset.x(); | |
| 442 m_currentPosX = offset.x(); | |
| 443 | |
| 444 m_verticalData.reset(); | |
| 445 *m_verticalData.m_currentPosition = offset.y(); | |
| 446 m_verticalData.m_desiredPosition = offset.y(); | |
| 447 m_currentPosY = offset.y(); | |
| 448 | |
| 449 notifyPositionChanged(); | |
| 450 } | |
| 451 | |
| 452 void ScrollAnimatorNone::cancelAnimations() | |
| 453 { | |
| 454 m_animationActive = false; | |
| 455 } | |
| 456 | |
| 457 void ScrollAnimatorNone::serviceScrollAnimations() | |
| 458 { | |
| 459 if (m_animationActive) | |
| 460 animationTimerFired(); | |
| 461 } | |
| 462 | |
| 463 void ScrollAnimatorNone::willEndLiveResize() | |
| 464 { | |
| 465 updateVisibleLengths(); | |
| 466 } | |
| 467 | |
| 468 void ScrollAnimatorNone::didAddVerticalScrollbar(Scrollbar*) | |
| 469 { | |
| 470 updateVisibleLengths(); | |
| 471 } | |
| 472 | |
| 473 void ScrollAnimatorNone::didAddHorizontalScrollbar(Scrollbar*) | |
| 474 { | |
| 475 updateVisibleLengths(); | |
| 476 } | |
| 477 | |
| 478 void ScrollAnimatorNone::updateVisibleLengths() | |
| 479 { | |
| 480 m_horizontalData.updateVisibleLength(scrollableArea()->visibleWidth()); | |
| 481 m_verticalData.updateVisibleLength(scrollableArea()->visibleHeight()); | |
| 482 } | |
| 483 | |
| 484 void ScrollAnimatorNone::animationTimerFired() | |
| 485 { | |
| 486 TRACE_EVENT0("blink", "ScrollAnimatorNone::animationTimerFired"); | |
| 487 | |
| 488 double currentTime = WTF::monotonicallyIncreasingTime(); | |
| 489 | |
| 490 bool continueAnimation = false; | |
| 491 if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTi
me)) | |
| 492 continueAnimation = true; | |
| 493 if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime)) | |
| 494 continueAnimation = true; | |
| 495 | |
| 496 if (continueAnimation) | |
| 497 startNextTimer(); | |
| 498 else | |
| 499 m_animationActive = false; | |
| 500 | |
| 501 TRACE_EVENT0("blink", "ScrollAnimatorNone::notifyPositionChanged"); | |
| 502 notifyPositionChanged(); | |
| 503 | |
| 504 if (!continueAnimation) | |
| 505 animationDidFinish(); | |
| 506 } | |
| 507 | |
| 508 void ScrollAnimatorNone::startNextTimer() | |
| 509 { | |
| 510 if (scrollableArea()->scheduleAnimation()) | |
| 511 m_animationActive = true; | |
| 512 } | |
| 513 | |
| 514 bool ScrollAnimatorNone::animationTimerActive() | |
| 515 { | |
| 516 return m_animationActive; | |
| 517 } | |
| 518 | |
| 519 void ScrollAnimatorNone::stopAnimationTimerIfNeeded() | |
| 520 { | |
| 521 if (animationTimerActive()) | |
| 522 m_animationActive = false; | |
| 523 } | |
| 524 | |
| 525 } // namespace blink | |
| OLD | NEW |