can I make objects drawn in canvas response to mouse events? for example, to change colors or to display toolips on mouseover? I can adjust some values by using other types of inputs (range, radio...), but cannot make direct mouse manipulation on objects drawn in canvas.
No.
Anything drawn on html canvas becomes unremembered pixels.
What you will need to do is "remember" everything about all the things you've drawn: shape, position, color.
Then you can respond to mouse events and compare the mouse position with the bounding boxes of your remembered drawings.
If you want to change any drawing (recolor, reposition, etc), you must redraw that drawing.
Most often when you redraw any one thing, you will erase the entire canvas and redraw all items that were on the canvas.
You can listen for mouse events on the canvas. The rest is up to you. If you keep a list of objects drawn on the canvas, you can scan through the list looking for one that is under the mouse.
Related
so what I want to achieve is drawing a rectangle with either a color/fillRect or with clearRect and then copy it to the other canvas layer under the one I was drawing on. Also I want to set a background to this layer with opacity.
What I've tried is setting background with fillStyle and fillRect and it went fine. Also I could draw the rectangle with fillRect on the upper canvas which had no background and then copy the rectangle to the other one with drawImage.
Problem was when I tried to create a rectangle with clearRect and copy it. As I noticed I can only clearRect with another rectangle. But then I have to set a background to the upper canvas, which is ok, but when I copy it to the other one it gets darker and darker every time (well of course..)
So how is this possible?
When you work with alpha channel you will as you already noticed accumulate alpha channel values as long as alpha < 255. The only way to "reset" this is to start fresh so-to-speak.
Here are a couple of options to get around this -
Option 1
Don't copy anything from the draft canvas to the main canvas but store all points and shapes into a 2-dimensional array or an array consisting of the shape objects with its points, color, line width and so forth.
When you need to update the main canvas, clear both canvases and then re-render all the shapes to the main one.
Option 2
If all shapes on the main canvas is suppose to have the same opacity then use a third off-screen canvas. Draw everything to this canvas non-transparent (this last is important).
When updating main canvas clear it, set globalAlpha on it and then draw the off-screen canvas to it.
So we'll probably need some example code, because I'm not 100% sure what your trying to do... your using 2 canvas objects, drawing on the top canvas, and copying that to the bottom canvas... something like?:
ctx2.drawImage(canvas1,0,0);
then your clearing the top canvas:
ctx1.clearRect(0,0,canvas1.width,canvas1.height);
and doing your draw routine again? are you trying to get some sort of trail effect or something?
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.
Im looking for an easy to use method of assigning drag behavior to multiple objects (images, shapes etc) in canvas. Does anyone have a good way or know of any libraries for dragging objects around? Thanks
Creating your own mouse events takes a little work - ideally you should either create or use some kind of mini-library. I'm thinking of creating something like this in the near future. Anyway, I created a drag and drop demo on jsFiddle showing how to drag images - you can view it here.
You can create draggable images like this:
var myImage = new DragImage(sourcePath, x, y);
Let me know if you have any questions about this. Hope it helps.
EDIT
There was a bug when dragging multiple images. Here is a new version.
Another thing you might want to check out is easeljs it sort of in the style of AS3... mouseEvents dragging etc...
The HTML Canvas—unlike SVG or HTML—uses a non-retained (or immediate) graphics API. This means that when you draw something (like an image) to the canvas no knowledge of that thing remains. The only thing left is pixels on the canvas, blended with all the previous pixels. You can't really drag a subset of pixels; for one thing, the pixels that were 'under' them are gone. What you would have to do is:
Track the mousedown event and see if it's in the 'right' location for dragging. (You'll have to keep track of what images/objects are where and perform mouse hit detection.)
As the user drags the mouse, redraw the entire canvas from scratch, drawing the image in a new location each time based on the offset between the current mouse location and the initial mousedown location.
Some alternatives that I might suggest:
SVG
Pure HTML
Multiple layered canvases, and drag one transparent canvas over another.
The HTML Canvas is good for a lot of things. User interaction with "elements" that appear to be distinct (but are not) is not one of those things.
Update: Here are some examples showing dragging on the canvas:
http://developer.yahoo.com/yui/examples/dragdrop/dd-region.html
http://www.redsquirrel.com/dave/work/interactivecanvas/
http://langexplr.blogspot.com/2008/11/using-canvas-html-element.html
None of these have created a separate library for tracking your shapes for you, however.
KineticJS is one such Javascript Library that u can use exclusively for animations
Heres the Link html5canvastutorials
Canvas and jCanvas
You're definitely gonna want to check out jCanvas. It's a super clean wrapper for Canvas, which kicks open a lot of doors without adding code complexity. It makes things like this a breeze.
For example, here's a little sandbox of something close to what you're after, with dragging and redrawing built right in:
Drawing an Arrow Between Two Elements.
I ventured down the road of doing everything with DIVs and jQuery but it always fell short on interactivity and quality.
Hope that helps others, like me.
JP
As you create new objects whether they are windows, cards, shapes or images to be draggable, you can store them in an array of "objects currently not selected". When you click on them or select them or start dragging them you can remove them from the array of "objects not selected". This way you can control what can move in the event of a particular mousedown event or mousemove event by checking if it isn't selected. If it is selected it will not be in the "not selected" array and you can move the mouse pointer over other shapes while dragging shapes without them becoming dragged.
Creating arrays of objects you would like to drag also helps with hierarchy. Canvas draws the pixels belonging to the foremost object last. So if the objects are in an array you simply switch their instance as in element in the array say from objectArray[20] to objectArray[4] as you iterate through the array and draw the objects stored in the array elements you can change whether other objects are seen on top or behind other objects.
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.