Skip to content

Instantly share code, notes, and snippets.

@homj
Created October 11, 2014 23:33
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save homj/f7805d744e7bd3be0432 to your computer and use it in GitHub Desktop.
Save homj/f7805d744e7bd3be0432 to your computer and use it in GitHub Desktop.
I'm getting hungry!
/*
* 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