I've got a pure AS3 (no Flex) project that uses Flare to display and interact with a data visualization. I just implemented some panning behavior, so you can click and drag the visualization around, and now I'd like to give the user a visual indicator that this is possible, by switching the arrow cursor with a nice grabby-looking hand icon.
The user can click and drag at any time except when the mouse is over a clickable node (at which time the cursor swaps to a pointer - this behavior is already in place).
So...
1) Do I need to create my own custom bitmap/sprite or is there a palette of built-in cursors I can use? (I'm not using Flex.)
2) Is there a way to simply replace the default arrow with the pan cursor project-wide, or do I need to attach the swapping to mouse events on display objects? Can I use the stage object to make this behavior apply everywhere?
3) How do I perform the swap? Do I use the Cursor object directly or do I need to get involved with the CursorManager?
Any guidance, pseudo-code, or words of wisdom is greatly appreciated!
I don't think there's a CursorManger in flash, only flex. The way i'm doing is with a custom class which hides the cursor and drags the customized cursor at mouse_move. You have to set it to mouseChildren=false, otherwise will flickr or the buttons will not be clickable. One problem i found is with custom contextual menus. Try this link http://abrahamyan.com/2009/03/23/as3-cursormanager/
A few things I learned (all pretty newby, really). Firstly, there are some built-in cursor options you can set by setting Mouse.cursor to any of the options of MouseCursor.TYPE. The Mouse object is a singleton available app-wide, so anywhere you change it in your code, the change persists until another change is triggered.
For my simple case, I did this:
//on init, start with the "hand"
Mouse.cursor = MouseCursor.HAND;
//on clickable items, change to "pointer", then back to "hand"
myClickableNode.addEventListener(MouseEvent.ROLL_OVER, function(evt:Event):void {
Mouse.cursor = MouseCursor.BUTTON;
});
myClickableNode.addEventListener(MouseEvent.ROLL_OUT, function(evt:Event):void {
Mouse.cursor = MouseCursor.HAND;
});
The result is you always have the "hand" until you rollover something clickable, then you get the "pointer".
Related
Im developing a flash game, and i would love to implement raining effect. Here's my progress on rain so far: http://www.squ4re.eu/Rain.html
The code is pretty simple; every raindrop is an object, when it hits the ground it places itself again at the top of the screen and adds splash animation.
But the problem is to click something BEHIND the rain. Lets say i have some selectable units at the battleground. In most cases an random raindrop interrupts selecting an object behind it. So here's my question: Is it possible in flash to create object "transparent" to mouse click, so i can click an object behind it? Or is there any other way to solve this problem?
Thank you in advance.
As #putvande mentioned, you could use mouseEnabled on every interactive object that should be disabled for mouse interaction. You also could create rainLayer and disable it for mouse interaction:
myRainLayer.mouseEnabled = false;
myRainLayer.mouseChildren = false;
mouseChildren - determines whether or not the children of the object are mouse, or user input device, enabled. If an object is enabled, a user can interact with it by using a mouse or user input device. The default is true.
Also consider to use display objects that don't inherit from InteractiveObject, like Bitmap, Shape and Video
I'm using GWT 2.4 Drag and Drop API to drag elements for data transfer between widgets. Implementing the Drag and Drop behaviour was straight forward but I'm having problems changing the cursor while dragging an element.
I've done a bit of research and I've found a few articles on how I could achieve this.
This article http://blog.vjeux.com/2012/css/css-cross-browser-drag-cursor.html suggests that it can be done by setting the cursor property to whichever acceptable value we would want. I've tried (cursor: -webkit-drag; or cursor: move;) on the element to be dragged or the element where an element can be dropped but only added a small image to the bottom right of the cursor icon.
Took a look at this http://www.html5rocks.com/en/tutorials/dnd/basics/, it is said that the cursor(effect) can be changed when dragging or dropping by setting effectAllowed and dropEffect from the dataTransfer object. Despite the GWT Drag and Drop API not exposing none of these properties, I can set them through JSNI yet the effect was the same as before (with CSS).
I've found these questions HTML5 Drag & Drop Change icon/cursor while dragging and Changing Mouse Cursor for HTML5 Drag Drop Files (GMail Drag Drop) on the same subject but none seemed to help to actually change/replace the icon while dragging.
Any help is appreciated.
Test environment:
Ubuntu 12.04.1
Chrome 22
Cheers,
I guess the easiest way is to use:
RootPanel.getBodyElement().getStyle().setCursor(Cursor.MOVE);
whenever you start moving and:
RootPanel.getBodyElement().getStyle().setCursor(Cursor.DEFAULT);
whenever your done.
Also you can set CSS-property:
cursor: whatever;
on whatever element you want. You would usually use it like this:
div.over-this-div-the-cursor-becomes-different:hover {
cursor: move;
}
see: http://www.w3schools.com/cssref/pr_class_cursor.asp
Is there a way to set the priority (CursorManagerPriority.HIGH) of a mouse cursor set via Mouse.cursor = '...';?
Long story short, I've had to resort to using the CursorManager to apply cursors, because setting the priority is crucial for my application due to the HTML control overriding all cursor changes without a high priority. Setting cursors with the cursor manager totally works, but the cursors aren't as fast/response as those rendered at the OS level (as described here).
If there isn't a way, my next question is: is there any way to suppress the cursor changes made by the HTML control? Setting mouseEnabled = false does it... but disables all mouse events on the HTML page, so that doesn't work.
Example:
This doesn't work:
setInterval(function():void { Mouse.cursor = 'ibeam'; }, 100);
Setting a cursor with a high priority works, however:
// ibeamCursor is an embedded PNG
CursorManager.setCursor(ibeamCursor, CursorManagerPriority.HIGH, -2, -4);
(this code is used at mx:Application scope)
I'm going to assume that you have access to the code for the HTML control...otherwise, I'm not sure you can do this at all.
I don't think you can set priority on cursors set by Mouse.cursor = "..."; (tho I could be wrong...if anyone has info to the contrary, feel free to correct me.)
However, I think you can very easily suppress cursor changes simply by using a boolean variable and an if-statement.
var customCursors:Boolean;
Then, on each place where the cursor changes occur...
if(customCursors == true)
{
Mouse.cursor = "mycursor";
}
This will allow or suppress changes to the cursors, simply by changing the customCursors variable.
However, there may be something more useful if you're dealing with two conflicting cursors, and you want one to only take place during certain instances. For that, you could try a different if statement.
In my own code, I want one cursor to show up only while dragging an object, but not just while the mouse is over it. One is inside the move event, and the other inside the over event. There was a third that would show up only when the object was dragged over a certain point, and when it was not, it needed to be the regular dragging cursor.
This created a rather annoying conflict...
To fix that, I actually checked the Mouse.cursor property in my if statement! The placement of various Mouse.cursor statements in my events created a sort of priority for the cursors. It works perfectly.
In my mouse over statement:
Mouse.cursor = "hand";
In my mouse down statement (where I start dragging):
Mouse.cursor = "dragging";
In my move statement:
if(Mouse.cursor == "draggingover")
{
Mouse.cursor = "dragging";
}
In my mouse up statement (where I stop dragging):
Mouse.cursor = "hand";
In my mouse out statement:
Mouse.cursor = "pointer";
I hope this helps! If it does, don't worry about overlooking this seemingly obvious solution...I think we're all prone to do so when we're looking for built-in functions.
If this isn't helpful, sorry. Again, I don't think there is another way, but if anyone knows of one, please weigh in.
I believe HTML control inherits from ScrollControlBase. Try fixing your Mouse issues on that parent control, rather than on the HTML control.
Also, you can try overriding the HTML control, adding code to remove default cursor look and feel. See this blog post, and just do the opposite.
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 want to create a dialog or alert box, where a DisplayObject would take and force the focus, until an okay button or something releases the lock. thanks.
The easy way to do this is to make your "dialog" as big as the stage, with a whacking great transparent area around the dialog itself.
The transparent area can listen for any mouse clicks, and just swallow them (which will prevent them being picked up by stuff further back in the display list).
To show the alert, just stick it on top of everything else, When the user closes it, take it away again.
If you are using flex and actionscript, simply use a SkinnablePopUpContainer
var alt:CustomPopUp = new CustomPopUp();
alt.open(this,true) //the second variable is for modal, which will disable view
this.enabled = false; //this will grey out the parent view and provide visual focus to your popup.
To do this, you will need to disable access to all objects under your 'alert' DisplayObject. There are multiple ways of doing this, here 2 I can think off:
Loop through the display list and disable any display objects under your alert depth wise.
Cheat it with a blocker. When you display your alert, display another clip (could have alpha set to 0 ) that blocks the user from hovering/clicking objects. The blocker might need a bit of setup( buttonMode = true, useHandCursor = false, etc. )
This 'modal' behavior has been around for some so there might be no need to reinvent the wheel, depending of your current setup.
If you're using the Flex framework, you've got the functionality in, for Flash you can use the Alert Manager from the Yahoo! Flash Astra Components:
Goodluck,