103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/browser/android/edge_effect_l.h" 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "cc/layers/ui_resource_layer.h" 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/base/android/system_ui_resource_manager.h" 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace content { 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace { 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Time it will take the effect to fully recede in ms 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kRecedeTimeMs = 600; 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Time it will take before a pulled glow begins receding in ms 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int kPullTimeMs = 167; 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Time it will take for a pulled glow to decay to partial strength before 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// release 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kPullDecayTimeMs = 2000; 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst float kMaxAlpha = 0.5f; 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kPullGlowBegin = 0.f; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Min/max velocity that will be absorbed 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kMinVelocity = 100.f; 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kMaxVelocity = 10000.f; 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kEpsilon = 0.001f; 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kSin = 0.5f; // sin(PI / 6) 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const float kCos = 0.866f; // cos(PI / 6); 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// How much dragging should effect the height of the glow image. 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Number determined by user testing. 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst float kPullDistanceAlphaGlowFactor = 0.8f; 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kVelocityGlowFactor = 6; 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const ui::SystemUIResourceManager::ResourceType kResourceType = 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui::SystemUIResourceManager::OVERSCROLL_GLOW_L; 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)template <typename T> 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)T Lerp(T a, T b, T t) { 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return a + (b - a) * t; 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)template <typename T> 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)T Clamp(T value, T low, T high) { 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return value < low ? low : (value > high ? high : value); 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)template <typename T> 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)T Damp(T input, T factor) { 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) T result; 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (factor == 1) { 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result = 1 - (1 - input) * (1 - input); 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result = 1 - std::pow(1 - input, 2 * factor); 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return result; 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)EdgeEffectL::EdgeEffectL(ui::SystemUIResourceManager* resource_manager) 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : resource_manager_(resource_manager), 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_(cc::UIResourceLayer::Create()), 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_(0), 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_(0), 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_start_(0), 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_finish_(0), 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_start_(0), 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_finish_(0), 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) displacement_(0.5f), 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_displacement_(0.5f), 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_(STATE_IDLE), 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pull_distance_(0) { 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Prevent the provided layers from drawing until the effect is activated. 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetIsDrawable(false); 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)EdgeEffectL::~EdgeEffectL() { 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->RemoveFromParent(); 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool EdgeEffectL::IsFinished() const { 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return state_ == STATE_IDLE; 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::Finish() { 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetIsDrawable(false); 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pull_distance_ = 0; 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_IDLE; 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::Pull(base::TimeTicks current_time, 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) float delta_distance, 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) float displacement) { 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_displacement_ = displacement; 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (state_ == STATE_PULL_DECAY && current_time - start_time_ < duration_) { 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (state_ != STATE_PULL) { 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_ = std::max(kPullGlowBegin, glow_scale_y_); 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_PULL; 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) start_time_ = current_time; 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) duration_ = base::TimeDelta::FromMilliseconds(kPullTimeMs); 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) float abs_delta_distance = std::abs(delta_distance); 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pull_distance_ += delta_distance; 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_ = glow_alpha_start_ = std::min( 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kMaxAlpha, 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_ + (abs_delta_distance * kPullDistanceAlphaGlowFactor)); 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (pull_distance_ == 0) { 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_ = glow_scale_y_start_ = 0; 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) float scale = 1.f - 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1.f / std::sqrt(std::abs(pull_distance_) * bounds_.height()) - 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 0.3f; 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_ = glow_scale_y_start_ = std::max(0.f, scale) / 0.7f; 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_finish_ = glow_alpha_; 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_finish_ = glow_scale_y_; 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::Release(base::TimeTicks current_time) { 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pull_distance_ = 0; 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (state_ != STATE_PULL && state_ != STATE_PULL_DECAY) 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_RECEDE; 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_start_ = glow_alpha_; 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_start_ = glow_scale_y_; 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_finish_ = 0.f; 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_finish_ = 0.f; 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) start_time_ = current_time; 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs); 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::Absorb(base::TimeTicks current_time, float velocity) { 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_ABSORB; 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) velocity = Clamp(std::abs(velocity), kMinVelocity, kMaxVelocity); 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) start_time_ = current_time; 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This should never be less than 1 millisecond. 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) duration_ = base::TimeDelta::FromMilliseconds(0.15f + (velocity * 0.02f)); 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The glow depends more on the velocity, and therefore starts out 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // nearly invisible. 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_start_ = 0.3f; 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_start_ = std::max(glow_scale_y_, 0.f); 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Growth for the size of the glow should be quadratic to properly respond 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // to a user's scrolling speed. The faster the scrolling speed, the more 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // intense the effect should be for both the size and the saturation. 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_finish_ = 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2.f, 1.f); 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Alpha should change for the glow as well as size. 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_finish_ = Clamp( 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_start_, velocity * kVelocityGlowFactor * .00001f, kMaxAlpha); 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_displacement_ = 0.5; 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool EdgeEffectL::Update(base::TimeTicks current_time) { 17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsFinished()) 17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const double dt = (current_time - start_time_).InMilliseconds(); 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const double t = std::min(dt / duration_.InMilliseconds(), 1.); 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float interp = static_cast<float>(Damp(t, 1.)); 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_ = Lerp(glow_alpha_start_, glow_alpha_finish_, interp); 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_ = Lerp(glow_scale_y_start_, glow_scale_y_finish_, interp); 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) displacement_ = (displacement_ + target_displacement_) / 2.f; 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (t >= 1.f - kEpsilon) { 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) switch (state_) { 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_ABSORB: 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_RECEDE; 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) start_time_ = current_time; 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs); 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_start_ = glow_alpha_; 19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_start_ = glow_scale_y_; 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_alpha_finish_ = 0.f; 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_scale_y_finish_ = 0.f; 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_PULL: 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_PULL_DECAY; 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci start_time_ = current_time; 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci duration_ = base::TimeDelta::FromMilliseconds(kPullDecayTimeMs); 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_alpha_start_ = glow_alpha_; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_scale_y_start_ = glow_scale_y_; 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // After pull, the glow should fade to nothing. 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_alpha_finish_ = 0.f; 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_scale_y_finish_ = 0.f; 21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_PULL_DECAY: 21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = STATE_RECEDE; 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_RECEDE: 21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Finish(); 21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) default: 22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool one_last_frame = false; 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (state_ == STATE_RECEDE && glow_scale_y_ <= 0) { 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Finish(); 22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) one_last_frame = true; 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return !IsFinished() || one_last_frame; 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::ApplyToLayers(const gfx::SizeF& size, 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const gfx::Transform& transform) { 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsFinished()) 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // An empty window size, while meaningless, is also relatively harmless, and 24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // will simply prevent any drawing of the layers. 24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (size.IsEmpty()) { 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetIsDrawable(false); 24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float r = size.width() * 0.75f / kSin; 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float y = kCos * r; 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float h = r - y; 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const float o_r = size.height() * 0.75f / kSin; 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const float o_y = kCos * o_r; 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const float o_h = o_r - o_y; 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const float base_glow_scale = h > 0.f ? std::min(o_h / h, 1.f) : 1.f; 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bounds_ = gfx::Size(size.width(), (int)std::min(size.height(), h)); 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Size image_bounds( 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci r, std::min(1.f, glow_scale_y_) * base_glow_scale * bounds_.height()); 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetIsDrawable(true); 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetUIResourceId(resource_manager_->GetUIResourceId(kResourceType)); 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetTransformOrigin(gfx::Point3F(bounds_.width() * 0.5f, 0, 0)); 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetBounds(image_bounds); 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetContentsOpaque(false); 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetOpacity(Clamp(glow_alpha_, 0.f, 1.f)); 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float displacement = Clamp(displacement_, 0.f, 1.f) - 0.5f; 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float displacement_offset_x = bounds_.width() * displacement * 0.5f; 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float image_offset_x = (bounds_.width() - image_bounds.width()) * 0.5f; 26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Transform offset_transform; 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) offset_transform.Translate(image_offset_x - displacement_offset_x, 0); 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) offset_transform.ConcatTransform(transform); 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetTransform(offset_transform); 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::SetParent(cc::Layer* parent) { 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (glow_->parent() != parent) 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) parent->AddChild(glow_); 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glow_->SetUIResourceId(resource_manager_->GetUIResourceId(kResourceType)); 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// static 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void EdgeEffectL::PreloadResources( 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui::SystemUIResourceManager* resource_manager) { 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(resource_manager); 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) resource_manager->PreloadResource(kResourceType); 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace content 287