Faizan
Faizan

Reputation: 552

Blur Image Canvas

I have a form through which user can track a process, and I am showing the progress through visuals.

I have tried to use a picture of a progress bar rectangle and a picture of a flag. I am drawing it through the canvas, but they appear blurry, including the heading which is text.

This is how it appear on web page

These are the original pictures, which are clear:

Flag pic Bar Pic

And here is my code:

<head>
    <style>
        #myCanvas {
            border: 1px solid #d3d3d3;
            width: 100%;
            height: 100%;
        }

        #invis {
            display: none;
        }
    </style>
</head>


<img src="~/Temp/images/track.png"/>
<canvas id="myCanvas"></canvas>






<img src="~/Temp/images/flag.png" id="invis" />
<script>
    debugger;
window.onload = function() {
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");


        ctx.font = "15px Arial";
        let text = "Email Request Process Live Tracking";
        ctx.fillStyle = "#0000ff";
        ctx.fillText(text,canvas.width/2 - ctx.measureText(text).width/2,20);


        let img1 = new Image();
        let startX = 40;
        let startY = canvas.height - 50;
        let width = canvas.width - 80;
        let height = 10;
        img1.onload = function () {

            ctx.drawImage(img1, startX, startY, width, height)

        };

        img1.src = "/Temp/images/track.png"


        var progress = "FH";
        var progress1 = "HR";
        var progress2 = "IT";
        let locations = {
          function: {x: startX-20, y: startY},
          FH: {x: startX + width/28, y: startY},
          HR: { x: startX + 2 * (width / 4.2), y: startY },
          IT: { x: startX + 4 * (width / 4.3), y: startY },
          processed: {x: startX + 3 * (width/5), y: startY},
          actionPerformed: {x: startX + 4 * (width/5), y: startY},
          handedoverClosed: {x: startX + width, y: startY}
        };
        let img = new Image;
        img.onload = function () {

            let x = locations[progress].x
            let y = locations[progress].y
            ctx.drawImage(img, locations[progress].x, locations[progress].y - 40, 20, 40)

        };

        img.src = "/Temp/images/flag.png"
}


</script>

Upvotes: 0

Views: 1038

Answers (1)

zero298
zero298

Reputation: 26920

Your canvas needs an explicit width and height:

<canvas width="1000" height="1000"></canvas>

Otherwise you will have the default number of pixels available in the canvas but those pixels will be stretched over the total width of your screen.

To get the appropriate size of your <canvas> you should get the dimensions that your canvas will occupy with getBoundingClientRect(), set them on the element explicitly, and re-render. Otherwise you will still get scaling issues.


Consider the example below. The first render will happen using the default canvas size and you will see the Stack Overflow logo stretched because it is trying to show what will probably be a 300 width canvas that is stretched across ~600 pixels.

After a few seconds the canvas' dimensions are explicitly set to be the actual calculated size of the element. Because of that, the canvas is no longer stretched.

Bear in mind, that if the screen is resized, you will need to do this calculation and render again.

const img = new Image();

function main() {
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");

  console.log(`${canvas.width} | ${canvas.height}`); // Probably 300 | 150

  ctx.drawImage(img, 0, 0, 200, 200);

  setTimeout(() => {
    const {
      width,
      height
    } = canvas.getBoundingClientRect();

    canvas.width = width;
    canvas.height = height;

    console.log(`${canvas.width} | ${canvas.height}`);

    ctx.drawImage(img, 0, 0, 200, 200);
  }, 3000);
}

img.addEventListener("load", main);
img.src = "https://cdn.sstatic.net/Img/unified/sprites.svg";
canvas {
  width: 100%;
}
<canvas id="canvas"></canvas>

Upvotes: 3

Related Questions