1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "platform/scroll/ProgrammaticScrollAnimator.h"
7
8#include "platform/geometry/IntPoint.h"
9#include "platform/scroll/ScrollableArea.h"
10#include "public/platform/Platform.h"
11#include "public/platform/WebCompositorSupport.h"
12#include "public/platform/WebScrollOffsetAnimationCurve.h"
13
14namespace blink {
15
16PassOwnPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(ScrollableArea* scrollableArea)
17{
18    return adoptPtr(new ProgrammaticScrollAnimator(scrollableArea));
19}
20
21ProgrammaticScrollAnimator::ProgrammaticScrollAnimator(ScrollableArea* scrollableArea)
22    : m_scrollableArea(scrollableArea)
23    , m_startTime(0.0)
24{
25}
26
27ProgrammaticScrollAnimator::~ProgrammaticScrollAnimator()
28{
29}
30
31void ProgrammaticScrollAnimator::resetAnimationState()
32{
33    m_animationCurve.clear();
34    m_startTime = 0.0;
35}
36
37void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
38{
39    m_startTime = 0.0;
40    m_targetOffset = offset;
41    m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->createScrollOffsetAnimationCurve(m_targetOffset, WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut));
42
43    m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition()));
44    if (!m_scrollableArea->scheduleAnimation()) {
45        resetAnimationState();
46        m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y()));
47    }
48}
49
50void ProgrammaticScrollAnimator::cancelAnimation()
51{
52    resetAnimationState();
53}
54
55void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime)
56{
57    if (m_animationCurve) {
58        if (!m_startTime)
59            m_startTime = monotonicTime;
60        double elapsedTime = monotonicTime - m_startTime;
61        bool isFinished = (elapsedTime > m_animationCurve->duration());
62        FloatPoint offset = m_animationCurve->getValue(elapsedTime);
63        m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y()));
64
65        if (isFinished) {
66            resetAnimationState();
67        } else if (!m_scrollableArea->scheduleAnimation()) {
68            m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
69            resetAnimationState();
70        }
71    }
72}
73
74} // namespace blink
75