1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.ui; 18 19 import android.animation.ValueAnimator; 20 import android.graphics.Canvas; 21 import android.graphics.ColorFilter; 22 import android.graphics.Paint; 23 import android.graphics.PixelFormat; 24 import android.graphics.drawable.Drawable; 25 26 import com.android.camera.util.Gusterpolator; 27 28 public class AnimatedCircleDrawable extends Drawable { 29 private static final int CIRCLE_ANIM_DURATION_MS = 300; 30 private static int DRAWABLE_MAX_LEVEL = 10000; 31 32 private int mCanvasWidth; 33 private int mCanvasHeight; 34 35 private int mAlpha = 0xff; 36 private int mColor; 37 private Paint mPaint; 38 private int mRadius; 39 private int mSmallRadiusTarget; 40 AnimatedCircleDrawable(int smallRadiusTarget)41 public AnimatedCircleDrawable(int smallRadiusTarget) { 42 mPaint = new Paint(); 43 mPaint.setAntiAlias(true); 44 mSmallRadiusTarget = smallRadiusTarget; 45 } 46 setColor(int color)47 public void setColor(int color) { 48 mColor = color; 49 updatePaintColor(); 50 } 51 updatePaintColor()52 private void updatePaintColor() { 53 int paintColor = (mAlpha << 24) | (mColor & 0x00ffffff); 54 mPaint.setColor(paintColor); 55 invalidateSelf(); 56 } 57 58 // abstract overrides 59 @Override getOpacity()60 public int getOpacity() { 61 return PixelFormat.TRANSLUCENT; 62 } 63 64 @Override setAlpha(int alpha)65 public void setAlpha(int alpha) { 66 mAlpha = alpha; 67 updatePaintColor(); 68 } 69 70 @Override setColorFilter(ColorFilter cf)71 public void setColorFilter(ColorFilter cf) { 72 //TODO support this? 73 } 74 // end abstract overrides 75 76 @Override onLevelChange(int level)77 public boolean onLevelChange(int level) { 78 if (level != getLevel()) { 79 invalidateSelf(); 80 return true; 81 } 82 return false; 83 } 84 animateToSmallRadius()85 public void animateToSmallRadius() { 86 int smallLevel = map(mSmallRadiusTarget, 87 0, diagonalLength(mCanvasWidth, mCanvasHeight)/2, 88 0, DRAWABLE_MAX_LEVEL); 89 final ValueAnimator animator = 90 ValueAnimator.ofInt(getLevel(), smallLevel); 91 animator.setDuration(CIRCLE_ANIM_DURATION_MS); 92 animator.setInterpolator(Gusterpolator.INSTANCE); 93 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 94 @Override 95 public void onAnimationUpdate(ValueAnimator animation) { 96 setLevel((Integer) animation.getAnimatedValue()); 97 } 98 }); 99 animator.start(); 100 } 101 animateToFullSize()102 public void animateToFullSize() { 103 final ValueAnimator animator = 104 ValueAnimator.ofInt(getLevel(), DRAWABLE_MAX_LEVEL); 105 animator.setDuration(CIRCLE_ANIM_DURATION_MS); 106 animator.setInterpolator(Gusterpolator.INSTANCE); 107 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 108 @Override 109 public void onAnimationUpdate(ValueAnimator animation) { 110 setLevel((Integer) animation.getAnimatedValue()); 111 } 112 }); 113 animator.start(); 114 } 115 116 @Override draw(Canvas canvas)117 public void draw(Canvas canvas) { 118 mCanvasWidth = canvas.getWidth(); 119 mCanvasHeight = canvas.getHeight(); 120 121 mRadius = map(getLevel(), 0, DRAWABLE_MAX_LEVEL, 122 0, diagonalLength(canvas.getWidth(), canvas.getHeight())/2); 123 canvas.drawCircle(canvas.getWidth()/2.0f, canvas.getHeight()/2.0f, 124 mRadius, mPaint); 125 } 126 127 /** 128 * Maps a given value x from one input range [in_min, in_max] to 129 * another output range [out_min, out-max]. 130 * @param x Value to be mapped. 131 * @param in_min Input range minimum. 132 * @param in_max Input range maximum. 133 * @param out_min Output range minimum. 134 * @param out_max Output range maximum. 135 * @return The mapped value. 136 */ map(int x, int in_min, int in_max, int out_min, int out_max)137 private static int map(int x, int in_min, int in_max, int out_min, int out_max) { 138 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 139 } 140 diagonalLength(int w, int h)141 private static int diagonalLength(int w, int h) { 142 return (int) Math.sqrt((w*w) + (h*h)); 143 } 144 }