// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/renderer/webview_animating_overlay.h" #include "base/logging.h" #include "content/public/renderer/render_view.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" #include "ui/gfx/size.h" #include "ui/gfx/skia_util.h" const int kAnimationDurationMiliseconds = 500; const int kAnimationFrameRate = 60; const int kTargetAlpha = 191; WebViewAnimatingOverlay::WebViewAnimatingOverlay( content::RenderView* render_view) : render_view_(render_view), state_(HIDDEN), animation_(kAnimationDurationMiliseconds, kAnimationFrameRate, this) { } WebViewAnimatingOverlay::~WebViewAnimatingOverlay() { if (render_view_->GetWebView()) render_view_->GetWebView()->removePageOverlay(this); } void WebViewAnimatingOverlay::Show() { if (state_ == ANIMATING_IN || state_ == VISIBLE) return; if (state_ == ANIMATING_OUT) { animation_.SetCurrentValue(1.0 - animation_.GetCurrentValue()); } else { DCHECK_EQ(HIDDEN, state_); if (render_view_->GetWebView()) render_view_->GetWebView()->addPageOverlay(this, 0); } state_ = ANIMATING_IN; animation_.Start(); } void WebViewAnimatingOverlay::Hide() { if (state_ == ANIMATING_OUT || state_ == HIDDEN) return; if (state_ == ANIMATING_IN) animation_.SetCurrentValue(1.0 - animation_.GetCurrentValue()); state_ = ANIMATING_OUT; animation_.Start(); } void WebViewAnimatingOverlay::paintPageOverlay(WebKit::WebCanvas* canvas) { SkRect rect = gfx::RectToSkRect(gfx::Rect(render_view_->GetSize())); // The center of the radial gradient should be near the top middle. SkPoint center_point; center_point.iset(rect.width() * 0.5, rect.height() * 0.05); int radius = static_cast(rect.width()); // Animate in or out using the alpha. int alpha = GetCurrentAlpha(); SkColor colors[] = { SkColorSetARGB(alpha, 255, 255, 255), SkColorSetARGB(alpha, 127, 127, 127) }; SkAutoTUnref shader(SkGradientShader::CreateRadial(center_point, SkIntToScalar(radius), colors, NULL, arraysize(colors), SkShader::kClamp_TileMode)); SkPaint paint; paint.setShader(shader); paint.setDither(true); canvas->drawRect(rect, paint); } void WebViewAnimatingOverlay::AnimationEnded(const ui::Animation* animation) { if (state_ == ANIMATING_IN) { state_ = VISIBLE; } else { DCHECK_EQ(ANIMATING_OUT, state_); state_ = HIDDEN; if (render_view_->GetWebView()) render_view_->GetWebView()->removePageOverlay(this); } } void WebViewAnimatingOverlay::AnimationProgressed( const ui::Animation* animation) { render_view_->Repaint(render_view_->GetSize()); } int WebViewAnimatingOverlay::GetCurrentAlpha() { switch (state_) { case ANIMATING_IN: return animation_.CurrentValueBetween(0, kTargetAlpha); case ANIMATING_OUT: return animation_.CurrentValueBetween(kTargetAlpha, 0); case VISIBLE: case HIDDEN: return kTargetAlpha; } NOTREACHED(); return 1.0; }