| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.camera.ui; |
| |
| import android.animation.ValueAnimator; |
| import android.graphics.Canvas; |
| import android.graphics.ColorFilter; |
| import android.graphics.Paint; |
| import android.graphics.PixelFormat; |
| import android.graphics.drawable.Drawable; |
| |
| import com.android.camera.util.Gusterpolator; |
| |
| public class AnimatedCircleDrawable extends Drawable { |
| private static final int CIRCLE_ANIM_DURATION_MS = 300; |
| private static int DRAWABLE_MAX_LEVEL = 10000; |
| |
| private int mCanvasWidth; |
| private int mCanvasHeight; |
| |
| private int mAlpha = 0xff; |
| private int mColor; |
| private Paint mPaint; |
| private int mRadius; |
| private int mSmallRadiusTarget; |
| |
| public AnimatedCircleDrawable(int smallRadiusTarget) { |
| mPaint = new Paint(); |
| mPaint.setAntiAlias(true); |
| mSmallRadiusTarget = smallRadiusTarget; |
| } |
| |
| public void setColor(int color) { |
| mColor = color; |
| updatePaintColor(); |
| } |
| |
| private void updatePaintColor() { |
| int paintColor = (mAlpha << 24) | (mColor & 0x00ffffff); |
| mPaint.setColor(paintColor); |
| invalidateSelf(); |
| } |
| |
| // abstract overrides |
| @Override |
| public int getOpacity() { |
| return PixelFormat.TRANSLUCENT; |
| } |
| |
| @Override |
| public void setAlpha(int alpha) { |
| mAlpha = alpha; |
| updatePaintColor(); |
| } |
| |
| @Override |
| public void setColorFilter(ColorFilter cf) { |
| //TODO support this? |
| } |
| // end abstract overrides |
| |
| @Override |
| public boolean onLevelChange(int level) { |
| invalidateSelf(); |
| return true; |
| } |
| |
| public void animateToSmallRadius() { |
| int smallLevel = map(mSmallRadiusTarget, |
| 0, diagonalLength(mCanvasWidth, mCanvasHeight)/2, |
| 0, DRAWABLE_MAX_LEVEL); |
| final ValueAnimator animator = |
| ValueAnimator.ofInt(getLevel(), smallLevel); |
| animator.setDuration(CIRCLE_ANIM_DURATION_MS); |
| animator.setInterpolator(Gusterpolator.INSTANCE); |
| animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
| @Override |
| public void onAnimationUpdate(ValueAnimator animation) { |
| setLevel((Integer) animation.getAnimatedValue()); |
| } |
| }); |
| animator.start(); |
| } |
| |
| public void animateToFullSize() { |
| final ValueAnimator animator = |
| ValueAnimator.ofInt(getLevel(), DRAWABLE_MAX_LEVEL); |
| animator.setDuration(CIRCLE_ANIM_DURATION_MS); |
| animator.setInterpolator(Gusterpolator.INSTANCE); |
| animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
| @Override |
| public void onAnimationUpdate(ValueAnimator animation) { |
| setLevel((Integer) animation.getAnimatedValue()); |
| } |
| }); |
| animator.start(); |
| } |
| |
| @Override |
| public void draw(Canvas canvas) { |
| mCanvasWidth = canvas.getWidth(); |
| mCanvasHeight = canvas.getHeight(); |
| |
| mRadius = map(getLevel(), 0, DRAWABLE_MAX_LEVEL, |
| 0, diagonalLength(canvas.getWidth(), canvas.getHeight())/2); |
| canvas.drawCircle(canvas.getWidth()/2.0f, canvas.getHeight()/2.0f, |
| mRadius, mPaint); |
| } |
| |
| /** |
| * Maps a given value x from one input range [in_min, in_max] to |
| * another output range [out_min, out-max]. |
| * @param x Value to be mapped. |
| * @param in_min Input range minimum. |
| * @param in_max Input range maximum. |
| * @param out_min Output range minimum. |
| * @param out_max Output range maximum. |
| * @return The mapped value. |
| */ |
| private static int map(int x, int in_min, int in_max, int out_min, int out_max) { |
| return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; |
| } |
| |
| private static int diagonalLength(int w, int h) { |
| return (int) Math.sqrt((w*w) + (h*h)); |
| } |
| } |