Adding and Removing Event Listeners in Adobe Animate (HTML5) - actionscript-3

I'm trying to create an interactive HTML5 animation with Adobe Animate and I'm having an issue with my event listeners not being added or removed properly.
My intention is for the animation to always be listening for a mousedown event. When that fires, I want to listen for both mousemove and mouseup events. An object on the canvas will move with the cursor as mousemove fires and, when mouseup fires, the event listeners for both mousemove and mouseup are removed. However, the event listeners seem to persist. I've provided my code below; any help would be appreciated!
var canvas = document.getElementById('canvas');
canvas.addEventListener('mousedown', drag.bind(this));
function drag(event) {
canvas.addEventListener('mousemove', dragging.bind(this));
canvas.addEventListener('mouseup', stopDragging.bind(this));
function dragging(event) {
/* DRAG PROGRAM LOGIC */
}
function stopDragging(event) {
canvas.removeEventListener('mousemove', null);
canvas.removeEventListener('mouseup', null);
}
}

Related

MOUSE_DOWN not firing when expected - AS3, Actionscript

MOUSE_DOWN not firing when expected - AS3, Actionscript
I am not seeing the below code trace in MOUSE_DOWN fired, until I lift the mouse button back up.
This happens even on a new FLA, with only MOUSE_DOWN, MOUSE_UP and CLICK handler code -- nothing else.
Regardless of what I do, I only see MOUSE_DOWN, MOUSE_UP and CLICK traced out AFTER I lift (release) the mouse button..
See code below.
It happens if I attach the handlers to the stage;
or to a sprite.
It happens with/without buttonMode being set.
It happens with/without preventDefault() being called in CLICK..
It happens using event:MouseEvewnt or event:Event as some have suggested.
When I click, I see nothing.
When I release, I see this:
Mouse down
Mouse up
Mouse CLICK
Why don't I see "Mouse down" when clicking (before releasing)?
What the heck am I missing here?
Thank you!
stage.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent)
{
// event.preventDefault();
trace("Mouse down");
} );
stage.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent)
{
// event.preventDefault();
trace("Mouse up");
} );
stage.addEventListener(MouseEvent.CLICK, function(event:Event)
{
// event.preventDefault();
trace("Mouse CLICK");
} );

My mouse clicks created and triggered my eventListener at the same time

I tried to achieve the following but failed with the code below:
Click mouse once to appear the box.
Click it again to disappear the box.
What happened is that when I fire the mouse.click event (by clicking), that triggered the "stage.addEventListener(MouseEvent.CLICK, boxGone)" event listener as well. At the screen there is nothing happened because I technically addChild and removeChild the box at the same frame.
I am guessing my initial click created and triggered the event listener at the same time.Is there anyway to avoid this from happening without changing my triggering event(mouse click)? below is the code:
public function ClassConstructor(){
addEventListener(MouseEvent.CLICK, onMouseClickHandler);
}
private function onMouseClickHandler(e:MouseEvent):void{
box.x = stage.mouseX;
box.y = stage.mouseY;
box.gotoAndPlay(1);
stage.addChild(box);
stage.addEventListener(MouseEvent.CLICK, boxGone);
}
private function boxGone(e:MouseEvent):void{
stage.removeChild(box);
stage.removeEventListener(MouseEvent.CLICK, boxGone);
}
Thanks in advance,
Sunny
Modify your first listener with:
stage.addEventListener(MouseEvent.CLICK, onMouseClickHandler);
The event goes from your main class to the stage, and you add the second listener in between, so it is called just after the function's closure. Another solution, to be sure, would be to call
e.stopImmediatePropagation();
This prevents any listener to catch the same event.

Catching mouse events on html5 canvas when placed in the background

