0

This is a school analog clock project. I'm just learning canvas and a lot of it is not clear to me. The clock works but I have a problem with the hands that leave a mark after each movement. The clearRect method solves this problem but also deletes part of the png image. Do you know how to keep the image constant and clearRect only delete the hands?

window.onload = draw;

let myCanvas = document.getElementById("my-canvas");
var myCtx = myCanvas.getContext('2d');

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");

var canvas2 = document.createElement("canvas");
var ctx2 = canvas2.getContext("2d");

var radius = myCanvas.height / 2;
myCtx.translate(radius, radius);
radius = radius * 0.90

imageBack(myCtx);
setInterval(draw, 1000);

function imageBack(ctx2) {
    var img = new Image();
    img.addEventListener(
        `load`,
        function () {
            ctx2.drawImage(img, -100, -100, 200, 200);
        },
        false
    );
    img.src = "watch1.png";
}

function draw() {
    // set Time
    postaviVreme(myCtx, radius);

    // myCtx.clearRect(-50, -50, 100, 100);
}


// set Time
function postaviVreme(ctx, radius) {
    // ctx.clearRect(-50,-50, 100,100);

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

    hour = hour % 12;
    hour = (hour * Math.PI) / 6 + (minute * Math.PI) / (6 * 60) + (second * Math.PI) / (360 * 60);
    minute = (minute * Math.PI) / 30 + (second * Math.PI) / (30 * 60);
    second = (second * Math.PI) / 30;

//set hours hand
    nacrtajSatnicu(ctx, hour);
// set minutes hand
    nacrtajMinutaru(ctx, minute);
// set seconds hand
    nacrtajSekundaru(ctx, second);

}

function nacrtajSatnicu(ctx, h) {
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.rotate(h);
    ctx.lineTo(0, -radius * 0.3);
    ctx.strokeStyle = "black";
    ctx.closePath();
    ctx.stroke();
    ctx.rotate(-h);
}

// function nacrtajMinutaru and function nacrtajSekundaru - almost same as nacrtajSatnicu 

image

1 Answer 1

1

Load the image and start timer when loaded

const bgImg = new Image();
bgImg.src = "watch1.png";
bgImg.addEventListener("load",() => setInterval(postaviVreme, 1000), {once: true});

Then each tick of the clock clear the whole canvas and redraw everything.

// only need one canvas
const canvas = document.getElementById("my-canvas");
const ctx = canvas.getContext('2d');
const PI6 = Math.PI / 6;

function postaviVreme() {
    ctx.setTransform(1,0,0,1,0,0); // reset transform to clear canvas
    ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);

    var radius = ctx.canvas.height / 2;
    ctx.translate(radius, radius);
    radius *= 0.9;

    ctx.drawImage(bgImg, -100, -100, 200, 200);

    var now = new Date();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();
    
    nacrtajSatnicu(ctx, (hour % 12 + minute / 60 + second / 3600) * PI6);
    nacrtajMinutaru(ctx, (minute + second  / 60) * PI6 / 5);
    nacrtajSekundaru(ctx, second * PI6 / 5);    
}
1
  • Ah, yeah, you're correct. I was under the impression .clearRect and .fillRect didn't take transforms into account, but I tried it out :) Deleted that older misleading comment.
    – AKX
    Commented Aug 31, 2020 at 6:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.