OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.widget; |
| 6 |
| 7 import android.graphics.Canvas; |
| 8 import android.graphics.Color; |
| 9 import android.graphics.LinearGradient; |
| 10 import android.graphics.Matrix; |
| 11 import android.graphics.Paint; |
| 12 import android.graphics.Shader; |
| 13 import android.view.View; |
| 14 |
| 15 /** |
| 16 * This class draws a variable-sized shadow at the top or bottom edge of a view.
This is just like |
| 17 * a fading edge, except that the shadow color can have an alpha component, wher
eas a fading edge |
| 18 * color must be opaque. |
| 19 */ |
| 20 public class FadingShadow { |
| 21 |
| 22 public static final int POSITION_TOP = 0; |
| 23 public static final int POSITION_BOTTOM = 1; |
| 24 |
| 25 private static final int SMOOTH_ALGORITHM_INTERPOLATION_POINTS_NUM = 8; |
| 26 |
| 27 private Paint mShadowPaint = new Paint(); |
| 28 private Matrix mShadowMatrix = new Matrix(); |
| 29 private Shader mShadowShader; |
| 30 |
| 31 /** |
| 32 * @param shadowColor The color of the shadow, e.g. 0x11000000. |
| 33 */ |
| 34 public FadingShadow(int shadowColor) { |
| 35 final int n = SMOOTH_ALGORITHM_INTERPOLATION_POINTS_NUM; |
| 36 float[] positions = new float[n]; |
| 37 int[] colors = new int[n]; |
| 38 int transparentShadowColor = shadowColor & 0x00FFFFFF; |
| 39 int shadowAlpha = Color.alpha(shadowColor); |
| 40 |
| 41 // Piece-wise linear interpolation of the smooth cubic function below. |
| 42 for (int i = 0; i < n; ++i) { |
| 43 float x = (float) i / (n - 1); |
| 44 // Polynomial computation by Estrin's scheme. |
| 45 float value = (1.0f - 2.2f * x) + (1.8f - 0.6f * x) * (x * x); |
| 46 |
| 47 positions[i] = x; |
| 48 colors[i] = (Math.round(shadowAlpha * value) << 24) | transparentSha
dowColor; |
| 49 } |
| 50 |
| 51 mShadowShader = new LinearGradient(0, 0, 0, 1, colors, positions, Shader
.TileMode.CLAMP); |
| 52 |
| 53 } |
| 54 |
| 55 /** |
| 56 * Draws a shadow at the top or bottom of a view. This should be called from
dispatchDraw() so |
| 57 * the shadow is drawn on top of the view's children. |
| 58 * |
| 59 * @param view The View in which to draw the shadow. |
| 60 * @param canvas The canvas on which to draw. |
| 61 * @param position Where to draw the shadow: either POSITION_TOP or POSITION
_BOTTOM. |
| 62 * @param shadowHeight The maximum height of the shadow, in pixels. |
| 63 * @param shadowStrength A value between 0 and 1 indicating the relative siz
e of the shadow. 0 |
| 64 * means no shadow at all. 1 means a full height shado
w. |
| 65 */ |
| 66 public void drawShadow(View view, Canvas canvas, int position, float shadowH
eight, |
| 67 float shadowStrength) { |
| 68 float scaledShadowHeight = Math.max(0.0f, Math.min(1.0f, shadowStrength)
) * shadowHeight; |
| 69 if (scaledShadowHeight < 1.0f) return; |
| 70 |
| 71 int left = view.getScrollX(); |
| 72 int right = left + view.getRight(); |
| 73 |
| 74 if (position == POSITION_BOTTOM) { |
| 75 int bottom = view.getScrollY() + view.getBottom() - view.getTop(); |
| 76 mShadowMatrix.setScale(1, scaledShadowHeight); |
| 77 mShadowMatrix.postRotate(180); |
| 78 mShadowMatrix.postTranslate(left, bottom); |
| 79 mShadowShader.setLocalMatrix(mShadowMatrix); |
| 80 mShadowPaint.setShader(mShadowShader); |
| 81 canvas.drawRect(left, bottom - scaledShadowHeight, right, bottom, mS
hadowPaint); |
| 82 } else if (position == POSITION_TOP) { |
| 83 int top = view.getScrollY(); |
| 84 mShadowMatrix.setScale(1, scaledShadowHeight); |
| 85 mShadowMatrix.postTranslate(left, top); |
| 86 mShadowShader.setLocalMatrix(mShadowMatrix); |
| 87 mShadowPaint.setShader(mShadowShader); |
| 88 canvas.drawRect(left, top, right, top + scaledShadowHeight, mShadowP
aint); |
| 89 } |
| 90 } |
| 91 } |
OLD | NEW |