I placed the html5 canvas in the background using the following
style="position:fixed;top:0;left:0;z-index:-1;"
On my window.onload(), I am adding a mouse event listener to the canvas as follows
canvas.addEventListener('mousemove', onMouseMove, false)
but unfortunately my canvas is not receiving any mouse events. How do you propagate events down the z-axis? Is it possible to do it without using any external library(if exist)?
I tried searching for it but couldn't found anything relevant so far.
You want to "bubble" a mousemove event from a none-fixed element to a fixed element with different parents? I think you have to check and trigger for your own:
Build a wrapper for the none fixed element(s). This gets also a mousemove event listener. If the mousemove is over the fixed element (check clientX and clientY), trigger the mousemove event on the fixed element.
E.g. tested with firefox:
function onCanvasMouseMove(oEvent) {
console.log(oEvent);
}
// wrapper mousemove handler:
// if the mouse is over the canvas, trigger mousemove event on it.
function onWrapperMouseMove(oEvent) {
if (
oEvent.clientX <= oCanvas.offsetWidth
&& oEvent.clientY <= oCanvas.offsetHeight
) {
oEvent.stopPropagation();
var oNewEvent = document.createEvent("MouseEvents");
oNewEvent.initMouseEvent("mousemove", true, true, window, 0, oEvent.screenX, oEvent.screenY, oEvent.clientX, oEvent.clientY, false, false, false, false, 0, null);
oCanvas.dispatchEvent(oNewEvent);
}
}
var oCanvas;
window.onload = function() {
oCanvas = document.getElementById('canvas');
oCanvas.addEventListener('mousemove', onCanvasMouseMove, false);
// add mousemove listener to none-fixed wrapper
var oWrapper = document.getElementById('wrapper');
oWrapper.addEventListener('mousemove', onWrapperMouseMove, false);
};
Also see this example.
P.s.: bubbling is not the right word, it normaly means bubbling the event to the parent elements.
You could try setting the overlaid elements to pointer-events: none but this will only work in Firefox, Chrome and Safari. It might also cause you some issues if there are some elements and mouse events you do want to handle before they hit the canvas.

Is every MOUSE_DOWN guaranteed a MOUSE_UP?

Are there any circumstances under which a Flash application could receive two MouseEvent.MOUSE_DOWN without a MouseEvent.MOUSE_UP in between?
In my ActionScript 3 application, I want to track the user dragging a sprite. My plan is to listen for a MouseEvent.MOUSE_DOWN, start an indefinitely repeating timer that records the mouse position, and stop the timer on MouseEvent.MOUSE_UP. Is that a good plan?
Click but do not release the button.
While keeping the button down move the cursor outside.
Release the button outside.
Come back inside and click again.
You will get two down event without an up event.
A better solution to drag-and-drop might be to listen MOUSE_MOVE event and in the event handler check buttonDown property. If the button is down while moving, this will be true, otherwise false.
EDIT: For stage even if you release the button outside the flash window then up event is fired. So for stage this can work, but still instead of timer using MOUSE_MOVE with buttonDown looks better to me. You can check yourself with the following code:
public class StageEventTest extends Sprite
{
public function StageEventTest()
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
}
private function onDown(evt:MouseEvent):void {
trace("down");
}
private function onUp(evt:MouseEvent):void {
trace("up");
}
private function onMove(evt:MouseEvent):void {
trace("move", evt.buttonDown);
}
}
it will miss the mouse up event if the mouse is outside of the stage and continue it's mouse tracking when mousing over the stage since the mouse up event was never called. this likely problem can be mitigated by using Event.MOUSE_LEAVE - forward the mouse leave event to the mouse up event handler so that if the user mouses away from the stage the mouse up event will be called.
Yes, but unless you are listening to the stage, I think you can miss the mouseup event if the mouse has gone outside the Flash movie. Nothing beats an experiment though.
Below you can find the code I always use for custom dragging. Normally, it should work fine. I listen to the MOUSE_MOVE-event for repositioning and tracking the sprite, but you can just as well use the Event.ENTER_FRAME-event or use a timer instead.
ObjectToDrag.addEventListener(MouseEvent.MOUSE_DOWN, startCustomDrag);
public function startCustomDrag(e:MouseEvent):void
{
_prevX= e.stageX;
_prevY= e.stageY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragObject); //REPLACE BY TIMER OR Event.ENTER_FRAME
stage.addEventListener(MouseEvent.MOUSE_UP, stopCustomDrag);
}
private function dragObject(e:MouseEvent):void
{
ObjectToDrag.x += _prevX - e.stageX; //OR ANY OTHER CALCULATION
ObjectToDrag.y += _prevY - e.stageY; //OR ANY OTHER CALCULATION
_prevX= e.stageX;
_prevY= e.stageY;
}
public function stopCustomDrag(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragObject); //REPLACE BY TIMER OR Event.ENTER_FRAME
stage.removeEventListener(MouseEvent.MOUSE_UP, stopCustomDrag);
}

Actionscript 3: Preventing mouse events *except* for a specific button/movieclip?

Is there a way to block mouse events except for a specific MovieClip or Sprite?
i.e. I know that to prevent ALL mouse clicks, I can write something like:
stage.addEventListener(MouseEvent.CLICK, onPreventClick, true, 0, true);
...
private function onPreventClick(e:MouseEvent) {
e.stopImmediatePropagation();
e.preventDefault();
}
You can check e.currentTarget to find the object who fired the Event and doing your filtering according to that.