Home > Net >  How to remove thin border on 2 sides of canvas element?
How to remove thin border on 2 sides of canvas element?

Time:11-01

UPDATE: enter image description here

Any idea why this is happening? Similar SO questions/solutions have not solved my problem.

window.onload = function() {
    var speaker = document.getElementById('speaker');
    //speaker.onload = MoveElement(speaker, "right", 1000);

    //Create canvases & contexts
    var canvas = document.getElementById('canvas');
    var ctxB = canvas.getContext('2d');
    var canvas2 = document.getElementById('canvas2');
    var ctxT = canvas2.getContext('2d');

    //Get waterfall image object
    var waterfall = document.getElementById('waterfall');

    //Set canvas w&h properties
    canvas.width = canvas2.width = .3*waterfall.width;
    canvas.height = canvas2.height = .3*waterfall.height;

    //Populate Bottom canvas with waterfall image
    ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);

    //Populate Top canvas with white rectangle
    ctxT.fillStyle = "white";
    ctxT.fillRect(0, 0, canvas2.width, canvas2.height);

    //Make Top canvas "erasable"
    canvas2.addEventListener('mousemove', event => {
        var x = event.offsetX;
        var y = event.offsetY;  
        const eraseSize = 15;
        ctxT.clearRect(x-eraseSize/2, y-eraseSize/2, eraseSize, eraseSize);
    });
}

//Set interval timer to repeatedly execute TransparencyCheck()
var timer = setInterval(TransparencyCheck, 500);

//Check that all pixel alpha values = 0
function TransparencyCheck() {
    var canvas2 = document.getElementById('canvas2');
    var ctxT = canvas2.getContext('2d');
    var imageDataTop = ctxT.getImageData(0, 0, canvas2.width, canvas2.height);
    var counter = 0;

    for (var i = 3; i < imageDataTop.data.length; i  = 4) {
        if (imageDataTop.data[i] == 0) {
            counter  ;
        }
    if (counter == imageDataTop.data.length/4) {
        canvas2.style.opacity = "0";
        }
    }
}
#stack {
    position: relative;
}
#stack canvas {
    position: absolute;
    display: block;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 150px;
}
            <img hidden src="https://sample-videos.com/img/Sample-jpg-image-50kb.jpg" alt="issue here" id="waterfall" />
      
        <div id="stack">
            <canvas id="canvas"></canvas>
            <canvas id="canvas2" onmouseout="TransparencyCheck()"></canvas>
        </div>
 
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

The problem is that the dimensions of the canvas are being calculated as a fraction (0.3) of the dimensions of the underlying image. This can result in a 'part pixel' problem. That is the system has to decide how to show a fraction of a CSS pixel, and on modern screens several screen pixels are used to show one CSS pixel. A screen pixwl can get 'left behind' (ie still showing) during this process.

A slightly hacky way of getting round this (but I know of no other) is to decrease the size of the bottom canvas by a few pixels so that we are absolutely sure any left overs are under the white of the top canvas at the start.

This snippet makes doubly sure by taking 2px off the width and height.

Incdentally, I copied the code from the codepen pointed at by the question and it worked as an SO snippet OK. Here it is:

window.onload = function() {
  var speaker = document.getElementById('speaker');
  //speaker.onload = MoveElement(speaker, "right", 1000);

  //Create canvases & contexts
  var canvas = document.getElementById('canvas');
  var ctxB = canvas.getContext('2d');
  var canvas2 = document.getElementById('canvas2');
  var ctxT = canvas2.getContext('2d');

  //Get waterfall image object
  var waterfall = document.getElementById('waterfall');

  //Set canvas w&h properties
  canvas.width = canvas2.width = .3 * waterfall.width;
  canvas.width = canvas.width - 2;
  canvas.height = canvas2.height = .3 * waterfall.height;
  canvas.height = canvas.height - 2;


  //Populate Bottom canvas with waterfall image
  ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);

  //Populate Top canvas with white rectangle
  ctxT.fillStyle = "white";
  ctxT.fillRect(0, 0, canvas2.width, canvas2.height);

  //Make Top canvas "erasable"
  canvas2.addEventListener('mousemove', event => {
    var x = event.offsetX;
    var y = event.offsetY;
    const eraseSize = 15;
    ctxT.clearRect(x - eraseSize / 2, y - eraseSize / 2, eraseSize, eraseSize);
  });
}

//Set interval timer to repeatedly execute TransparencyCheck()
var timer = setInterval(TransparencyCheck, 5000);

//Check that all pixel alpha values = 0
function TransparencyCheck() {
  var canvas2 = document.getElementById('canvas2');
  var ctxT = canvas2.getContext('2d');
  var imageDataTop = ctxT.getImageData(0, 0, canvas2.width, canvas2.height);
  var counter = 0;

  for (var i = 3; i < imageDataTop.data.length; i  = 4) {
    if (imageDataTop.data[i] == 0) {
      counter  ;
    }
    if (counter >= imageDataTop.data.length / 4) {
      canvas2.style.opacity = "0";
      clearTimeout(timer);
      alert('all top canvas erased');
    }
  }
}
#stack {
  position: relative;
}

#stack canvas {
  position: absolute;
  display: block;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 150px;
}
<img hidden src="https://sample-videos.com/img/Sample-jpg-image-50kb.jpg" alt="issue here" id="waterfall" />

<div id="stack">
  <canvas id="canvas"></canvas>
  <canvas id="canvas2" onmouseout="TransparencyCheck()"></canvas>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related