15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/animation/scroll_animator.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/animation/slide_animation.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kDefaultAcceleration = -1500.0f; // in pixels per second^2 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assumes that d0 == 0.0f 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float GetPosition(float v0, float a, float t) { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float max_t = -v0 / a; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t > max_t) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = max_t; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return t * (v0 + 0.5f * a * t); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float GetDelta(float v0, float a, float t1, float t2) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetPosition(v0, a, t2) - GetPosition(v0, a, t1); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScrollAnimator::ScrollAnimator(ScrollDelegate* delegate) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) velocity_x_(0.0f), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) velocity_y_(0.0f), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_t_(0.0f), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration_(0.0f), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acceleration_(kDefaultAcceleration) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScrollAnimator::~ScrollAnimator() { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScrollAnimator::Start(float velocity_x, float velocity_y) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (acceleration_ >= 0.0f) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acceleration_ = kDefaultAcceleration; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float v = std::max(fabs(velocity_x), fabs(velocity_y)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_t_ = 0.0f; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) velocity_x_ = velocity_x; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) velocity_y_ = velocity_y; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration_ = -v / acceleration_; // in seconds 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_.reset(new ui::SlideAnimation(this)); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_->SetSlideDuration(static_cast<int>(duration_ * 1000)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_->Show(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScrollAnimator::Stop() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) velocity_x_ = velocity_y_ = last_t_ = duration_ = 0.0f; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_.reset(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScrollAnimator::AnimationEnded(const ui::Animation* animation) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScrollAnimator::AnimationProgressed(const ui::Animation* animation) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float t = static_cast<float>(animation->GetCurrentValue()) * duration_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float a_x = velocity_x_ > 0 ? acceleration_ : -acceleration_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float a_y = velocity_y_ > 0 ? acceleration_ : -acceleration_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float dx = GetDelta(velocity_x_, a_x, last_t_, t); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float dy = GetDelta(velocity_y_, a_y, last_t_, t); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_t_ = t; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnScroll(dx, dy); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScrollAnimator::AnimationCanceled(const ui::Animation* animation) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 83