How to build an Analog Clock using Canvas and Clock components

181 views
Skip to first unread message

SteveJG

unread,
Dec 18, 2018, 9:23:49 AM12/18/18
to mitappinv...@googlegroups.com
Analog Clock - Clock using the Canvas component

This example is one way to provide an animation of a Clock or Christmas Clock using the Canvas and Clock components.

ACimage2.png

ACimage.png



AnalogClockBlocks.png


Requires 3 ImageSprites (a transparent background png image) for the hour, minute and second clock hands; a Canvas component, a clock face ImageSprite and understanding of how the ImageSprite and Clock components work.

Attached is an aia file that includes example Public Domain images and sound files. Add your own music and graphics to make the clock 'mechanism" work as you like in your app.

For you to do:
1) Create a 'school' or grandfather clock: add a second Canvas below the Clock face and add a pendulum.
2) Redo the random sound file routine to dis-allow a sound file to repeat itself.
3) Create clock faces for different holidays/events.
4) Experiment with Themes and Fixed/Responsive Sizing.
5) Remove the clock 'tick' and/or provide a volume control
6) Add your own images/sound files.


Merry Christmas,
Steve

AnalogClock.aia

TimAI2

unread,
Jan 4, 2019, 2:47:31 PM1/4/19
to MIT App Inventor Forum
@Steve

You got me motivated ;)

Here is an analog clock built entirely of canvas elements (e.g. drawCircle, drawText, drawLine)
(no doubt it has been done before)

screencanvasclock.png


aia attached


CanvasClock.aia

TimAI2

unread,
Jan 6, 2019, 6:00:40 AM1/6/19
to mitappinv...@googlegroups.com
Getting carried away now, a further example using html 5 and javascript, for use in a webviewer

jshtml5clock.png


<!DOCTYPE html>

<html>
<style>
body
{
background
-color:#D4EFDF;
</style>

<body>

<canvas id="canvas" width="300" height="300"
style="background-color:#D4EFDF">
</canvas>

<script>

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx
.translate(radius, radius);
radius
= radius * 0.90
setInterval
(drawClock, 1000);

function drawClock() {

  drawFace
(ctx, radius);
  drawNumbers
(ctx, radius);
  drawTime
(ctx, radius);

}

function drawFace(ctx, radius) {

 
var grad;
  ctx
.beginPath();
  ctx
.arc(0, 0, radius, 0, 2*Math.PI);
  ctx
.fillStyle = '#FEF9E7';
  ctx
.fill();
  grad
= ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
  grad
.addColorStop(0, '#333');
  grad
.addColorStop(0.5, 'white');
  grad
.addColorStop(1, '#333');
  ctx
.strokeStyle = grad;
  ctx
.lineWidth = radius*0.1;
  ctx
.stroke();
  ctx
.beginPath();
  ctx
.arc(0, 0, radius*0.1, 0, 2*Math.PI);
  ctx
.fillStyle = '#333';
  ctx
.fill();

}

function drawNumbers(ctx, radius) {

 
var ang;
  
var num;
  ctx
.font = radius*0.15 + "px arial";
  ctx
.textBaseline="middle";
  ctx
.textAlign="center";
  
for(num = 1; num < 13; num++){
    ang
= num * Math.PI / 6;
    ctx
.rotate(ang);
    ctx
.translate(0, -radius*0.85);
    ctx
.rotate(-ang);
    ctx
.fillText(num.toString(), 0, 0);
    ctx
.rotate(ang);
    ctx
.translate(0, radius*0.85);
    ctx
.rotate(-ang);

 
}

}

function drawTime(ctx, radius){

   
var now = new Date();
    
var hour = now.getHours();
    
var minute = now.getMinutes();
    
var second = now.getSeconds();

   
//hour

    hour
=hour%12;
    hour
=(hour*Math.PI/6)+
    
(minute*Math.PI/(6*60))+
    
(second*Math.PI/(360*60));
    drawHand
(ctx, hour, radius*0.5, radius*0.07);

   
//minute

    minute
=(minute*Math.PI/30)+(second*Math.PI/(30*60));
    drawHand
(ctx, minute, radius*0.8, radius*0.07);

   
// second

    second
=(second*Math.PI/30);
    drawHand
(ctx, second, radius*0.9, radius*0.02);

}


function drawHand(ctx, pos, length, width) {

    ctx
.beginPath();
    ctx
.lineWidth = width;
    ctx
.lineCap = "round";
    ctx
.moveTo(0,0);
    ctx
.rotate(pos);
    ctx
.lineTo(0, -length);
    ctx
.stroke();
    ctx
.rotate(-pos);

}

</script>
</body>

</html>



jsclock.aia
Reply all
Reply to author
Forward
0 new messages