** Read before you mark as duplicate! **
Getting the mouse position on the canvas nearly works fine.
My window size is 800 x 600
My canvas size is 400 x 300:
canvas.width = 400;
canvas.height = 300;
My canvas css size is 100% x 100%:
canvas {width: 100vw; height: 100vh;}
The problem is: if my mouse is in the middle of the canvas I get this mouse position: 400, 300. If my window size was 1600 x 1200 I would get 800, 600.
I would like to get the canvas position of the mouse. What I mean by this, is I'm looking to get 200, 150, regardless of the window size.
How would I do this?
Thank's for the help.
You have to create conversion from model coordinates to screen coordinates and back. Here is good explanation for it: http://www.ckollars.org/canvas-two-coordinate-scales.html
You could paste this into your code.
document.getElementById("canvasId").addEventListener('mousemove',function(event){mousePos(event);});
function getMousePos(e){
var rect = canvas.getBoundingClientRect();
//this gets your canvas size.
return {
x: Math.round(e.clientX - rect.left),
y: Math.round(e.clientY - rect.top)
};
function mousePos(e){
var pos = getMousePos(e);
var mouseX = pos.x;
var mouseY = pos.y;
}
then you could just reference the mouseX and mouseY somewhere else.
//enter the rest of your code here.
Related
I've been playing around with the HTML5 canvas lately and one of the things I've wanted to do is create a simple page with a canvas that'll draw a circle wherever you click. I have some code that looks like it should work, and I've been attempting to debug with some console output, but I've been unable to see any errors at the moment.
I'm using Codepen though, so I'm unsure how fully featured that console is, and I unfortunately can't use the dev console on my laptop at the moment (locked down school Chromebook).
Could someone take a look? I'll put the code in here and drop a link to the pen as well. Thanks!
HTML:
<canvas id="canvas" onclick="drawCircle(event)"></canvas>
CSS:
canvas {
position: relative;
background: #f1c40f;
width: 100%;
height: 100%;
}
JS:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
function drawCircle(e) {
var pos = getCursorPosition(c, e);
var clickX = pos.x;
var clickY = pos.y;
ctx.fillStyle = "#2980b9";
ctx.beginPath();
ctx.arc(clickX, clickY, 10, 0, 2 * Math.PI);
ctx.fill();
console.log(clickX, clickY);
console.log("drawcircle");
}
function getCursorPosition(canvas, e) {
// Gets click position
rect = canvas.getBoundingClientRect();
console.log('getcursorpos');
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
Codepen link: https://codepen.io/wolverine1621/pen/gWvjgx
Any help is appreciated. It's probably something pretty simple but this is really my first time working with canvas, so any input is helpful!
Thanks!
The issue is occurring because, you set the canvas's width and height using css.
You should rather set it using javascript, like so ...
c.width = window.innerWidth;
c.height = window.innerHeight;
and to make the canvas flexible, so that it maintains it's size, use ...
window.onresize = function() {
c.width = window.innerWidth;
c.height = window.innerHeight;
}
Here is the working codepen
A couple of things:
1) you are not setting a width and height for your canvas, so there is going to be distortion and the x/y values are going to be weird. Solution: set the width and height of the canvas to the window height and width
2) Your method for determining clickX and clickY is overly complicated. Solution: use event.clientX and event.clientY
After getting your context, set the width and height:
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
Note: I would also encourage you to remove the margin on the body in CSS
body { margin: 0 }
Now you can get rid of getCursorPosition (because it is giving you wrong values)
var clickX = e.clientX
var clickY = e.clientY
The code below paints correctly but it paints to wrong coordinates. It should paint the place where the mouse is. I was not able to discover my mistake. Thanks.
JSFIDDLE
container.mousedown(function(e) {
var parentOffset = $(this).offset();
var x = e.pageX - parentOffset.left;
var y = e.pageY - parentOffset.top;
context_temp.beginPath();
context_temp.moveTo(x, y);
started = true;
});
container.mousemove(function(e) {
var parentOffset = $(this).offset();
var x = e.pageX - parentOffset.left;
var y = e.pageY - parentOffset.top;
if (started) {
context_temp.lineTo(x, y);
context_temp.stroke();
}
});
container.mouseup(function(e) {
var parentOffset = $(this).offset();
var x = e.pageX - parentOffset.left;
var y = e.pageY - parentOffset.top;
if (started) {
container.mousemove(x, y);
started = false;
update();
}
});
You're setting your canvas width and height in CSS. That just stretches the canvas the same as it would an image.
The effect is drawing in the wrong place.
Instead you need to set your canvas dimensions on the tag itself:
<canvas width="400" height="400"></canvas>
A <canvas> has its own width and height, which not only define its physical size (unless CSS steps in), but also its logical size (the number of rows/columns of pixels on its drawing surface). When CSS changes the size, the canvas stretches to fit, but doesn't change its logical size. Basically, the pixels stretch too, so the logical and physical coordinates no longer match up.
To fix the problem, you could either do the math to match the coordinates back up, or exclusively use the canvases' own width/height to size them, or set the canvases' width and height properties after the fact to match the width and height set by CSS.
I'm trying to draw on a canvas, but the mouse positions are off, they seem to be too far to the right when I draw.
The canvas is centered in the middle with a width of 960px.
Here's the URL to the page: http://passion4web.co.uk/ben/canvas/app/
I'm using the following function to get the mouse position:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
A canvas has two distinct sizes:
The size on the page
The size in pixel of the image
You need to set the canvas size in pixel to the size on the page to get an accurate 1:1 rendering:
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
Please remember that when you set the width/height members of a canvas object the picture is cleared (even if you are setting the same value currently present).
I'm working with this script "Drawing polygons with the mouse" and it works very well.
The issue I have is when I put the canvas in the design of my site. The canvas is thus now in relative position and the coords are wrong. I have a lag between my cursor and the draw…
If I set the div in position: fixed, there is no problem.
The positions are declared as follows:
canvas.addEventListener("click", function(e) {
var x = e.clientX-canvas.offsetLeft;
var y = e.clientY-canvas.offsetTop;
How to fix this? How to put the canvas in my design and have the right coords?
Thank you very much!
Try my "simple" mouse code (simple because it does not take into account border/padding/HTML offset):
function getMouse(e, canvas) {
var element = canvas, offsetX = 0, offsetY = 0, mx, my;
// Compute the total offset
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// This isn't the best code because I am not adding padding and border style widths to offset. I'm just keeping it simple.
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
return {x: mx, y: my};
}
Cannot figure this out, how to find the translated position of the background relative to the canvas. I have the characters coordinates, and I have the coordinates from a mouse click within the canvas, but can't figure out how to find the offset.
In the canvas, when I click somewhere, I get an (x,y) value from (0,0) - (650,575), the size of the window, no matter where my character is. If the character is at (2000, 1500) on the canvas, my click/touch input will always send the character up and left towards 0,0 on the background coordinate.
At first I thought I should subtract the player X position from the max width, then add an offset half the width of the screen, and do the same for the Y position, but that didn't work.
Then I tried subtracting half the width/height of the screen from the current player x,y values but that doesn't work.
Anyone point me in the right direction, it seems elementary but I can't figure it out it's been years since math class???? Thanks
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 650;
canvas.height = 575;
var WIDTH=5000; //level width
var HEIGHT=3750; //level height
ctx.translate(-WIDTH*.5,-HEIGHT*.5); //starts in center of background
Where my player begins on load:
hero.x = WIDTH*.5+325; //offset half canvas width
hero.y = HEIGHT*.5+275; //offset half canvas height
For the Background:
ctx.drawImage(bgImage, BGsrcX , BGsrcY, 1250 , 938 ,-150, -150, BGdestW, BGdestH); `//image is stretched to 5000x3750`
This is the mouse input I'm using
if(navigator.userAgent.match(/(iPhone)|(iPod)|(iPad)/i)){
document.addEventListener('touchstart', function(e) {
if(e.touches.length == 1){ // Only deal with one finger
var touch = e.touches[0]; // Get the information for finger #1
var x = touch.pageX - canvas.offsetLeft;
var y = touch.pageY - canvas.offsetTop;
//clickEvent(x,y); //call your function to manage tweets
}
},false);
}
else{
document.addEventListener('mousedown',function(e) {
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
console.log(x+":"+y);
clickEvent(x,y); //call your function to manage tweets
},false);
}
For the keyboard input to actually pan the background:
if(16 in keysDown && 38 in keysDown && hero.y > 200) {ctx.translate(0,12); }
Don't work with half-translated and non-translated coordinates, translate your mouse click coordinates AND your canvas coordinates.
Then you can just use simple subtraction to find the offset, and to find the distance, you you use the distance formula.