Skip to content

Instantly share code, notes, and snippets.

@uwcc
Last active July 5, 2023 22:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 33 You must be signed in to fork a gist
  • Save uwcc/9374a9f850dd38c4f0436083f04a5664 to your computer and use it in GitHub Desktop.
Save uwcc/9374a9f850dd38c4f0436083f04a5664 to your computer and use it in GitHub Desktop.
Creative Coding 2: Project 1_Clock

MDDN 242 Project 1: Time-based Media

THIS IS YOUR README

Update this file as you go along to record your progress.

{
"commits": [
{
"sha": "0000000000000000000000000000000000000001",
"name": "Final"
},
{
"sha": "0000000000000000000000000000000000000002",
"name": "Alarm"
},
{
"sha": "0000000000000000000000000000000000000003",
"name": "Clock"
},
{
"sha": "0000000000000000000000000000000000000004",
"name": "maeda_clock"
},
{
"sha": "0000000000000000000000000000000000000005",
"name": "sketch"
}
]
}
<!-- This HTML file displays your original Clock -->
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="clock.js"></script>
<script language="javascript" type="text/javascript" src="runner.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.0;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
<a href="part1.html">part1</a>
<a href="part2.html">part2</a>
<a href="clock.html">clock</a>
<a href="debug.html">debug</a>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>Timer</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Alarm Set</td>
<td id="checkContainer1"></td>
</tr>
<tr>
<td>Alarm Active</td>
<td id="checkContainer2"></td>
</tr>
</table>
</div>
</div>
<br>
</body>
/*
* use p5.js to draw a clock on a 960x500 canvas
*/
function draw_clock(obj) {
// draw your own clock here based on the values of obj:
// obj.hours goes from 0-23
// obj.minutes goes from 0-59
// obj.seconds goes from 0-59
// obj.millis goes from 0-999
// obj.seconds_until_alarm is:
// < 0 if no alarm is set
// = 0 if the alarm is currently going off
// > 0 --> the number of seconds until alarm should go off
background(50); // beige
fill(200); // dark grey
textSize(40);
textAlign(CENTER, CENTER);
text("YOUR MAIN CLOCK CODE GOES HERE", width / 2, 200);
fill(249, 140, 255);// pink
ellipse(width / 3, 350, 150);
fill(140, 255, 251) // blue
ellipse(width / 2, 350, 150);
fill(175, 133, 255); // purple
ellipse(width / 3 * 2, 350, 150);
}
/*
* This is some example code
* use p5.js to draw a clock on a 960x500 canvas
*/
function draw_clock(obj) {
// draw your own clock here based on the values of obj:
// obj.hours goes from 0-23
// obj.minutes goes from 0-59
// obj.seconds goes from 0-59
// obj.millis goes from 0-999
// obj.seconds_until_alarm is:
// < 0 if no alarm is set
// = 0 if the alarm is currently going off
// > 0 --> the number of seconds until alarm should go off
background(0);
const ballWidth = 100;
fill(255, 255, 0);
let secs = obj.seconds;
let millis = obj.millis;
let exactSeconds = secs + millis / 1000.0;
posX = map(exactSeconds, 0, 60, ballWidth/2, width-ballWidth/2);
posY = map(60, 0, 100, 0, height);
ellipse(posX, posY, ballWidth);
fill(255);
posX = map(obj.minutes, 0, 59, ballWidth/2, width-ballWidth/2);
posY = map(40, 0, 100, 0, height);
ellipse(posX, posY, ballWidth);
posX = map(obj.hours, 0, 23, ballWidth/2, width-ballWidth/2);
posY = map(20, 0, 100, 0, height);
ellipse(posX, posY, ballWidth);
}
/*
* This is some example code
* us p5.js to draw a clock on a 960x500 canvas
*/
function draw_clock(obj) {
// draw your own clock here based on the values of obj:
// obj.hours goes from 0-23
// obj.minutes goes from 0-59
// obj.seconds goes from 0-59
// obj.millis goes from 0-999
// obj.seconds_until_alarm is:
// < 0 if no alarm is set
// = 0 if the alarm is currently going off
// > 0 --> the number of seconds until alarm should go off
let hours = obj.hours;
let minutes = obj.minutes;
let seconds = obj.seconds;
let millis = obj.millis;
let alarm = obj.seconds_until_alarm;
background(255,255,200); // beige
fill(128,100,100); // dark grey
text("Hour: " + hours, 10, 22);
text("Minute: " + minutes, 10, 42);
text("Second: " + seconds, 10, 62);
text("Millis: " + millis, 10, 82);
let hourBarWidth = map(hours, 0, 23, 0, width);
let minuteBarWidth = map(minutes, 0, 59, 0, width);
let secondBarWidth = map(seconds, 0, 59, 0, width);
let millisBarWidth = map(millis, 0, 1000, 0, width);
noStroke();
fill(40);
rect(0, 100, hourBarWidth, 50);
fill(80);
rect(0, 150, minuteBarWidth, 50);
fill(120)
rect(0, 200, secondBarWidth, 50);
fill(160)
rect(0, 250, millisBarWidth, 50);
// Make a bar which *smoothly* interpolates across 1 minute.
// We calculate a version that goes from 0...60,
// but with a fractional remainder:
let secondBarWidthChunky = map(seconds, 0, 59, 0, width);
let secondsWithFraction = seconds + (millis / 1000.0);
let secondBarWidthSmooth = map(secondsWithFraction, 0, 60, 0, width);
fill(100, 100, 200)
rect(0, 350, secondBarWidthChunky, 50);
fill(120, 120, 240)
rect(0, 400, secondBarWidthSmooth, 50);
text("Minute: " + secondsWithFraction, 200, 42);
fill(200, 100, 100)
let alarm_message = ""
if(alarm < 0) {
alarm_message = "Alarm: Not Set"
}
else if(alarm == 0) {
alarm_message = "Alarm: GOING OFF"
}
else {
let seconds_remaining = int(alarm);
alarm_message = "Alarm: will go off in " + seconds_remaining + " seconds"
}
text(alarm_message, 400, 42);
}
<!-- This HTML file displays the debug page -->
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
<script language="javascript" type="text/javascript" src="z_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="runner.js"></script>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>Timer</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Alarm Set</td>
<td id="checkContainer1"></td>
</tr>
<tr>
<td>Alarm Active</td>
<td id="checkContainer2"></td>
</tr>
</table>
</div>
</div>
<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>
</table>
</div>
</div>
</body>
<br>
<a href="part1.html">part1</a>
<a href="part2.html">part2</a>
<a href="clock.html">clock</a>
<a href="debug.html">debug</a>
</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")
}
<!-- This HTML file displays the sketch -->
<head>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="sketch.jpg" width="960" height="500"/>
<br>
<a href="part1.html">part1</a>
<a href="part2.html">part2</a>
<a href="clock.html">clock</a>
<a href="debug.html">debug</a>
</body>
// Update this function to draw you own maeda clock on a 960x500 canvas
function draw_clock(obj) {
// YOUR MAIN CLOCK CODE GOES HERE
background(50); // beige
fill(200); // dark grey
textSize(40);
textAlign(CENTER, CENTER);
text("YOUR MAEDA CLOCK CODE GOES HERE", width/2, height/2);
}
<!-- This HTML file displays the sketch -->
<head>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="sketch.jpg" width="960" height="500"/>
<br>
<a href="part1.html">part1</a>
<a href="part2.html">part2</a>
<a href="clock.html">clock</a>
<a href="debug.html">debug</a>
</body>
<!-- This HTML file displays your Maeda Clock -->
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="maeda_clock.js"></script>
<script language="javascript" type="text/javascript" src="runner.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.0;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
<a href="part1.html">part1</a>
<a href="part2.html">part2</a>
<a href="clock.html">clock</a>
<a href="debug.html">debug</a>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>Timer</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Alarm Set</td>
<td id="checkContainer1"></td>
</tr>
<tr>
<td>Alarm Active</td>
<td id="checkContainer2"></td>
</tr>
</table>
</div>
</div>
<br>
</body>
const canvasWidth = 960;
const canvasHeight = 500;
let prevSec;
let millisRolloverTime;
let nextAlarm;
let debug_is_on = (typeof DEBUG !== 'undefined');
let alarmOverlayCheckbox;
let alarmOverlaySlider;
let defaultAlarmSliderValue=15;
function setup () {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
alarmOverlaySlider = createSlider(0, 30, defaultAlarmSliderValue);
alarmOverlaySlider.parent("slider1Container")
alarmOverlaySlider.changed(sliderUpdated);
alarmOverlaySlider.mouseMoved(sliderUpdated);
alarmOverlaySlider.touchMoved(sliderUpdated);
alarmOverlayCheckbox = createCheckbox('', false);
alarmOverlayCheckbox.parent('checkContainer1');
alarmOverlayCheckbox.changed(guideChangedEvent);
alarmActiveCheckbox = createCheckbox('', false);
alarmActiveCheckbox.parent('checkContainer2');
alarmActiveCheckbox.attribute('disabled','');
// this is true if debug.js is included
if(debug_is_on) {
debug_setup();
}
turn_off_alarm();
}
function sliderUpdated() {
defaultAlarmSliderValue = alarmOverlaySlider.value();
// print("Updated defaultAlarmSliderValue to " + defaultAlarmSliderValue)
}
function guideChangedEvent() {
let alarmIsOn = alarmOverlayCheckbox.checked();
if(alarmIsOn) {
turn_on_alarm();
}
else {
turn_off_alarm();
}
redraw();
}
function turn_on_alarm() {
// disable slider
alarmOverlaySlider.attribute('disabled','');
nextAlarm = millis() + defaultAlarmSliderValue * 1000;
print("Alarm on: T minus " + defaultAlarmSliderValue + " seconds");
}
function turn_off_alarm() {
// enable slider back to default
alarmOverlaySlider.value(defaultAlarmSliderValue);
alarmOverlaySlider.removeAttribute('disabled');
alarmOverlayCheckbox.checked(false);
alarmActiveCheckbox.checked(false);
print("Alarm now off")
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;
turn_off_alarm();
}
else if (millis_offset < 0) {
alarm = 0;
alarmOverlaySlider.value(alarm);
alarmActiveCheckbox.checked(true);
}
else {
alarm = millis_offset / 1000.0;
alarmOverlaySlider.value(alarm);
alarmActiveCheckbox.checked(false);
}
}
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);
}
}
obj = {};
obj.hours = H;
obj.minutes = M;
obj.seconds = S;
obj.millis = mils;
obj.seconds_until_alarm = alarm;
draw_clock(obj);
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
// 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');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment