Paint canvas not working properly - javascript

http://www.asifslab.com/reveal.js-master/Why%20does%20wind%20feel%20cold.html#/4
Why doesn't the drawing canvas work properly? The line drawn is away from the point clicked. However, if I use the canvas out of reveal.js it works perfectly. http://codepen.io/anon/pen/eEaKh
Also when the erase function is run, it leaves a white border outside. How do I fix these problems?

just change e.pageX to e.clientX and e.pageY to e.clientY because in your codepen account
canvas origin and page origin is almost at same place but in other it is not.

To calculate the mouse position you need to subtract the position of the canvas:
Here is one way of doing this (inside the event handler):
var rect = canvas.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top;
Now your x and y will be relative to canvas.

Here's a copy/pasta of a small part of my paint app. Notice I'm using offsets of the canvas in my calculations. I also have a zoom function that scales the canvas, so taking into account that I added it to the calculation of the mouse cursor.
$('canvas').mousemove(function(e) {
// x and y are globals, x inits to null, mousedown sets x, mouseup returns x to null
if (x==null) return;
x = (100/$('#zoom').val())*(e.pageX - $(this).offset().left);
y = (100/$('#zoom').val())*(e.pageY - $(this).offset().top);
$('#debug').html(x+', '+y); // constantly update (x,y) position in a fixed div during debugging
});

Related

Get Coordinates of image on click

I have a set of divs which are dynamic, I somehow want them in a different order. So I'm using flex order to control the order of the divs. One of the div contains an image. By clicking on that image it should console the x & y coordinates of the click which is related to the image. I have made everything I want. But the problem is I'm getting the y coordinates in a negative number, I believe it is because of the order I have changed using flex.
Here's what I tried
The expected result: When I click on the border image top left position it should console the exact position of the click which is related to the image.
This is caused by your own calculations.
You can simplify the calculation using this function
GetMousePositionRelativeToTarget(e) {
// Get the target
const target = e.target;
// Get the bounding rectangle of target
const rect = target.getBoundingClientRect();
// Mouse position
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
console.log(x + ':' + y);
return [x, y];
}

SIgnature pad: Can not properly detect mouse coordinates after scaling

I am using phrogz's solution for zooming and panning. Basically for a drawing pad.
The issue is, after zooming and panning, the mouse movement and the drawing movement have a bit of distance, i.e. I mouse the mouse somewhere, it draws elsewhere.
The blue represents my actual mouse movement
Example
From his example, it may seem like he has handled it here, however, I am still facing the issue
canvas.addEventListener('mousedown',function(evt){
document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
dragStart = ctx.transformedPoint(lastX,lastY);
dragged = false;
},false);

Is there a way of clicking an specific point/element in a canvas (with javascript, jquery or selenium)

