Skip to content

Instantly share code, notes, and snippets.

@christinapetris
Forked from dribnet/.block
Last active March 21, 2017 06:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christinapetris/a362c4443e4e8673ae386cc7614493ea to your computer and use it in GitHub Desktop.
Save christinapetris/a362c4443e4e8673ae386cc7614493ea to your computer and use it in GitHub Desktop.
17.1.MDDN242 PS1
license: mit
// note: this file is poorly named - it can generally be ignored.
// helper functions below for supporting blocks/purview
function saveBlocksImages(doZoom) {
if(doZoom == null) {
doZoom = false;
}
// generate 960x500 preview.jpg of entire canvas
// TODO: should this be recycled?
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 960;
offscreenCanvas.height = 500;
var context = offscreenCanvas.getContext('2d');
// background is flat white
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 960, 500);
context.drawImage(this.canvas, 0, 0, 960, 500);
// save to browser
var downloadMime = 'image/octet-stream';
var imageData = offscreenCanvas.toDataURL('image/jpeg');
imageData = imageData.replace('image/jpeg', downloadMime);
p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');
// generate 230x120 thumbnail.png centered on mouse
offscreenCanvas.width = 230;
offscreenCanvas.height = 120;
// background is flat white
context = offscreenCanvas.getContext('2d');
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 230, 120);
if(doZoom) {
// pixelDensity does the right thing on retina displays
var pd = this._pixelDensity;
var sx = pd * mouseX - pd * 230/2;
var sy = pd * mouseY - pd * 120/2;
var sw = pd * 230;
var sh = pd * 120;
// bounds checking - just displace if necessary
if (sx < 0) {
sx = 0;
}
if (sx > this.canvas.width - sw) {
sx = this.canvas.width - sw;
}
if (sy < 0) {
sy = 0;
}
if (sy > this.canvas.height - sh) {
sy = this.canvas.height - sh;
}
// save to browser
context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
}
else {
// now scaledown
var full_width = this.canvas.width;
var full_height = this.canvas.height;
context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
}
imageData = offscreenCanvas.toDataURL('image/png');
imageData = imageData.replace('image/png', downloadMime);
p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
}

PS1 MDDN 242 2017

Battery Clock

In the beginning I wanted to focus on having a digital clock where you could more visually see the time passing by like an hour glass. I expanded this idea and thought about other ways I could show time passing in a day. As I did some research on clocks I was also influenced by the circadium rythm idea. So loosely encorporated this idea of time shown as energy with a battery clock.

I think it is quite interesting in that it could encourage people to sleep before their energy runs out at midnight to be able to recharge.

The second task where we had to recreate one of Maeda's clocks, I created a digital clock which displays with a forloop. This was a good way for me remember what I had learnt before.

For the third task I managed to create a basic version of my initial idea. Here I was able to use the map function successfully to make the battery bar and percentage change over time accordingly.

For the fourth task I included the alarm function. At first I was just going to make the sketch flash red. But I thought the shaking would be more dynamic and interesting. I am glad I included this feature.

I also included a lot of changing elements which relied on the map function including moving clouds, changing colour background and appearing/disappearing stars.

As I debugged I found an error with the mapping where the percentage would go over 100, the battery bar would become too big and my whole sketch just crashed sometimes. But with the right calculations to make hour2 = hour + (minute / 60) + (second/(60*60)); this was fixed.

Another issue I kept having is wondering how to make the clouds and stars. Ideally I would have liked to have used a random number generator to have different clouds each time. However, when using random it would animate and keep redrawing each second. So I delved into arrays to see if it would make it better. Despite this taking longer, I am happy with the result. If I had more time I would like to know a better way of doing this.

/*
* us p5.js to draw a clock on a 960x500 canvas
*/
function draw_clock(hour, minute, second, millis, alarm) {
textSize(80);
background(169, 201, 209);
//////to make clouds and other thing move smoother (for every second)
// if (hour == 23 && minute ==59 ){
// hour2 = hour +(minute/59);
// }
hour2 = hour + (minute / 60) + (second/(60*60));
//////background change depending on time
var posOpacity;
//////optionA background getting light at 6am
// if (hour2 > 6 ){
// posOpacity= map(hour2, 6, 7, 255, 0);
// }
// if (hour2 > 18 ){
// posOpacity= map(hour2, 18, 19, 0, 255);
// }
//////optionB background getting light from midnight
if (hour2 < 12){
posOpacity= map(hour2, 0, 11, 255, 0);
}
else {
posOpacity= map(hour2, 12, 24, 0, 255);
}
background(14,15,52, posOpacity);
//////for position of clouds moving from left to right
var posXC;
if (hour2 > 6) {
posXC = map(hour2, 6, 17, 960, -1200);
}
else {
posXC = 1250;
}
fill(252,243,229);
//////clouds
clouds(posXC,-10);
clouds(posXC+800, 0);
//////stars appear from 20:00 -> 22:00
var opacityStars;
if (hour2 > 20) {
opacityStars = map(hour2, 20, 22, 0, 255);
}
//////stars go away from 4:00 ->6:00
else if (hour2 >4) {
opacityStars = map(hour2, 4, 6, 255, 0);
}
stars(opacityStars);
//////Battery
noStroke();
fill(255);
var shakeX=random(-10,10);
var shakeY=random(-10,10);
//if alarm is going off, battery shakes and flashes red
if (alarm == 0) {
translate(shakeX, shakeY);
if (second % 2 == 0) {
fill(255,54,51, 255);
}
}
//alarm build up shake
if (alarm > 0) {
if (alarm < 15.0) {
var shakeX = map(alarm, 0, 15, 10, 0);
var shakeY = map(alarm, 0, 15, 10, 0);
var buildShakeX = random(shakeX);
var buildShakeY = random(shakeY);
translate(buildShakeX, buildShakeY);
}}
//////verySmallRectangle (makes battery)
rect(900, 195, 33, 110, 15, 15);
//////batteryBar
if (alarm == 0) {
//flashes transparent red
if (second % 2 == 0) {
fill(255,54,51, 100);
}
}
////battery getting bigger from 00:00 -> 12:00 and smaller from 12:00 -> 00:00
var pos;
if (hour2 > 12 ) {
pos = map(hour2, 12, 24, 430, 0);
}
else {
pos = map(hour2, 0, 12, 0, 430);
}
print(hour2);
rect(460, 165, pos, 170, 10, 10);
//////bigRectOnlyStroke (edge of battery)
stroke(255);
fill(0,0);
strokeWeight(13);
//flashes red on alarm
if (alarm == 0) {
if (second % 2 == 0) {stroke(255,54,51, 255);}
}
rect(445, 150, 460, 200, 15, 15);
noStroke();
//////lightning bolt flashes when charging from 00:00 -> 12:00
if (second % 2== 0) {
if (hour2 < 12) {
fill(255,248,205);
beginShape();
vertex(660, 180);
vertex(660, 240);
vertex(560, 220);
vertex(700, 320);
vertex(700, 260);
vertex(790, 280);
endShape(CLOSE);
}
}
//////digitalclock
fill(255, 207, 0);
if (alarm == 0){
textStyle(BOLD);
}
else{
textStyle(NORMAL);
}
textAlign(LEFT);
var sec_string = "";
if(second < 10) {
sec_string = "0";
}
var min_string = "";
if(minute < 10) {
min_string = "0";
}
var hour_string = "";
if(hour < 10) {
hour_string = "0";
}
sec_string = sec_string + second;
min_string = min_string + minute;
hour_string = hour_string + hour;
text(hour_string + ':' + min_string + ':' + sec_string, 514, 278);
//////percentage sign
textStyle(NORMAL);
fill(255);
// changes to red on alarm
if (alarm == 0) {
if (second % 2 == 0) {
fill(255,54,51, 255);
}
}
//percentage going up to 100 from 00:00 -> 12:00 then goes down to 0 from 12:00 ->24:00
var posPercentage;
if (hour2 < 12) {
posPercentage = map(hour2, 0, 12, 0, 100);
}
else {
posPercentage = map(hour2, 12, 24, 100, 0);
}
textSize(150);
textAlign(RIGHT);
text(int(posPercentage) + '%', 413, 305);
}
function stars(opacityStars){
fill(255, 235, 147, opacityStars);
var starX = [349,458,626,532,606,396,422,758,793,217,578,142,490,76,64,734,873,1,836,362,156,613,161,36,78,441,40,190,315,120,7,63,83,740,155]
var starY = [311,95,461,176,45,242,105,421,121,492,111,462,427,180,297,5,439,243,106,164,276,44,411,89,229,349,103,171,190,398,77,28,262,451,73]
for (var n = 0; n < 36; n++) {
ellipse(starX[n], starY[n], random(0,2), random(0,10));
ellipse(starX[n], starY[n], random(0,10), random(0,2));
ellipse(starX[n]+50, starY[n]+50, random(0,2), random(0,1));
ellipse(starX[n]+50, starY[n]+50, random(0,1), random(0,2));
ellipse(starX[n]+200, starY[n]+100, random(0,2), random(0,1));
ellipse(starX[n]+200, starY[n]+100, random(0,1), random(0,2));
ellipse(starX[n], starY[n]+100, random(0,2), random(0,1));
ellipse(starX[n], starY[n]+100, random(0,1), random(0,2));
ellipse(starX[n]+250, starY[n], random(0, 2), random(0,15));
ellipse(starX[n]+250, starY[n], random(0, 15), random(0,2));
ellipse(starX[n]+820, starY[n], random(0, 2), random(0,5));
ellipse(starX[n]+820, starY[n], random(0, 5), random(0,2));
ellipse(starX[n], starY[n]+300, random(0, 2), random(0,5));
ellipse(starX[n], starY[n]+300, random(0, 5), random(0,2));
}
}
function clouds(posX,y){
for (var i = 0; i < 8; i++) {
var cloudX = [100,125,125,155,155,178,186]
var cloudY = [100,80,118,85,125,93,115]
var cloudW = [50,40,65,60,60,60,60]
var cloudH = [50,65,60,60,60,60,40]
var cloudW2 = [80,60,68,62,62,80,70]
var cloudH2 = [60,52,68,66,42,42,42]
var cloudW3 = [100,80,80,85,60,80,80]
var cloudH3 = [70,72,90,94,90,60,50]
ellipse(cloudX[i] -posX, cloudY[i]+y, cloudW[i], cloudH[i]);
ellipse(cloudX[i] -posX +500, cloudY[i]+200 +y, cloudW[i], cloudH[i]);
ellipse(cloudX[i] -posX +300, cloudY[i]+370 +y, cloudW3[i], cloudH3[i]);
ellipse(cloudX[i] -posX +700, cloudY[i]+100 +y, cloudW2[i], cloudH2[i]);
ellipse(cloudX[i] -posX +420, cloudY[i]+30 +y, cloudW2[i], cloudH2[i]);
ellipse(cloudX[i] -posX +90, cloudY[i]+170 +y, cloudW[i], cloudH[i]);
}
}
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="debug.js"></script>
<script language="javascript" type="text/javascript" src="clock.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
<div class="inner" id="controls">
<table>
<tr>
<td>debug</td>
<td id="checkboxDebug"></td>
</tr>
<tr>
<td>hours</td>
<td id="sliderHours"></td>
<td>minutes</td>
<td id="sliderMinutes"></td>
<td>seconds</td>
<td id="sliderSeconds"></td>
<td>millis</td>
<td id="sliderMillis"></td>
</tr>
<tr>
<td>alarm</td>
<td id="checkboxAlarm"></td>
<td>alarm_secs</td>
<td id="sliderAlarm"></td>
</tr>
</table>
</div>
</div>
</table>
</body>
var DEBUG=true;
var debugCheckbox;
var hourSlider;
var minSlider;
var secSlider;
var millisSlider;
var alarmSlider;
function debug_setup() {
debugCheckbox = createCheckbox('', false);
debugCheckbox.parent("checkboxDebug")
hourSlider = createSlider(0, 23, 12);
hourSlider.parent("sliderHours")
minSlider = createSlider(0, 59, 0);
minSlider.parent("sliderMinutes")
secSlider = createSlider(0, 59, 0);
secSlider.parent("sliderSeconds")
millisSlider = createSlider(0, 999, 0);
millisSlider.parent("sliderMillis")
alarmCheckbox = createCheckbox('', false);
alarmCheckbox.parent("checkboxAlarm")
alarmSlider = createSlider(0, 60, 0);
alarmSlider.parent("sliderAlarm")
}
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="clock.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
</div>
</table>
</body>
{
"commits": [
{
"sha": "29ef822f92f12edf4e5303df357177e3214111e8",
"name": "final"
},
{
"sha": "b13f7f83620b0efd05e60c69c731d3d47150b54e",
"name": "clock_alarm"
},
{
"sha": "bd29ce60a1cc47de102d485ccc1091d4479553ff",
"name": "original_clock"
},
{
"sha": "047087c6bf1589003603e995b9f8291c5b1f8469",
"name": "maeda_clock"
},
{
"sha": "09c16f8cc4cea618d061d19e906659fe6eba5f17",
"name": "sketch"
}
]
}
var canvasWidth = 960;
var canvasHeight = 500;
var prevSec;
var millisRolloverTime;
var nextAlarm;
var debug_is_on = (typeof DEBUG !== 'undefined');
function setup () {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
// this is true if debug.js is included
if(debug_is_on) {
debug_setup();
}
turn_off_alarm();
}
function turn_on_alarm() {
nextAlarm = millis() + 20000;
print("Alarm on: T minus 20 seconds");
}
function turn_off_alarm() {
nextAlarm = -1;
print("Alarm turned off");
}
function mouseClicked() {
if (debug_is_on && debugCheckbox.checked()) {
return;
}
if (nextAlarm > 0) {
turn_off_alarm();
}
else {
turn_on_alarm();
}
}
// taking ideas from http://cmuems.com/2016/60212/deliverables/deliverables-02/
function draw () {
var H, M, S, mils, alarm;
if (debug_is_on && debugCheckbox.checked()) {
hourSlider.removeAttribute('disabled');
minSlider.removeAttribute('disabled');
secSlider.removeAttribute('disabled');
millisSlider.removeAttribute('disabled');
alarmCheckbox.removeAttribute('disabled');
alarmSlider.removeAttribute('disabled');
H = hourSlider.value();
M = minSlider.value();
S = secSlider.value();
mils = millisSlider.value();
if (alarmCheckbox.checked()) {
alarm = alarmSlider.value();
}
else {
alarm = -1;
}
}
else {
// Fetch the current time
H = hour();
M = minute();
S = second();
if (nextAlarm > 0) {
now = millis();
var millis_offset = nextAlarm - now;
if (millis_offset < -10000 ){
// turn off alarm
nextAlarm = -1;
alarm = -1;
}
else if (millis_offset < 0) {
alarm = 0;
}
else {
alarm = millis_offset / 1000.0;
}
}
else {
alarm = -1;
}
// Reckon the current millisecond,
// particularly if the second has rolled over.
// Note that this is more correct than using millis()%1000;
if (prevSec != S) {
millisRolloverTime = millis();
}
prevSec = S;
mils = floor(millis() - millisRolloverTime);
if (debug_is_on) {
hourSlider.attribute('disabled','');
minSlider.attribute('disabled','');
secSlider.attribute('disabled','');
millisSlider.attribute('disabled','');
alarmCheckbox.attribute('disabled','');
alarmSlider.attribute('disabled','');
hourSlider.value(H);
minSlider.value(M);
secSlider.value(S);
millisSlider.value(mils);
alarmCheckbox.checked(alarm >= 0);
alarmSlider.value(alarm);
}
}
draw_clock(H, M, S, mils, alarm);
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment