Created
October 11, 2014 23:33
-
-
Save homj/f7805d744e7bd3be0432 to your computer and use it in GitHub Desktop.
I'm getting hungry!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2014 Johannes Homeier | |
* | |
* 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 de.twoid.drawericondrawabletest; | |
import android.graphics.Canvas; | |
import android.graphics.ColorFilter; | |
import android.graphics.Paint; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.graphics.drawable.Drawable; | |
public class HamburgerIconDrawable extends Drawable { | |
public static final int STATE_DRAWER = 0; | |
public static final int STATE_ARROW = 1; | |
private static final float BURGER_SIZE = 18f; | |
private static final float SESAME_SIZE = 0.4f; | |
private static final float SALAD_THIKNESS = 0.2f; | |
private static final float SAUCE_THIKNESS = 0.2f; | |
private static final float BUN_THIKNESS = 2f; | |
private static final float PATTY_THIKNESS = 1.6f; | |
private static final int SESAMECOUNT = 7; | |
private static final float COMBINED_SESAME_WIDTH = SESAMECOUNT*SESAME_SIZE; | |
private static final float SESAME_SPACING = (BURGER_SIZE-COMBINED_SESAME_WIDTH)/7; | |
private static final float SESAME_INIT_LEFT = 15+SESAME_SPACING/2; | |
private static final float LEVEL_BREAKPOINT = 0.5f; | |
//level of the animation | |
private float level; | |
//Dimensions | |
private float scale = 3; | |
private int width; | |
private int height; | |
private int offsetX; | |
//Drawing-Objects | |
private Paint mPattyPaint; | |
private Paint mSaucePaint; | |
private Paint mSaladPaint; | |
private Paint mTopBunPaint; | |
private Paint mBottomBunPaint; | |
private Paint mSesamePaint; | |
private RectF topBunRect; | |
private RectF saladRect; | |
private RectF sauceRect; | |
private RectF pattyRect; | |
private RectF bottomBunRect; | |
private RectF sesameRect; | |
private boolean breakpointReached = false; | |
/** | |
* Create a new DrawerIconDrawable with size @param size in pixel | |
* @param size | |
*/ | |
public HamburgerIconDrawable(int size){ | |
this(size, size); | |
} | |
/** | |
* Create a new DrawerIconDrawable with width @param width and height @param height in pixel | |
*/ | |
public HamburgerIconDrawable(int width, int height){ | |
this(width, height, 0); | |
} | |
/** | |
* Create a new DrawerIconDrawable with width @param width and height @param height, and X-offset @param offsetX in pixel | |
*/ | |
public HamburgerIconDrawable(int width, int height, int offsetX){ | |
this.width = width; | |
this.height = height; | |
this.offsetX = offsetX; | |
scale = Math.min(width, height)/48; | |
setBounds(new Rect(0, 0, width, height)); | |
mPattyPaint = new Paint(); | |
mPattyPaint.setAntiAlias(true); | |
mPattyPaint.setColor(0xff896a5f); | |
mSaucePaint = new Paint(); | |
mSaucePaint.setAntiAlias(true); | |
mSaucePaint.setColor(0xfff65140); | |
mSaladPaint = new Paint(); | |
mSaladPaint.setAntiAlias(true); | |
mSaladPaint.setColor(0xff5ab33f); | |
mTopBunPaint = new Paint(); | |
mTopBunPaint.setAntiAlias(true); | |
mTopBunPaint.setColor(0xfffab965); | |
mBottomBunPaint = new Paint(); | |
mBottomBunPaint.setAntiAlias(true); | |
mBottomBunPaint.setColor(0xfff89923); | |
mSesamePaint = new Paint(); | |
mSesamePaint.setAntiAlias(true); | |
mSesamePaint.setColor(0xfffdd063); | |
topBunRect = new RectF(); | |
pattyRect = new RectF(); | |
sauceRect = new RectF(); | |
saladRect = new RectF(); | |
bottomBunRect = new RectF(); | |
sesameRect = new RectF(); | |
setLevel(0); | |
} | |
@Override | |
public void draw(Canvas canvas) { | |
canvas.translate(offsetX, 0); | |
drawBottomBun(canvas); | |
drawPattyAndStuff(canvas); | |
drawTopBun(canvas); | |
} | |
private void drawTopBun(Canvas canvas){ | |
float scaleFactor = level < LEVEL_BREAKPOINT ? level*2 : (level-0.5f)*2; | |
canvas.save(); | |
offsetTopBun(3*scale*scaleFactor, 0, -3*scale*scaleFactor, 0); | |
canvas.rotate(level < LEVEL_BREAKPOINT ? level*450 : 225 + (1-level)*270, 24*scale, 24*scale); | |
canvas.drawRect(topBunRect, mTopBunPaint); | |
drawSesame(canvas, scaleFactor); | |
canvas.restore(); | |
} | |
private void drawSesame(Canvas canvas, float scaleFactor) { | |
for(int i = 0;i<7;i++){ | |
offsetSesameRect(i, scaleFactor); | |
canvas.drawRect(sesameRect, mSesamePaint); | |
} | |
} | |
private void drawPattyAndStuff(Canvas canvas){ | |
float scaleFactor = level < LEVEL_BREAKPOINT ? level*2 : (level-0.5f)*2; | |
canvas.save(); | |
offsetPatty(0, 0, -2*scale*scaleFactor, 0); | |
canvas.rotate(level < LEVEL_BREAKPOINT ? level*360 : 180 + (1-level)*360, 24*scale, 24*scale); | |
canvas.drawRect(pattyRect, mPattyPaint); | |
canvas.drawRect(sauceRect, mSaucePaint); | |
canvas.drawRect(saladRect, mSaladPaint); | |
canvas.restore(); | |
} | |
private void drawBottomBun(Canvas canvas){ | |
float scaleFactor = level < LEVEL_BREAKPOINT ? level*2 : (level-0.5f)*2; | |
canvas.save(); | |
offsetBottomBun(3*scale*scaleFactor, 0, -3*scale*scaleFactor, 0); | |
canvas.rotate(level < LEVEL_BREAKPOINT ? level*270 : 135 + (1-level)*450, 24*scale, 24*scale); | |
canvas.drawRect(bottomBunRect, mBottomBunPaint); | |
canvas.restore(); | |
} | |
private void offsetSesameRect(int i, float scaleFactor){ | |
float shrunkenSesameSpacing = SESAME_SPACING - 6*scaleFactor*3f/BURGER_SIZE; | |
sesameRect.set( | |
SESAME_INIT_LEFT*scale + 3*scaleFactor*scale + i*(shrunkenSesameSpacing +SESAME_SIZE)*scale | |
,BURGER_SIZE*scale | |
, (SESAME_INIT_LEFT+SESAME_SIZE)*scale + 3*scaleFactor*scale + i*(shrunkenSesameSpacing +SESAME_SIZE)*scale | |
, (BURGER_SIZE+SESAME_SIZE)*scale); | |
} | |
private void offsetTopBun(float offsetLeft, float offsetTop, float offsetRight, float offsetBottom){ | |
topBunRect.set( | |
15*scale + offsetLeft | |
,18*scale + offsetTop | |
, (15+BURGER_SIZE)*scale + offsetRight | |
, (18+BUN_THIKNESS)*scale + offsetBottom | |
); | |
} | |
private void offsetPatty(float offsetLeft, float offsetTop, float offsetRight, float offsetBottom){ | |
saladRect.set( | |
15*scale + offsetLeft | |
,23*scale + offsetTop | |
, (15+BURGER_SIZE)*scale + offsetRight | |
, (23+SALAD_THIKNESS)*scale + offsetBottom | |
); | |
sauceRect.set( | |
15*scale + offsetLeft | |
,(23+SALAD_THIKNESS)*scale + offsetTop | |
, (15+BURGER_SIZE)*scale + offsetRight | |
, (23+SALAD_THIKNESS+SAUCE_THIKNESS)*scale + offsetBottom | |
); | |
pattyRect.set( | |
15*scale + offsetLeft | |
,(23+SALAD_THIKNESS+SAUCE_THIKNESS)*scale + offsetTop | |
, (15+BURGER_SIZE)*scale + offsetRight | |
, (23+SALAD_THIKNESS+SAUCE_THIKNESS+PATTY_THIKNESS)*scale + offsetBottom | |
); | |
} | |
private void offsetBottomBun(float offsetLeft, float offsetTop, float offsetRight, float offsetBottom){ | |
bottomBunRect.set( | |
15*scale + offsetLeft | |
,28*scale + offsetTop | |
, (15+BURGER_SIZE)*scale + offsetRight | |
, (28+BUN_THIKNESS)*scale + offsetBottom | |
); | |
} | |
@Override | |
public void setAlpha(int alpha) { | |
mPattyPaint.setAlpha(alpha); | |
invalidateSelf(); | |
} | |
@Override | |
public void setColorFilter(ColorFilter cf) { | |
mPattyPaint.setColorFilter(cf); | |
invalidateSelf(); | |
} | |
@Override | |
public int getOpacity() { | |
return 0; | |
} | |
/** | |
* set the state of the Drawable; | |
* @param level | |
*/ | |
public void setState(int state){ | |
switch(state){ | |
case STATE_DRAWER: | |
setLevel((float) STATE_DRAWER); | |
break; | |
case STATE_ARROW: | |
setLevel((float) STATE_ARROW); | |
break; | |
} | |
} | |
/** | |
* set the level of the animation; drawer indicator is fully displayed at 0; arrow is fully displayed at 1 | |
* @param level | |
*/ | |
public void setLevel(float level){ | |
if(level == 1) breakpointReached = true; | |
if(level == 0) breakpointReached = false; | |
this.level = (breakpointReached ? LEVEL_BREAKPOINT : 0) + level/2; | |
invalidateSelf(); | |
} | |
@Override | |
public int getIntrinsicWidth() { | |
return width; | |
} | |
@Override | |
public int getIntrinsicHeight() { | |
return height; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment