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" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector2d_f.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TimingFunction; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A small helper class that does the math for zoom animations, primarily for 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// double-tap zoom. Initialize it with starting and ending scroll/page scale 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// positions and an animation length time, then call ...AtTime() at every frame 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to obtain the current interpolated position. The supplied timing function 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is used to ease the animation. 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// All sizes and vectors in this class's public methods are in the root scroll 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// layer's coordinate space. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PageScaleAnimation { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Construct with the state at the beginning of the animation. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static scoped_ptr<PageScaleAnimation> Create( 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Vector2dF& start_scroll_offset, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float start_page_scale_factor, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::SizeF& viewport_size, 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::SizeF& root_layer_size, 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TimingFunction> timing_function); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~PageScaleAnimation(); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following methods initialize the animation. Call one of them 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // immediately after construction to set the final scroll and page scale. 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Zoom while explicitly specifying the top-left scroll position. 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ZoomTo(const gfx::Vector2dF& target_scroll_offset, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float target_page_scale_factor, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double duration); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Zoom based on a specified anchor. The animator will attempt to keep it 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // at the same position on the physical display throughout the animation, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unless the edges of the root layer are hit. The anchor is specified 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as an offset from the content layer. 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ZoomWithAnchor(const gfx::Vector2dF& anchor, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float target_page_scale_factor, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double duration); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // These should be called before the first frame of animation to initialize 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the start time. StartAnimation should only be called once after creation. 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool IsAnimationStarted() const; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void StartAnimation(base::TimeTicks time); 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Call these functions while the animation is in progress to output the 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // current state. 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Vector2dF ScrollOffsetAtTime(base::TimeTicks time) const; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) float PageScaleFactorAtTime(base::TimeTicks time) const; 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool IsAnimationCompleteAtTime(base::TimeTicks time) const; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following methods return state which is invariant throughout the 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // course of the animation. 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks start_time() const { return start_time_; } 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta duration() const { return duration_; } 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks end_time() const { return start_time_ + duration_; } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF target_scroll_offset() const { return target_scroll_offset_; } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float target_page_scale_factor() const { return target_page_scale_factor_; } 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PageScaleAnimation(const gfx::Vector2dF& start_scroll_offset, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float start_page_scale_factor, 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::SizeF& viewport_size, 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::SizeF& root_layer_size, 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TimingFunction> timing_function); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ClampTargetScrollOffset(); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InferTargetScrollOffsetFromStartAnchor(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InferTargetAnchorFromScrollOffsets(); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF StartViewportSize() const; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF TargetViewportSize() const; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) float InterpAtTime(base::TimeTicks time) const; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF ViewportSizeAt(float interp) const; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF ScrollOffsetAt(float interp) const; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF AnchorAt(float interp) const; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF ViewportRelativeAnchorAt(float interp) const; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float PageScaleFactorAt(float interp) const; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float start_page_scale_factor_; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float target_page_scale_factor_; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF start_scroll_offset_; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF target_scroll_offset_; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF start_anchor_; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF target_anchor_; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF viewport_size_; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF root_layer_size_; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks start_time_; 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta duration_; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TimingFunction> timing_function_; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PageScaleAnimation); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CC_INPUT_PAGE_SCALE_ANIMATION_H_ 116