Search code examples
canvashtml5-canvasdrawing

How to paint on background canvas


So, when the canvas is positioned in background, obviously, I can't draw over element, that positioned above canvas in z-index.

 var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var width  = window.innerWidth;
        var height = window.innerHeight;
        canvas.height = height;
        canvas.width = width;

let hue = 0;
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let direction = true;

            var colorsArray = [
                "#5e9bd1",
                "#f4e78f",
                "#a4e38e",
                "#f1c39e",
                "#cbb7dd",
                "#cacaca"
            ];
            var randomNumber = Math.floor(Math.random()*colorsArray.length);
            var color = colorsArray[randomNumber]
            var lineWidth = Math.floor(Math.random()*200 + 20);
            ctx.lineWidth = lineWidth;
            ctx.lineCap = ctx.lineJoin = 'round';


        canvas.addEventListener('mouseup', function() {
            this.down = false;          
        }, 0);

        canvas.addEventListener('mousemove', function(e) {
                      this.down = true;   
            if(this.down) {
                 with(ctx) {
                                     ctx.strokeStyle = color;

                    beginPath();
                    moveTo(this.X, this.Y);
                    lineTo(e.pageX , e.pageY );
                    stroke();
                 }
                 this.X = e.pageX ;
                 this.Y = e.pageY ;
            }
        }, 0);

       
#canvas{
  z-index: 1;
  position: absolute;
}

div {
  position: fixed;
  top: 50px;
  left: 50px;
  z-index: 10;
  width: 200px;
  height: 200px;
  border: 1px black;
}
body{
    margin:0;
}
  <body>
  
<div>
<p>
gdsgsdg sd gasd g
gdsag ads
gdsa gsg asd
agsd 
asdg as
</p>
  <a href="test">LINK</a>
</div>
      <canvas id="canvas"  >
      </canvas>

  
</body>

I want to be able to draw on background positioned canvas, but at the same time to be able to use any other elements that positioned on top of it, while drawing remain active.


Solution

  • You can add the mouse listener to the document rather than the canvas. Eg document.addEventListener('mousemove', mouseEvent);

    To get the canvas coordinates you could use canvas.getBoundingClientRect(); to get its location, then adjust the event coordinates so that they are relative to the canvas. Don't forget about the page scroll position.

    Example using your snipet

    document.addEventListener("mouseup", mouseEvent);
    document.addEventListener("mousedown", mouseEvent);
    document.addEventListener('mousemove', mouseEvent);
    
    const mouse = {x: 0, y: 0, down: "forcedown"};  // starts with mouse down
    function mouseEvent(event) {
          const bounds = canvas.getBoundingClientRect();
          const x = event.pageX - bounds.left - scrollX;
          const y = event.pageY - bounds.top  - scrollY;
        if (event.type === "mousedown" || mouse.down === "forcedown") {
            mouse.down = true 
            mouse.x = x;
            mouse.y = y;
        }
        if (event.type === "mouseup") { mouse.down = false }
        if (mouse.down) {    
            ctx.beginPath()
            ctx.lineTo(mouse.x, mouse.y);
            ctx.lineTo(mouse.x = x, mouse.y = y);
            ctx.stroke();
        }
    }
    
    
    const ctx = canvas.getContext('2d');
    canvas.height = innerWidth;
    canvas.width = innerHeight;
    const colorsArray = ["#5e9bd1", "#f4e78f", "#a4e38e", "#f1c39e", "#cbb7dd", "#cacaca"];
    ctx.strokeStyle = colorsArray[Math.random() * colorsArray.length | 0];
    ctx.lineWidth = Math.random() * 2 + 2;
    ctx.lineCap = ctx.lineJoin = 'round';
    #canvas {
      z-index: 1;
      position: absolute;
    }
    
    div {
      position: fixed;
      top: 50px;
      left: 50px;
      z-index: 10;
      width: 200px;
      height: 200px;
      border: 1px black;
    }
    
    body {
      margin: 0;
    }
    <body>
    
      <div>
        <p>
          gdsgsdg sd gasd g gdsag ads gdsa gsg asd agsd asdg as
        </p>
        <a href="test">LINK</a>
      </div>
      <canvas id="canvas"> </canvas>
    
    
    </body>