I am having an issue with context.getImageData() after I scaled down the canvas. I have canvas added to the HTML page:
<canvas id="canvas" width="960" height="620"></canvas>
I have image drawn on that canvas acting like button. I am testing the alpha channel to know if mouse is over the button or not:
var mx = (e) ? (e.offsetX || e.layerX) : 0; var my = (e) ? (e.offsetY || e.layerY) : 0; var cx = mx - (btn.x * this.ratio - 2; var cy = my - btn.y * this.ratio - 2; var pixels = btn.getContext().getImageData(cx, cy, 1, 1); for (var j : number = 3; j < pixels.data.length; j += 4) { if((pixels.data[j])!=0 && e) { console.log('mouse over'); } }
The button is sliced from the big image and pre-rendered:
var btn = createCanvas("img.png", 0, 0, 100, 100); function createCanvas(img, sx , sy , w , h ) { var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); ctx.drawImage(img, sx, sy, w, h, 0, 0, w, h); return canvas; }
After that sliced button/image is added to the main canvas.
this.context.drawImage(btn, 0,0, btn.width, btn.height, 100, 100, btn.width, btn.height);
It works fine until I start to scale the whole canvas.
function scale() { var scale = {}; scale.x = window.innerWidth / this.canvas.width; scale.y = window.innerHeight / this.canvas.height; var ratio = scale.x <= scale.y ? scale.x : scale.y; }
After when I scale down the canvas the button hit/over area is bigger than the button/image itself. It looks it hasn't been scaled and it takes the original width and height. The graphic however is scaled accordingly to the canvas scale. I tried to multiply width and height by the ratio but it scale the image of a button but area where mouse reacts is still bigger than the button. What I should change in the code to have that issue gone?
ps I apologize for my English. :)
EDIT
The function I use to scale the canvas
window.addEventListener('resize', resize, false);
window.addEventListener('orientationchange', resize, false);
var canvas = $('#canvas');
var ratio = 1;
var originalCanvasW = 800;
var originalCanvasH = 600
function resize(e)
{
var scale = {x: 1, y: 1};
var s : string = '';
scale.x = window.innerWidth / canvas.width;
scale.y = window.innerHeight / canvas.height;
ratio = scale.x <= scale.y ? scale.x : scale.y;
ratio = (ratio > 1) ? 1 : ratio;
canvas.css('width',originalCanvasW*ratio);
canvas.css('height',originalCanvasH*ratio);
}
You are scaling the canvas with CSS. When you do that, you aren't actually affecting the canvas itself, you are just affecting its representation in the DOM of the website. Using CSS to scale a canvas is not recommended in most cases, because it doesn't change the internal drawing resolution which means the canvas will be displayed blurred. But it also results in one canvas-pixel no longer being equivalent to one screen-pixel.
context.getImageData
does still use the internal resolution ( width="960" height="620
)for its coordinates, while the mouse coordinates you use are measured in the coordinate system of the webpage the canvas is embedded in.
To solve this problem, there are two possibilities:
canvas.width
and canvas.height
and adjust the context.scale
accordingly so that 960px is still the full width of the canvas. I would recommend the second solution, because it will likely also look much better.
I think I finally managed. @Philipp thank you for the direction and stack overflow for the Related column on the right. I have found that post, stackoverflow.com/questions/14544260/ and I rewrite a bit of the resize function pasted and it worked! I am happy, I have been fighting with that from yesterday.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.