12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_INPUT_PAGE_SCALE_ANIMATION_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_INPUT_PAGE_SCALE_ANIMATION_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/time/time.h"
111675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch#include "cc/base/cc_export.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector2d_f.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TimingFunction;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A small helper class that does the math for zoom animations, primarily for
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// double-tap zoom. Initialize it with starting and ending scroll/page scale
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// positions and an animation length time, then call ...AtTime() at every frame
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to obtain the current interpolated position. The supplied timing function
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is used to ease the animation.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// All sizes and vectors in this class's public methods are in the root scroll
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// layer's coordinate space.
271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochclass CC_EXPORT PageScaleAnimation {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Construct with the state at the beginning of the animation.
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<PageScaleAnimation> Create(
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const gfx::Vector2dF& start_scroll_offset,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      float start_page_scale_factor,
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const gfx::SizeF& viewport_size,
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const gfx::SizeF& root_layer_size,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<TimingFunction> timing_function);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~PageScaleAnimation();
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The following methods initialize the animation. Call one of them
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // immediately after construction to set the final scroll and page scale.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Zoom while explicitly specifying the top-left scroll position.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ZoomTo(const gfx::Vector2dF& target_scroll_offset,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              float target_page_scale_factor,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              double duration);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Zoom based on a specified anchor. The animator will attempt to keep it
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // at the same position on the physical display throughout the animation,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unless the edges of the root layer are hit. The anchor is specified
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as an offset from the content layer.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ZoomWithAnchor(const gfx::Vector2dF& anchor,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      float target_page_scale_factor,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      double duration);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // These should be called before the first frame of animation to initialize
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the start time. StartAnimation should only be called once after creation.
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool IsAnimationStarted() const;
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void StartAnimation(base::TimeTicks time);
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Call these functions while the animation is in progress to output the
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // current state.
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Vector2dF ScrollOffsetAtTime(base::TimeTicks time) const;
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float PageScaleFactorAtTime(base::TimeTicks time) const;
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsAnimationCompleteAtTime(base::TimeTicks time) const;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The following methods return state which is invariant throughout the
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // course of the animation.
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeTicks start_time() const { return start_time_; }
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta duration() const { return duration_; }
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeTicks end_time() const { return start_time_ + duration_; }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF target_scroll_offset() const { return target_scroll_offset_; }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float target_page_scale_factor() const { return target_page_scale_factor_; }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PageScaleAnimation(const gfx::Vector2dF& start_scroll_offset,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     float start_page_scale_factor,
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     const gfx::SizeF& viewport_size,
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     const gfx::SizeF& root_layer_size,
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     scoped_ptr<TimingFunction> timing_function);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ClampTargetScrollOffset();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InferTargetScrollOffsetFromStartAnchor();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InferTargetAnchorFromScrollOffsets();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF StartViewportSize() const;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF TargetViewportSize() const;
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float InterpAtTime(base::TimeTicks time) const;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF ViewportSizeAt(float interp) const;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF ScrollOffsetAt(float interp) const;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF AnchorAt(float interp) const;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF ViewportRelativeAnchorAt(float interp) const;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float PageScaleFactorAt(float interp) const;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float start_page_scale_factor_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float target_page_scale_factor_;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF start_scroll_offset_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF target_scroll_offset_;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF start_anchor_;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2dF target_anchor_;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF viewport_size_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF root_layer_size_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeTicks start_time_;
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta duration_;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<TimingFunction> timing_function_;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PageScaleAnimation);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_INPUT_PAGE_SCALE_ANIMATION_H_
117