0

I have a canvas, which will display videos taken from file upload on the first layer, and the second layer allow rectangles to be drawn. As I am trying to annotate videos and not still images, I will need the annotations to be saved then cleared, and then redrawn again and again until the video is over. However, I have no clue how I should do so as I am relatively new to JavaScript.

This is the code I have for now for the drawing of the annotations:

// Drawing boxes
function handleMouseDown(e) {
    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);
    console.log(mouseX, mouseY);
    $("#downlog").html("Down: " + mouseX + " / " + mouseY);

    // Put your mousedown stuff here
    if (mouseIsDown) {
        console.log('1');
        canvas2.style.cursor = "crosshair";
        mouseIsDown = false;
        mouseIsUp = false;
        console.log(mouseIsDown);
    } else {
        handleMouseUp();
    }

    mouseIsDown = false;
    mouseIsUp = true;

}

function handleMouseUp(e) { // array? user input?
    mouseIsDown = false;
    startX = parseInt(e.clientX - offsetX);
    startY = parseInt(e.clientY - offsetY);
    /*if (mouseIsUp) {
        console.log('2');*/

        draw();

    }

function draw() {
/*  context2.clearRect(0, 0, canvas2.width, canvas2.height);*/
    context2.beginPath();
    context2.rect(startX, startY, mouseX - startX, mouseY - startY);
    context2.strokeStyle = "limegreen";
    context2.lineWidth = 2;
    context2.stroke();
    canvas2.style.cursor = "default";

}

$("#canvas2").mousedown(function(e) {
    handleMouseDown(e);
});

$("#canvas2").mouseup(function(e) {
    handleMouseUp(e);
});

function clearcanvas()
{
    var canvas2 = document.getElementById('canvas2'),
    context2 = canvas2.getContext("2d");
    context2.clearRect(0, 0, canvas2.width, canvas2.height);
}

I will really appreciate any help, thank you!

CCXXVIII
  • 129
  • 7

1 Answers1

0

Please read the comments. I hope my code is clear enough.

let c = document.getElementById("canvas");
let ctx = c.getContext("2d");
// the array of all rectangles
let rectsRy = [];
// the actual rectangle, the one that is beeing drawn
let o={};


// a variable to store the mouse position
let m = {},
// a variable to store the point where you begin to draw the rectangle    
start = {};
// a boolean 
let isDrawing = false;


function handleMouseDown(e) {
  start = oMousePos(c, e);
  isDrawing = true; 
  //console.log(start.x, start.y);
  c.style.cursor = "crosshair";
 
}

function handleMouseMove(e) { 
    if(isDrawing){
    m = oMousePos(c, e);
    draw();
    }
    }

function handleMouseUp(e) { // array? user input?
    c.style.cursor = "default";
    isDrawing = false;
    // push a new rectangle into the rects array
    rectsRy.push({x:o.x,y:o.y,w:o.w,h:o.h});
    }

function draw() {  
    o.x = start.x;
    o.y = start.y;
    o.w = m.x - start.x;
    o.h = m.y - start.y;
  
    clearcanvas();
    // draw all the rectangles saved in the rectsRy
    rectsRy.map(r => {drawRect(r)})
    // draw the actual rectangle
    drawRect(o);  
}

c.addEventListener("mousedown", handleMouseDown);

c.addEventListener("mousemove", handleMouseMove);

c.addEventListener("mouseup", handleMouseUp);

function clearcanvas(){
ctx.clearRect(0, 0, c.width, c.height);
}

function drawRect(o){
    ctx.strokeStyle = "limegreen";
    ctx.lineWidth = 2;
    ctx.beginPath(o);
    ctx.rect(o.x,o.y,o.w,o.h);
    ctx.stroke();
}

// a function to detect the mouse position
// the function returns an object
function oMousePos(canvas, evt) {
  let ClientRect = canvas.getBoundingClientRect();
 return { 
 x: Math.round(evt.clientX - ClientRect.left),
 y: Math.round(evt.clientY - ClientRect.top)
  }
}
canvas{border:1px solid #d9d9d9;}
<canvas id="canvas" width="600" height="300">
enxaneta
  • 31,608
  • 5
  • 29
  • 42
  • Thank you so so much, this really helped me a lot! However, when I clear the canvas and redraw, the previously drawn rectangles which have already been added into the array all shows up at once. Is it possible to keep them saved in the array, but not reappear anymore? Thank you :) – CCXXVIII Sep 13 '18 at 02:53
  • Inside the function `draw` you have to comment out this line of code; ` rectsRy.map(r => {drawRect(r)})`.This is the code that draws all the rectangles saved in the `rectsRy`; the array of the rectangles. – enxaneta Sep 13 '18 at 05:25
  • If I comment out that line, then I am only able to draw one rectangle at a time. – CCXXVIII Sep 14 '18 at 00:48
  • Is it possible to have all the rectangles shown as they are, but not have them reappear after I clear the canvas? Example I first draw four rectangles (and want them to all show on the canvas) and then clear the canvas to redraw more rectangles. After clearing, I do not want the previously drawn four rectangles to appear anymore, but still have them saved in the array. Is this possible? Thank you! – CCXXVIII Sep 14 '18 at 02:18
  • *Is it possible to have all the rectangles shown as they are, but not have them reappear after I clear the canvas?* In this case you would need to empty the `rectsRy` first: `rectsRy.length = 0` *After clearing, I do not want the previously drawn four rectangles to appear anymore, but still have them saved in the array. Is this possible?* Yes, but in this case you need to save them in an other variable: [Copying array by value in JavaScript](https://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript#7486130) – enxaneta Sep 14 '18 at 07:09