block by dribnet 5a2b0ae2aa7f9fdc33688717bb41ef58

PS1 MDDN 242 2019

Full Screen

PS1 MDDN 242 2019

Tom Clock

A more complicated example of a digital clock.

index.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.js"></script>
    <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
    <script language="javascript" type="text/javascript" src="clock_tom.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>
</table>
<br>
<a href="part1.html">part1</a> 
<a href="part2.html">part2</a> 
</body>

clock.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.js"></script>
    <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
    <script language="javascript" type="text/javascript" src="clock_tom.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>
</table>
<br>
<a href="part1.html">part1</a> 
<a href="part2.html">part2</a> 
</body>

clock.js

/*
 * 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);
}

clock_bars.js

/*
 * 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);        
}

clock_empty.js

function draw_circle_row(row_height) {
    for (let i = 0; i < 5; i++) {
        // do some stuff here
        ellipse(200 + i*100, row_height, 80, 80);
    }    
}

/*
 * 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

    let main_color = 200;
    const STROKE_COLOR = 100;

    let row_height = 200;

    strokeWeight(8)

    background(main_color);
    fill(main_color);
    stroke(STROKE_COLOR);

    for(row_height = 100; row_height < 600; row_height = row_height + 100) {
        draw_circle_row(row_height);
    }

}

clock_tom.js

/*
 * us p5.js to draw a clock on a 960x500 canvas
 */ 

/* size of square */
const s = 24

let numbers = [
  // 0
  [
    [2, 1],
    [3, 1],
    [1, 2],
    [4, 2],
    [1, 3],
    [4, 3],
    [1, 4],
    [4, 4],
    [2, 5],
    [3, 5],
  ],
  // 1
  [
    [2, 2],
    [3, 1],
    [3, 2],
    [3, 3],
    [3, 4],
    [3, 5]
  ],
  // 2
  [
    [1, 1],
    [2, 1],
    [3, 1],
    [4, 2],
    [4, 3],
    [3, 3],
    [2, 4],
    [1, 5],
    [2, 5],
    [3, 5],
    [4, 5]
  ],
  [ // 3
    [1, 1],
    [2, 1],
    [3, 1],
    [4, 2],
    [3, 3],
    [2, 3],
    [4, 4],
    [3, 5],
    [2, 5],
    [1, 5]
  ],
  [ // 4
    [1, 1],
    [3, 1],
    [1, 2],
    [3, 2],
    [1, 3],
    [2, 3],
    [3, 3],
    [4, 3],
    [3, 4],
    [3, 5]
  ],
  [ // 5
    [1, 1],
    [2, 1],
    [3, 1],
    [4, 1],
    [1, 2],
    [1, 3],
    [2, 3],
    [3, 3],
    [4, 4],
    [3, 5],
    [2, 5],
    [1, 5]
  ],
  [ // 6
    [2, 1],
    [3, 1],
    [4, 1],
    [1, 2],
    [1, 3],
    [2, 3],
    [3, 3],
    [1, 4],
    [4, 4],
    [2, 5],
    [3, 5],
  ], //7
  [
    [1, 1],
    [2, 1],
    [3, 1],
    [4, 1],
    [4, 2],
    [3, 3],
    [3, 4],
    [3, 5],
  ],
  [ // 8
    [2, 1],
    [3, 1],
    [1, 2],
    [4, 2],
    [2, 3],
    [3, 3],
    [1, 4],
    [4, 4],
    [2, 5],
    [3, 5],
  ],
  [ // 9
    [2, 1],
    [3, 1],
    [4, 1],
    [1, 2],
    [4, 2],
    [2, 3],
    [3, 3],
    [4, 3],
    [4, 4],
    [4, 5]
  ],
]

function draw_number(num, x, y) {
  /* this resets any previous translations */
  resetMatrix();
  translate(x, y);
  var pixels = numbers[num%numbers.length];
  for(var i=0; i<13; i++) {
    var cur_pixel = pixels[i%pixels.length];
    rect(cur_pixel[0] * s, cur_pixel[1] * s, s, s);
  }
}

