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.
Related
I have several images in my scene, I managed to make the zoom and pan work but the problem is, All of the images are zooming in at the same time. The scripts are place on each gameobject. I used gameobject for the images.
You need apply a filter so you just appli the transformations to one game object, since every one of them are GameObjects I recommend use raycast to sellect an object and then activate his Zoom.cs script just for this object.
I sugest to use just one Zoom.cs in the scene instead of every object having his own copy, then change your function to work with one game object as a paremeter and, when you touch your game object then that object will be the one to suffer the transformation.
If you doesn't want to implement a raycast or change your function at all, then you could set all the images inside a matrix, or use an index system, the central image, or the index you designed, will be the one to suffer the transformations. so you can scroll betwen your gaery and be sure that just the image that you designate in your matrix/index will be the choosen one. The trouble here is that you need to fully control the scroll animation so no one of the images will be in a wrong place like in between two index.
Is it possible to create an application using Kinetic.js where you create a shape, then scale it as you move the mouse around? I couldn't find anything in the Kinetic APIs, so I am mixing in "raw" JQuery. In particular, I use $("canvas").last().mousemove function, but it turns out this is actually very slow.
Here is the JSFiddle.
Any tips on making it faster?
I don't think the Kinetic.js has support for layer.on("mousemove", fn), because it seems to only apply to shapes.
yes. You would do something like this:
$('#container').on('mousemove', function(evt) {
shape.setScale(someValue);
layer.batchDraw();
});
In other words, attach a mousemove listener to the container div element (the one you pass into the Kinetic stage). set the shape scale with the setScale() method. Use batchDraw() instead of draw() so that the draw operation hooks into the KineticJS animation engine for much better performance. Otherwise, if you use draw(), you'll be redrawing the entire layer each time a mousemove event is detected, which could be hundreds of thousands of times per second depending on the browser
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 am creating a photo editor app where, at some point, the photo you edit is supposed to be dropped between two layers of DisplayObjects (a background image and an image mask.)
There is a problem, though. When the image you are editing is dropped between the background and the image mask layers, it becomes unclickable, and therefore gets stuck there, with no chance of dragging it again. (The photo editor uses TransformManager library.)
I am looking for a way to allow you to select the image you are editing no matter if there is another DisplayObject on top of it. And that probably means finding some way to click through the image mask.
Is there a way to do that?
I tried setting mouseChildren = false on imageMask, but that didn't have the desired effect.
Many thanks.
I had similar problems and I managed to solve it by using both
displayobject.mouseChildren = false;
and
displayobject.mouseEnabled = false;
on the object that you want to click through.
How about this?
mask.mouseEnabled = false;
You can always attach a Mouse Click listener to the container, and then either use GetObjectsUnderPoint and check for your object or do a hit test and see if the mouse position is over your intended object.
The hit test would look something like this !this.YourPhoto.hitTestPoint(stage.mouseX, stage.mouseY, false)
b
If I understand your problem, this handy class should solve it:
http://www.mosessupposes.com/utilities/InteractivePNG.html
Take a look at what senocular does here, specifically in the handleUpdate method. Basically: getting a list of everything under the mousePoint to find your object.
I think I stumbled upon similar problem, although in as2.
In flash when you position movie clip over movie clip, and the movie clip on the top has any mouse events implemented, it captures all mouse events so they never reach occluded movie clip.
The solution is not to have any mouse events for the top movie clip and have the movie clip positioned at the bottom capture mouse event and redirect some of them to the top movie clip (you can check mouse position with hitTest to determine if they should be redirected).
i had a strange bug i used;
movieClip.mouseEnabled = false;
but wasn't working for some reason.. was driving me crazy!! as i have used it so many times before. tried lots of different things nothing worked then i deleted the MovieClip and the created a new one and worked.. so the MovieClip's contents must have been corrupt or something as it had a old dynamic Text Area box embedded within the MovieClip.
hope this helps someone out there..
Hallo, I been having this problem for a while and I have no idea how to solve it.
I have a flash game (very much like a normal memory game) that has a lot of Movieclips in it that has MouseEvents attached to them. But, when I add a bitmap over the stage (used for covering lots of unwanted things and has to be there) that is the full size of the screen non of my events are fired anymore. The reason is that the overlay bitmap is stealing all of the events.
How can I stop this behavior? Is there a way of letting the events pass through the overlay object? Or for the overlay object to be ignored when it comes to events?
Thanks.
Assuming your overlay is stored in a variable m_overlay, then
m_overlay.mouseEnabled = false;
However you said it is used for "covering lots of unwanted things" so perhaps we need more information on what you are trying to achieve?
I've solved this in the past by creating "proxy" object to capture mouse clicks. The MCs under the bitmap aren't going to receive events.