Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

116
Views
HTML canvas shows tiny slice of adjacent image in tileset

I've been programming a game using the HTML5 canvas and JavaScript, and when I try to rotate an image, it displays a tiny sliver of the adjacent image from the sprite sheet. I know that I could separate the images in the sprite sheet, but I'm trying to find another way to solve the problem, like changing a setting.

It isn't a big problem, but it's strange that a piece of an adjacent image would be grabbed when it was not specified. The sprites are 16 by 16 pixels.

screenshot

another one

in the sprite sheet

The line of code that draws the hand sprite is the second draw image, and I'm using an index to grab the images. Here, the result is 208, which is where the green square is in the image.

c.save();
                c.translate(canvas.width/2, canvas.height/2); 
                if(mouseAngle >= 90 || mouseAngle <= -90) {
                    c.scale(-1, 1);
                    c.rotate(Math.PI / 180 * (180 + -mouseAngle));
                } else {
                    c.rotate(Math.PI / 180 * (mouseAngle));
                };
                c.drawImage(Images.items, itemID[this.heldItem] * 16, 0, 16, 16, scale, -12 * scale, 16 * scale, 16 * scale);
                c.drawImage(Images.player, this.handFramePath[this.dmgIndex] * 16, 0, 16, 16, scale, -12 * scale, 16 * scale, 16 * scale);
                c.restore();
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Yes, textures do bleed from the cropping of drawImage.
Usually we can try to prevent that by ensuring that our context's transforms are on integer coordinates, as to avoid any antialiasing, but for rotation... that's more complex.

So the best in your case (with or without bleeding actually), is to extract each sprite from the sprite-sheet in its own ImageBitmap object.

This way the cropping will be done without any transformation messing in, and it will have the added benefit of allowing the browser to optimize the sprites that are used more often (rather than moving the whole sprite-sheet every time).

(async() => {

  const spritesheet = document.querySelector("img");
  await spritesheet.decode();
  const canvas = document.querySelector("canvas");
  const ctx = canvas.getContext("2d");
  // apply some transforms
  ctx.translate(50, 50);
  ctx.rotate(Math.PI/32);
  ctx.translate(-50, -50); 

  // draw only the gray rectangle
  // cropped from the full spritesheet on the left
  // (bleeds in all directions on Chrome)
  ctx.drawImage(spritesheet,
    8, 8, 8, 8,
    50, 50, 50, 50
  );
  // single sprite on the right
  const sprite = await createImageBitmap(spritesheet, 8, 8, 8, 8);
  ctx.drawImage(sprite,
    150, 50, 50, 50
  );

})().catch(console.error);
<p>The original sprite-sheet:<img src="https://i.stack.imgur.com/I1xPN.png"></p>
<canvas></canvas>

createImageBitmap is now supported in all up to date browsers, but for older ones (e.g Safari did expose it only a few weeks ago), I made a polyfill you can find here.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!