How can I apply a click at a specific position in a canvas? (using coordinates seems the most logical to me, but can't find any way to do it, any other idea is welcomed). Note that I do not have access to the code that creates the canvas.
EDIT: Some clarification, the canvas has multiple elements being drawn that i can't select with jquery but need to click them. I could find their coordinates manually and do some calculations, but every time i try to pass a click or mouse event into that position is not being taken as a real mouse click (the button that should be clicked, is not).
How about trying
canvas.on('click', function(e) {
// calculate x y coordinates on canvas
var x = e.pageX - $(this).offset().left,
y = e.pageY - $(this).offset().top;
// implement collision detection via the coordinates the element you want to click (assuming you know where it is)
if (y > <elementY> && y < <elementY> + <elementHeight>
&& x > <elementX> && x < <elementX> + <elementWidth>) {
alert('found it');
}
});
I have no time testing that snippet. If you know the x and y coordinates of your elements within your canvas, that code might just do the trick.
What I tried to do with that snippet is to simulate a bounding box via elmentY and elementY + elementHeight as well as elementX and elementX + elementWidth. If you know all those values, you can simply check whether the x and y values of your click event fall in that said box.
Edit
If you want to trigger a click event at a certain position, define the clickEvent beforehand and set the pageX and pageY attributes.
var e = new jQuery.Event("click");
e.pageX = 10;
e.pageY = 10;
$(<canvas>).trigger(e);
You might have to include the offset of your canvas in the calculations as well.

Html5 canvas hittest arbitrary shape

I'm trying to develop program which can render images and text in canvas. I tried to handle click on image in canvas, but it work for rectable images.
My question: Did you know solution or frameworks for handle click on visible part of image (not transparent part) in canvas ?
I'm looking for javascript implementation of ActionScript hitTestObject function, if someone familiar with it.
Here is simple algorithm with rectable hit text: http://jsfiddle.net/V92Gn/298/
var hitted = e.clientX >= position.x &&
e.clientX <= position.x + logoImg.width &&
e.clientY >= position.y &&
e.clientY <= position.y + logoImg.height;
Solution using pure JavaScript + canvas
For cases where the hit target is mixed with the background you can do two things:
Create a separate canvas which is stacked on top of the main canvas, draw the target object on that and do the testing of that canvas.
Create an off-screen canvas which contains the target object isolated and test on that
In this example I will use an off-screen canvas.
What we do is to basically replicate the image by creating an off-screen canvas the size of the image and draw in the image when loaded. This will protect the background and keep it transparent no matter what is on the main canvas:
Modified fiddle here
/// create an off-screen canvas to hold image
var ocanvas = document.createElement('canvas');
var octx = ocanvas.getContext('2d');
logoImg.onload=function(){
/// set off-screen canvas to same size as image
ocanvas.width = this.width;
ocanvas.height = this.height;
octx.drawImage(this, 0, 0);
... rest of code
Then using your existing code but with an adjustment for mouse position we can use the hitted variable you use to first check if we are inside the target object.
$(canvas).on('mousemove', function(e) {
/// correct mouse position so it becomes relative to canvas
var r = canvas.getBoundingClientRect(),
x = e.clientX - r.left,
y = e.clientY - r.top;
var hitted = x >= position.x && x <= position.x + logoImg.width &&
y >= position.y && y <= position.y + logoImg.height;
Now that we know we are inside the rectangle we can extract a pixel from the off-screen canvas by compensating for the object position:
if (hitted === true) {
/// extract a single pixel at the adjusted position
var pixel = octx.getImageData(x - position.x, y - position.y, 1, 1).data;
/// set hitted again based on alpha value is 0 or not
hitted = pixel[3] > 0;
}
...
As you can see in the modified fiddle we only change the class you use to red when we are on an actual pixel in the target no matter what the background of it is (when drawn separately).
Finally a couple of words on CORS: In this case, as you use DropBox, you can request CORS usage of the image simply by activating the crossOrigin property on the image object before you set the source:
logoImg.crossOrigin = ''; /// this is the same as setting anonymous
logoImg.src="http://dl.dropbox.com/...";
As DropBox (and image sharing sites such as ImgUr.com) support CORS usage they will allow the request and we can therefor extract pixels from the image.
If the servers didn't allow it however we wouldn't be able to do this. To be sure CORS is ok you should host the image in the same domain as the page when you release it.
I recommend using EaselJS which has a hitTest method similar to how it works in Actionscript:
myDisplayObject.hitTest(localX, localY);
Here you can find some demos that show the technique:
http://shallaazm.com/createjs/easeljs/tutorials/HitTest/

HTML5/Canvas Mouse Position off when placed in actual Site

I'm capturing mouse position like this
mouse_move: function(e)
{
mousePos.x = e.pageX - vr.o.context.canvas.offsetLeft;
mousePos.y = e.pageY - vr.o.context.canvas.offsetTop;
},
and it has worked like a dream in all modern browsers while in development, Even tested Wrapping the <canvas/> in a basic dom structure to make sure mouse position adjusted...
obviously now I'm putting it in the actual site it's not working...
You can see here http://jondavidjohn.com/projects/
the mouse position ends up quite a ways south of the actual cursor, anything specifically that could be causing this?
SOLUTION
mouse_move: function(e)
{
mousePos.x = e.offsetX;
mousePos.y = e.offsetY;
},
COPIED FROM: http://simonsarris.com/blog/510-making-html5-canvas-useful
Getting mouse coordinates on Canvas
Getting good mouse coordinates is a little tricky on Canvas. You could use offsetX/Y and LayerX/Y, but LayerX/Y is deprecated in webkit (Chrome and Safari) and Firefox does not have offsetX/Y.
The most bulletproof way to get the correct mouse position is shown below. You have to walk up the tree adding the offsets together. Then you must add any padding or border to the offset. Finally, to fix coordinate problems when you have fixed-position elements on the page (like the wordpress admin bar or a stumbleupon bar) you must add the ’s offsetTop and offsetLeft.
Then you simply subtract that offset from the e.pageX/Y values and you’ll get perfect coordinates in almost every possible situation.
// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
CanvasState.prototype.getMouse = function(e) {
var element = this.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));
}
// Add padding and border style widths to offset
// Also add the <html> offsets in case there's a position:fixed bar
offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
// We return a simple javascript object (a hash) with x and y defined
return {x: mx, y: my};
}
Use e.offsetX and e.offsetY for now instead.
It actually gets more complicated when you introduce some other things, like margins and padding, but offsetX and offsetY will be much more accurate than what you've got to say the least.
I don't have my new "bulletproof-works-in-every-situation" mouse code on me right now, I can get that later for you if you think you'll need it.
edit: Derp! Thanks chopperdave for finally providing the code I forgot to add!

Categories

Resources