import ketai.sensors.KetaiSensor; import android.content.Context; import android.app.Notification; import android.app.NotificationManager; KetaiSensor sensor; PShader blur; String timeString = ""; PVector center; PVector shadowOffset; PVector fontPosition; PGraphics shadowText; //setting for how much the shadow can move away from center int shadowSize = 15; final float EARTH_GRAVITY = 9.8; public void setup() { //render method must be P2D fullScreen(P2D); //size(360, 360, P2D); orientation(PORTRAIT); //load in glsl shader for blurring blur = loadShader("sepblur.glsl"); background(0, 0, 0); noStroke(); textAlign(CENTER); textSize((int)(width/4)); text("loading", width/2, height/2 + (textAscent() / 2)); reset(); } private void reset() { center = new PVector(width/2, height/2); fontPosition = new PVector(center.x, center.y + (textAscent() / 2)); shadowOffset = new PVector(); shadowText = createGraphics(width, height, P2D); shadowText.beginDraw(); shadowText.textAlign(CENTER); shadowText.textSize((int)(width/4)); shadowText.fill(0, 0, 0); shadowText.endDraw(); sensor = new KetaiSensor(this); sensor.start(); } public void draw() { /********** * update * **********/ timeString = getTimeString(); /******** * draw * ********/ //clear frame background(0, 0, 0); //draw clockface fill(128, 128, 128); ellipse(center.x, center.y, width, width); //draw time shadow shadowText.beginDraw(); shadowText.clear(); shadowText.text(timeString, fontPosition.x + shadowOffset.x, fontPosition.y + shadowOffset.y); doBlur(shadowText); shadowText.endDraw(); image(shadowText, 0, 0); //draw time fill(255, 255, 255); text(timeString, fontPosition.x, fontPosition.y); } private void doBlur(PGraphics graphics) { //set blur settings blur.set("blurSize", 9); blur.set("sigma", 5.0f); blur.set("horizontalPass", 1); //apply horizontal blur graphics.filter(blur); //apply vertical blur blur.set("horizontalPass", 0); graphics.filter(blur); } private String addZeroPrefix(int value) { if (value < 10) { return "0" + value; } return "" + value; } private String getTimeString() { //24 hour, 0-padded time return addZeroPrefix(hour()) + ":" + addZeroPrefix(minute()) + ":" + addZeroPrefix(second()); } public void onAccelerometerEvent(float x, float y, float z, long timestamp, int accuracy) { //accelerometer data in m/s^2 , divided by the force of gravity on earth //light source is assumed to be directly above, so "down" determines where the shadow should go shadowOffset.set(shadowSize * (-x / EARTH_GRAVITY), shadowSize * (y / EARTH_GRAVITY), 0); } //android specific called method when app is put in background public void onPause() { super.onPause(); sensor.stop(); } //android specific called method when app is put in foreground public void onResume() { super.onResume(); reset(); }