function draw_number_interp(frac, num1, num2, x, y) {
  /* this resets any previous translations */
  resetMatrix();
  translate(x, y);
  var pixels1 = numbers[num1%numbers.length];
  var pixels2 = numbers[num2%numbers.length];
  for(var i=0; i<13; i++) {
    var cur_pixel1 = pixels1[i%pixels1.length];
    var cur_pixel2 = pixels2[i%pixels2.length];
    var pos_x = map(frac, 0.0, 1.0, cur_pixel1[0], cur_pixel2[0]);
    var pos_y = map(frac, 0.0, 1.0, cur_pixel1[1], cur_pixel2[1]);
    rect(pos_x * s, pos_y * s, s, s);
  }
}

function digits_from_num(num) {
  let digits = []
  if (num < 10) {
    digits.push(0);
  }
  else {
    n1 = Math.floor(num / 10);
    digits.push(n1);
  }
  n2 = Math.floor(num % 10);
  digits.push(n2);
  return digits;
}

function draw_clock(obj) {
  let hour = obj.hours;
  let minute = obj.minutes;
  let second = obj.seconds;
  let millis = obj.millis;
  let alarm = obj.seconds_until_alarm;

  var hour_pos = [40, height/2 - 3.5 * s];

  // DEBUG CODE TO TEST HOUR ROLLOVER
  // minute = minute + 35; // change based on current time
  // if (minute == 60) {
  //   minute = 0;
  //   hour = 0;
  // }

  // is alarm going off?
  if (alarm == 0) {
    if (second % 2 == 0) {
      background(0,0,100);      
    }
    else {
      background(100,100,0);      
    }
  }
  else {
    background(50);
  }

  noStroke();
  // is alarm going off in next 15 seconds
  if (alarm > 0) {
    fill(255,255,0);
    rect(width-50, height-50, 40, 40);
    if (alarm < 15.0) {
      var box_w = map(alarm, 0, 15, width, 0);
      var box_h = map(alarm, 0, 15, height, 0);
      rect(width/2-box_w/2, height/2-box_h/2, box_w, box_h);
    }
  }
  fill(255);

  // HOURS
  next_hour = (hour + 1) % 24;
  digits1 = digits_from_num(hour);
  digits2 = digits_from_num(next_hour);
  if(second >= 50 && minute == 59 && 
      (hour == 9 || hour == 19 || hour == 23)) {
    // minute_fraction_tens = millis  / 1000.0;
    seconds_left = (second - 50) + millis / 1000.0;
    hour_fraction_tens = seconds_left  / 10.0;
  }
  else {
    hour_fraction_tens = 0;
  }
  draw_number_interp(hour_fraction_tens, digits1[0], digits2[0], hour_pos[0] + 0.0 * 5 * s, hour_pos[1]);
  // draw_number(digits1[0], hour_pos[0], hour_pos[1]);

  if(second >= 55 && minute == 59) {
    // minute_fraction_tens = millis  / 1000.0;
    seconds_left = (second - 55) + millis / 1000.0;
    hour_fraction_ones = seconds_left  / 5.0;
  }
  else {
    hour_fraction_ones = 0;
  }
  draw_number_interp(hour_fraction_ones, digits1[1], digits2[1], hour_pos[0] + 1.0 * 5 * s, hour_pos[1]);
  // draw_number(digits1[1], hour_pos[0] + 1.0 * 5 * s, hour_pos[1]);

  // MINUTES
  next_minute = (minute + 1) % 60;
  digits1 = digits_from_num(minute);
  digits2 = digits_from_num(next_minute);
  if(second >= 58 && digits1[1] === 9) {
    // minute_fraction_tens = millis  / 1000.0;
    seconds_left = (second - 58) + millis / 1000.0;
    minute_fraction_tens = seconds_left  / 2.0;
  }
  else {
    minute_fraction_tens = 0;
  }
  draw_number_interp(minute_fraction_tens, digits1[0], digits2[0], hour_pos[0] + 2.5 * 5 * s, hour_pos[1]);

  if(second === 59) {
    minute_fraction_ones = millis  / 1000.0;
  }
  else {
    minute_fraction_ones = 0;
  }
  draw_number_interp(minute_fraction_ones, digits1[1], digits2[1], hour_pos[0] + 3.5 * 5 * s, hour_pos[1]);
  // draw_number(digits1[1], hour_pos[0] + 3.5 * 5 * s, hour_pos[1]);


  // SECONDS
  next_second = (second + 1) % 60;
  second_fraction = millis / 1000.0;
  digits1 = digits_from_num(second);
  digits2 = digits_from_num(next_second);
  // print(digits1);


  if(digits1[1] === 9 && millis > 500) {
    second_fraction_tens = (millis - 500) / 500.0;
  }
  else {
    second_fraction_tens = 0;
  }
  // draw the 10 second position
  draw_number_interp(second_fraction_tens, digits1[0], digits2[0], hour_pos[0] + 5.0 * 5 * s, hour_pos[1]);

  if(millis > 900) {
    second_fraction_ones = (millis-900) / 100.0;
  }
  else {
    second_fraction_ones = 0;
  }
  // draw the 1 second position
  draw_number_interp(second_fraction_ones, digits1[1], digits2[1], hour_pos[0] + 6.0 * 5 * s, hour_pos[1]);
}

