Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PressMove and PressUp fail to trigger when object disappears #606

Closed
Aurelain opened this issue Apr 16, 2015 · 3 comments
Closed

PressMove and PressUp fail to trigger when object disappears #606

Aurelain opened this issue Apr 16, 2015 · 3 comments
Labels

Comments

@Aurelain
Copy link

If you listen for "pressmove" or "pressup" on stage, it shouldn't matter what happens to the object that was under the mouse at the beginning of the drag operation.
Currently, if for whatever reason it ceases to exist, all dispatches also disappear with it.

In case this is a feature, not a bug, please let me advocate against it: imagine you are solely working with the stage. You don't have and don't wish to have knowledge of the objects present there. Let's suppose there's a MovieClip somewhere that has some frame gaps (_off: true). If you're unlucky, you might start your drag on this MovieClip, while it's in an "on" state and then the "off" comes and your unrelated stage drag just stops...

A simple standalone sample:

<canvas id="test" style="border:solid 1px red;" width="100" height="100"></canvas>
<script src="https://code.createjs.com/easeljs-0.8.0.min.js"></script>
<script src="https://code.createjs.com/tweenjs-0.6.0.min.js"></script>
<script src="https://code.createjs.com/movieclip-0.8.0.min.js"></script>

<script>
    var stage = new createjs.Stage(document.getElementById('test'));
    createjs.Ticker.addEventListener('tick', stage);

    var bg = new createjs.Shape();
    bg.graphics.beginFill('#ffff00').rect(0, 0, 100, 100).endFill();
    stage.addChild(bg);

    var circle = new createjs.Shape();
    circle.graphics.beginFill('#ff0000').drawCircle(50, 50, 25).endFill();
    stage.addChild(circle);

    stage.addEventListener('mousedown', function () {
        console.log('mousedown');
        stage.removeChild(circle); // <-- manual removal!
    });
    stage.addEventListener('pressmove', function () {
        console.log('pressmove');
    });

</script>

In the above code, we manually remove the red dot upon "mousedown".
If you started your drag on it, your "pressmove" will be lost.

@gskinner
Copy link
Member

I think what you're running into is the difference between a bubbled event vs a captured event. In the scenario you outlined, you are listening on the stage, but the event target / dispatcher is the circle instance.

What you want to do is capture the event on the stage itself (or at least higher up in the display list, where instances aren't being removed). You can do this using the mouseChildren property. For example, if you set mouseChildren = false on the stage (I think this will work on the stage), then it will cause any mouse interactions with children of the stage to be targeted to the stage itself.

I hope that makes sense. Feel free to reopen if you have more thoughts on this.

@gskinner gskinner added the FOL label Apr 16, 2015
@Aurelain
Copy link
Author

I understand your position. However, it feels unintuitive, especially when you compare it with AS3:

var tf:TextField = new TextField();
tf.border = true;
tf.type = 'input';
stage.addChild(tf);
stage.focus = tf;


stage.addEventListener('mouseDown', function(event:Event):void{
    trace('mouseDown', event.target); // [object TextField]
    stage.removeChild(tf); // removal!
});
stage.addEventListener('mouseUp', function(event:Event):void{
    trace('mouseUp', event.target); // [object Stage], it works!
});
stage.addEventListener('click', function(event:Event):void{
    trace('mouseUp', event.target); // ... never comes, somewhat justifiably
});


stage.addEventListener('keyDown', function(event:Event):void{
    trace('keyDown', event.target); // [object TextField]
    stage.removeChild(tf); // removal!
});
stage.addEventListener('keyUp', function(event:Event):void{
    trace('keyUp', event.target); // [object Stage], it works!
});

As you can see, AS3 triggers a mouseUp/keyUp, although the initial object is no longer in the display list.

I've solved my problem by using mouseChildren, but it felt a bit dirty :).

@gskinner
Copy link
Member

That reinforces my point though. The click event is not firing because it is a bubbled event that is predicated on a related target (the one you pressed on). Identically, pressMove is predicated on an related target (again, the one you pressed). On the other hand, mouseUp in AS3 is a global event that has no pre-existing target related to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants