I'm trying to make my own button in flash application. Here is some code:
addEventListener(MouseEvent.MOUSE_OUT, Out);
addEventListener(MouseEvent.MOUSE_OVER, Over);
...
private function Over(event:MouseEvent):void
{
addChild(overImage);
}
private function Out(event:MouseEvent):void
{
removeChild(overImage);
}
When mouse is over this button, overImage is blinking. Looks like Over and Out are calling each frame. What am I doing wrong?
If the mouse is positioned in a point where overImage will appear, then that child object will cause a MOUSE_OVER event on itself and thus a MOUSE_OUT event on its parent. The parent MOUSE_OUT will remove the overImage from the display list and that wil cause again a MOUSE_OVER over the parent, startin the loop once again and making the overImage to blink.
Since you tagged this with Flex; why not use a Flex Button?
The MouseOver event will fire continuously as the mouse moves. I would perform a check before calling the addChild to see if the overImage is already parented:
private function Over(event:MouseEvent):void
{
if(!overImage.parent){
addChild(overImage);
}
}
private function Out(event:MouseEvent):void
{
if(overImage.parent){
removeChild(overImage);
}
}
I suspect that will prevent the "Blinking".
Like the other guy said use ROLL_OVER and ROLL_OUT instead, OR set the button.mouseChildren = false.
The reason it's blinking is because MOUSE_OVER and MOUSE_OUT will for every child of that button. So if you have text, or a bg image / color, or a shine, or other elements inside of it, every time you roll over ANY of those parts, it's firing.
So when you add "overImage", it appears below the mouse, and that fires another mouseOut and mouseOver. Again, just use ROLL_OVER and ROLL_OUT, OR set mouseChildren = false
Just consider using MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT events. They ignore component's children. Without any additional checks and ugly tricks.
And by the way, buttons support skins and states, so you can just include your image into 'over' state.
Related
I have this problem, I use this image pan class: http://www.lextalkington.com/blog/2009/08/auto-pan-class-for-panning-an-image-on-mouse-movement/
but the problem is that the objects/sprites/movieclips that are in it have to be clickable, only problem is that the mouseChildren adn mouseEnabled properties can't be applied to a Rectangle object.
Anyone has an idea on how to be able to click through this so I can acces my objects in the panned item? (if that makes any sense...)
This class is using a Rectangle as the scrollRect for the image. The scrollRect only specifies the visible area of the image. It is not the thing you want to detect mouse clicks on.
Instead, you can listen for a mouse click on the image itself.
From the code you linked to, the image is a DisplayObject variable named _clip.
In the constructor for that image panning class, you can add your mouse listener:
_clip.addEventListener(MouseEvent.CLICK, onImageClick);
Then define the event handler:
private function onImageClick(event:Event):void
{
// do something
}
By the way, since _clip is a DisplayObject, it doesn't have mouseChildren or mouseEnabled properties (those are defined in subclasses of DisplayObject).
_clip.mouseEnable = false;
this should work, considering tha _clip will be clicked through
`I have a movie clip that I wanted to behave as a button on mouse over and mouse out, so I added a listener to change the cursor to button and arrow in roll over and roll out:
Object(this).my_mc.addEventListener(MouseEvent.ROLL_OVER,overButton);
Object(this).my_mc.addEventListener(MouseEvent.ROLL_OUT,outButton);
function overButton(e:MouseEvent):void {
Mouse.cursor="button";
}
function outButton(e:MouseEvent):void {
Mouse.cursor="arrow";
}
The problem is that after moving the mouse over and out the my_mc and executing this code, the mouse cursor will always be arrow even when rolling over other button symbols. Is like it will only behave according to the last instruction which is the outButton function.
How can I reset the mouse cursor behavior so that it will work normally with selectable text areas and buttons?
Thanks.
You should probably be restoring the Mouse.cursor property to "auto".
Mouse.cursor="auto"
Setting it to MouseCursor="arrow" on roll out means it will always show the arrow.
However, I would recommend removing these event listeners, and setting the buttonMode property of the MovieClip to true.
It's a bit cleaner, and I'm assuming performs better b/c Flash Player manages this without any extra code.
Say I have the following;
public function onBellyPatch_Two(e:MouseEvent):void
{
inBelly_Two.visible = true;
}
inBelly_Two is a MovieClip
I have two movieclips over top of each other, when you click one MovieClip another one shows up on top, and when you click that (second MovieClip)a textBox is updated.
I noticed that even if a movieclip object's visible property is false, when you click in the area where the movie clip is the MouseEvent.CLICK event is called. Is there a way to get around this? I would like to stack movieClip.
I guess one way to get around this problem would be:
removing the eventListener when movieClip is not visible and enabling the eventListener when moviclip is visible.
Is there some otherway?
Much Thanks,
Mike
Try adding:
inBelly_Two.buttonMode = false;
This will let onBellyPatch_Two be called no matter if inBelly_Two is visible or not.
Instead of removing the listener, you can just say
mc.mouseEnabled = false;
mouseEnabled docs
I have a button with a MouseEvent.CLICK listener. The CLICK event is being triggered when the button is pushed, mouse is down while rolled out, then released when rolled in on the button again. I do not want this to happen, the click event should not occur when the button is being dragged.
My flash file contains a large amount of buttons and click listeners, I would like to solve this problem with as little code as possible. What is the simplest solution to this problem?
you need to add event listeners and handlers when they are required and remove them when they are no longer needed. you will use your own logic for your needs, but here's an example:
button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
function mouseDownEventHandler(evt:MouseEvent):void
{
evt.currentTarget.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
evt.currentTarget.addEventListener(MouseEvent.ROLL_OUT, rollOutEventHandler);
trace("Mouse Down");
}
function mouseUpEventHandler(evt:MouseEvent):void
{
evt.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
evt.currentTarget.removeEventListener(MouseEvent.ROLL_OUT, rollOutEventHandler);
trace("Mouse Click (Mouse Up)");
}
function rollOutEventHandler(evt:MouseEvent):void
{
evt.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
evt.currentTarget.removeEventListener(MouseEvent.ROLL_OUT, rollOutEventHandler);
trace("Roll Out");
}
if you have a lot of buttons which behave the same way, you should create a custom button class of which all of your buttons would be instances.
On mouse down, record the mouse coordinates, do the same on mouse up and compare the two coordinates. If the distance is more than 10px (or whatever you want) then cancel the click (or set some boolean to false that allows the code in the click listener to run).
or
On mouse down, start recording the mouse coordinates, so you know the clip has been moved, then on mouse up, you know if the clip has been moved even if the user places the clip back on exactly the same spot.
Here's my dilemma:
If I add buttons to a Sprite, I have to listen for the MOUSE_DOWN or CLICK event to make the button work as it should.
However, I want the sprite that contains the button to function like a touchscreen device, and I want the contents of the sprite to scroll up-and-down when you swipe it...
I am afraid the mouse events of the buttons will prevent the events from being captured by the container. This would mean that when I swipe over the button, the button get's clicked instead of the container.
I know Flex passes events down the chain of elements, but I don't believe this is the case for Flash.. ?
You should use MOUSE_UP event instead of MOUSE_DOWN, it's better practice, even if not to consider problems with scrolling. After there's nothing on MOUSE_UP you can hang
function onMouseDown(e: Event) {
flag = true
}
on MOUSE_DOWN. After that
function onMouseDown(e: Event) {
if (flag) {
//scrolling here
}
}
and dont forget to set flag=fasle on MOUSE_UP.