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