I am playing around with HTML5 Canvas to develop an interactive personal website.
I created a canvas 400x200 and then put a background image on it. Now on top of the BG Image, I have placed 5 more images. Now, my requirement is, depending on the image clicked I want to 1, display a text outside of the canvas, and 2, grey out the other 4 images (more in an animated form).
I am able to accomplish till displaying the images, I am unable to create a click event action. Is it because the whole canvas is treated as one single image? if so would using #usemap work? I tried adding a addEventListener event but nothing is happening.
is there a easier way in SVG to accomplish the same?
Thanks for any pointers.
You can add click handler on the canvas using jquery like this
$("#canvasId").click(function(e){
alert("canvas clicked";
}
Now you will have to determine the image at which the click event was occurred. If you know the top-left and bottomRight corner of the image you can determine the image on which you had clicked. To determine the mouse location you can use something like following
var x = Math.floor((e.pageX-$("#canvasId").offset().left) / 20);
var y = Math.floor((e.pageY-$("#canvasId").offset().top) / 20);
Related
I'm using the konvajs library to draw multiple images to a canvas. The images are transparent on certain points.
Now I want to attach a click handler to the images, but the click handler shouldn't be fired if the image is transparent on that point / promote the click handler to the udnerlying image.
However currently the image on top get's all the click handlers. Is there a way to ignore click events on transparent parts of an image?
After looking throw the konvajs doku, I found this image sample: http://konvajs.github.io/docs/events/Image_Events.html
Hovering the lion does exactly what I want!
Is it possible to create some stack of transparent HTML5 canvases with event propagation?
For instance, I have a background canvas with drawn image on it with some attached click handler. After, I want to add another one canvas over the background canvas with exactly same size, also it has transparent zones. The question is, will the click handler of background canvas be fired if I click on it over the top layer?
will the click handler of background canvas be fired if I click on it over the top layer?
No it will not. The canvas blocks events from things behind it.
Generally you have two options: Put events on each canvas and make a system of letting them "fall through" if nothing happens on the first canvas, or putting events only on the topmost canvas and using those one events to do operations concerning all canvases.
I suggest the second approach. Keep all the events on only the topmost canvas.
I have a canvas element with a photo loaded on it. When clicking a link, the following is performed:
var ctx = canvas.getContext("2d");
ctx.scale(-1,1);
ctx.drawImage(canvas, canvas.width * -1, 0, canvas.width, canvas.height);
This works as expected (the image is flipped horizontally) on the first click, the third click, the fifth click, etc. On the second click, the fourth click, the sixth click, etc, nothing happens.
Any ideas on how I can get this to work for every click?
Yeah, the problem is because you're not restoring the canvas scale to 1,1 after you draw the image, so basically the first time the event is called your canvas scale is gonna be turned into -1,1 the next time it's gonna be 1,1 but you need it to be always -1,1. That's because you're drawing the image directly from the canvas and not from an image element thus, you gonna need to flip it every time.
Try using ctx.save() before the scaling and ctx.restore() after drawing the image. Or calling ctx.scale(-1, 1) again after drawing the image. Or you could just do the scaling outside the event (but after you've drawn the image to the canvas the first time) if your canvas is only used for this.
This here works for every click:
http://jsfiddle.net/4kcjn/2/
Ask yourself, what is different between it and yours?
It could be image-load related. Try yours without an image. Does it still have the same problem?
I'm trying to figure out how to drag and drop an image from one canvas to another canvas. Assuming the canvases are next to each other, would it be possible to seamlessly drag something across the border? If not, is it a better idea to drag a div over the canvas, get its ID, and place it by responding to the mouseup location on the canvas?
You don't drag items on a canvas. A canvas is a non-retained mode (or immediate mode) graphics API. You issue draw commands and you get pixels. Simulating dragging is comprised of tracking the user's mouse movements and choosing to repeatedly clear and re-draw the canvas with different parameters to make some subset of the pixels appear to move as a cohesive object.
Contrast this with HTML or SVG where you actually change position/transform properties of a real DOM object and the watch as the visual representation of your document updates automatically.
If you have two canvases and want to drag something from one to the other, what I would do is:
On mouse down on the 'menu' canvas, create a new canvas programmatically just as large as the object, and (using absolute CSS positioning) place it over top of the item the user clicked on.
Draw the item onto that canvas.
Track the mousemove event on the document, and update the position of the canvas relative to the mouse.
When the user releases the mouse over the destination canvas, throw away (or hide) your tiny 'dragging' canvas, and re-draw the main canvas with the item that was dragged in the appropriate location.
Though, what I'd probably really do here is use SVG. ;)
Check this answer.
It is for multiple select drag & drop, but maybe will be useful.
Why does this need to be 2 canvases? The canvas is your drawing area, you control it. Why do you need 2?
I'm working with the Canvas Tag to draw stuff to the screen, I have like 3 different shapes on the screen, and I want to make them linkable, they could be at different coordinates depending on the users interaction, is this possible with this?
Thanks!
You could attach an onmousemove handler to the element, and track the offset, if you need the mouse coordinates. Then you can just draw onto the canvas with those coords.