debug.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.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_tom.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>
</table>
<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>
<br>
<a href="part1.html">part1</a> 
<a href="part2.html">part2</a> 
<a href="clock.html">clock</a> 
</body>

debug.js

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")
}

maeda_clock.js

const spacing = 50;

// Update this function to draw you own maeda clock on a 960x500 canvas
function draw_clock(obj) {
  background(0, 0, 100);
  noStroke();
  fill(255);

  const ball_size = 100;
  let posX = 300;
  let posY = 300;

  posX = 3*width/4;
  posY = height/2;

  posX = map(20, 0, 100, 0, width);

  ellipse(posX, posY, ball_size);
}

part1.html

<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="part2.html">part2</a> 
<a href="clock.html">clock</a> 
</body>

part2.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/addons/p5.dom.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>
</head>
<body style="background-color:white">
    <div class="outer">
        <div class="inner">
            <div id="canvasContainer"></div>
        </div>
    </div>
</table>
<br>
<a href="part1.html">part1</a> 
<a href="clock.html">clock</a> 
</body>

preview.jpg

����JFIF��C	

			

		


��C	����"��	
��D	W��	!G��$23�"1�&(48Eqv�#AQa��s�������?��4M���<��ԗ|V���/R�4M���<��Գ��7|V���/R�4M���<��ԗ|V���/R�4E�5��<��ԗ|����3R�4E�5��<��ԗ|����3R�4E�5��<��ԗ|����3R�4E�5��<��ԗ|����3R�4E�5��<��Գ��7EW���ߵ���nv#����m��s9>R'��O��8{�}���E�A����ⷸG��z����E�A����ⷸG��z����E�A���ov����Gd�V����P�������>D�~9���w[d6y��7EW���ߵ���nv#����m��s9>R'��O��8{�}���E�A����ⷸG��z����E�A����ⷸG��z����E�A����ⷸG��z����E�A����ⷸG��z��ov����Gd�V����P�������>D�~9���w[d6��D��[�#��H3��7|V���/R]�[�#��H3�D��[�#��H3��7|V���/R]�[�#��H3���#�[A�{MF�v�Q�z��'f�)�6$�6V7��R�b�Xa� h��k{�y��.�����f��h��+{�y��.�����^��h��+{�y��.�����^��h��k{�y��.�����f��_k�Kh6i�-�ں?��<�4�{6�ĕ�J������,o�0��@:#;�������0��7;��=~+��Q$���_Ƚz�v��xQ羁;�G��=�	�
#�⿑z�Nވ���ר���.�y�Q$��t��}'p�7;�����7;�����j��Mn���k�O"z�Q����p��9���5�����<�G7�ѵ�}�ogj��Fof�sM����2�r��Iŏ
�E��-����=�lO�?��?�d�n�����^����2��[�#��Iw�op�?��+4w����w]�奯�3���B�̆���U2OL��,���B�̆���U2OL��,���B�̆���U2OL��,���B�̆���U2OL��,���B�̆��#(�M�U�{���oe;#۝�����5�ry��_ϔ��o*S���-��;Q����׃;��[�#��Iw�op�?��+4wU�G�g�W����v�.����g�w/����gݶ��h������}��3�K��{��n�j�b�A�����B��>�I鑐���X��i=1x5P�v��zddD�u�v���?^>�����[���#�~���q�Y�������[��w�op�>�5-�⿑z�d�淸G�Q����v����Gd�V����P�������>D�~9���w[d6]���t��}'pٽ���=��V��������:��=o��$���͓������!�g^
T,]��4��Y������}���U`�
'�F@n�j�b�A�����B��>�I鑐���X��i=1x5P�v��zddf��.��OL�պ��~�����a��o-�}s�տ~��8�����p�}�-�l�Q����׃;]�[�#Ϩ�Iw�op�>�5+6ov����Gd�V����P�������>D�~9���w[d6yڈ��xQ羁;�tF�q���tEk��D`�ik�w��t�ݟ�M�lF��]!�hz����g<��(����pF��E�^r�n�{;��>�F�
����DE�Ǚ�8����A�xe�D��h��Y���^Ƚ��L��,����]���7�X�n&%z�[�qi�e����'S�t2<ϑ'��dO��m��^ux5P�v��zf{�q��u�����ɒt�^
T,\�i=3D��tF�p��ś��X��i=04@����`�
'�/�.��OL
w�����DV���ih9�"���}FjK�k{�y��w"���}FjK�k{�y��w"���}FjK�k{�y��wQ����קr��Fx��^�H|�����=�	ܢ=.~y�N�Q����ר�v�Fx��^�Dm���t��}�ڝ�.~y���n����߿k{)���>G_���ۓ��r�|�N+yR�
�p��l���w�op�>�5%�5��<��ԃ;�w�op�>�5%�5��<��ԃ;��D_��E������}FjZ&������ү���P��]s�����<�_[���.?�m��
$3���B�̆���U2OL����G���lޑz��~�Ͻ��wnvku�p�M�<����q8��J|6���e�[��tF�q���>ZZwF��淸G�Q�����}FjA���%�5��<��Ԭՠ�>ZZwF��淸G�Q�����}FjA�ƈ�淸G�Q��wҪ5zv���������z��ǥg�2�8�1d��)N,~�h!���vܫ%m6N��G%�/KP���Y�ihg��sy��a�90�o���-���X�n&q���������FA1��N�<�da��>D�~9�>+-���!Z��j�b�CI鞵�����|�5l7kO��sg����։XcEᖉ7t���g���T����;%�OEP���i�ihg�%#sy�Hp��A�Ɇ��^�{z؟��N"���u��=7W]�����S�Vw���!��ďN���ł/߂m���?ݻ�a�Nmg��o���|j����o�Kl7k�]�DE��8g�2���<�1���KD��h��Y���X)��;��
���m���wS�Y��������7;�:#s���(�D_��E�ӹDz"�W�/^
$'oK��{��Dz]<(��@���=~+��Q$���_Ƚz���.�y�Q$��t��}'p��E���^�;�G�/�"��@	����G��NޗO
<��w:#s��s����X�|�m>����Sټ��o8�f�R�2� �R$ha�4X�a�`�!��N/���a���"o�e��ý��D���OE���-��>�� �����w6�Ĕ�l�IG�s7��4J.B,0ō-,h����,0��0��5BP���DL�ٴ1���&�$bqC���[�����q���D`�q���j�j�b�CI鑔���X���zb�j�b�CI鑔���X���zb�j�b�CI鑔���X���zb�j�b�CI鑔���X���zb�j�b�CI鑔��淸G�Q�����}FjVld�淸G�Q��wtF�p��_Ƚzw(�D_��E��Dm-};z\�(��@��#���G�����_Ƚz�ڝ�~+��Q |�;�\�(��@�I����G��N�����7�ڶ�vnvOP�	����|ϑ'��l��e�]��
�����X���zb�j�b�CI鑔���X���zb�j�b�CI鑔���X���zfv�����O�T�x���{�oS뜎���'���'/����Yl[gr��E���^�����}FjK�k{�y��Y��{�|���;'ڶ��ns����g<�O/��%#��͓������!���G��=�	��^
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL���tF�����׃U2OL^
T,\�i=22��W�U2OL��=v������f���'����ݯ����q���Y���kNF'h'3yH`�>�Yh��C��A/���v����l�%�;WHu��ƝOg<��(�n	8#F�� �_�yEk&3�J�ģ�餼�u8�gR2pǔ��A,X;��~6�j�b�CI鑕��d���=��,��>�$޶mg�g?�����yt|�Z?���M��i8�����D�$���X-�4hbY �a�� ���tFw��"���}FjA�ƈ�淸G�Q�����}FjA�ƈ�淸G�Q�����}FjA�ƈ�淸G�Q�����}FjA�ƈ�淸G�Q�����}FjAf�v��X���zb�j�b�CI遢\�,���B�̆��#(
#�⿑z��lގ���q�}�mwa��d�p�Nyܞ���q�l���V[��m��Xgk�����
'�/�.d4��ۥ�=�	ܢ5���������a��o-�}s�տ~��8�����p�}�-�nv�淸G�Q��gq�.�����f��淸G�Q��gq�.�����f��淸G�Q��h�����ר�v���Y�U�������ˮu>Y�ǝ���s�����m�5�&�j�b�CI遢S���=�
x5P�s!���e�/X=�o����������n����'��9>N'��O��8{�C�M�U�{���oe;#۝�����5�ry��_ϔ��o*S���-��D�淸G�Q��gq�.�����f��淸G�Q��gq�.�����f��淸G�Q��gq�.�����f��淸G�Q��gu��_Ƚ{;]�[�#Ϩ�KD���Y�U�������ˮu>Y�ǝ���s�����m�5�D�v��X���zb�j�b�CI遝�]<(��@�͛�/X=�o����������n����'��9>N'��O��8{�q����+A�|����
BEO$�.}8�Τ!⒗��Ɠ��
�[4X`����pۣV�����KO��^{IN`�)�:w8�-)����x�C6w���mZ�u�n�1��]��V��=/��O ��\�q��x�PE��##/|1cw[ow��w�U2OL
��%[k�Tb�f��4l���Jrf��Y>(e%���4[��6=��B�̆��'�|w����o�Kl7kO������uYy���#��/�H������;�x׵
��&�}^q�ޯU-�m�%X���)��	��^��D�������E�7|���`��^�ڢ�[�����.0�*����ޝ��5n��]�oN��@�9�tF�pDnw���G�/�"��$��~+��Q NޗO
<��'r���xQ羁;�Dz"�W�/^�I��⿑z����=�
$��.�y��Dnw�9�z�TgsJ>������RSi�ڝ��KKKG�$���Xa�4hѡ�A0�t@�p����q7d��6�絽��n��jm�� ��N�wuK��x�m��9=�N(	�Y)�ޕ�������E�40��E����X��i=1x5P�v��zddf��.��OL���^
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL^
T,\�i=22�ٽ���=��V��������:��=o��$���͓������!�f�
T,\�i=22��W�U2OL^
T,\�i=22��W�U2OL^
T,\�i=22�ٽ"������{)����>����:�ry�S����q[ʔ�m����`�6oGE`�A��h>ն���s�z��N�<�O[�|�8�6sd�+-���lٷ�U2OL��,���B�̆���U2OL��,���B�̆���U2OL��,���B�̆���U2OL��,���B�̆��1�H�`�A�g��v��;����N�ܞwT���8�V�>l���-�@�W�U2OL��,���B�̆���U2OL��?��

purview.json

{
  "commits": [
    {
      "sha": "03bad856c821fab218fdcc9c4446953e710d8a73",
      "name": "FINAL"
    },
    {
      "sha": "70bbdc7581471151e43e43cf3b6bf1e263c21928",
      "name": "smooth motion"
    },
    {
      "sha": "84d781be564509c0a07754193aac86b63808ff86",
      "name": "racing circles"
    },
    {
      "sha": "10195cf22890d59eb7beda9d41edb566816e080d",
      "name": "maeda clock start"
    },
    {
      "sha": "d9a3bcfabae6aa7337b524b5b94581a8b9dd31c0",
      "name": "waterfall sketch"
    }
  ]
}

runner.js

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);
    }
  }

  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);
  }
}

z_purview_helper.js

// 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');
}