Ad

How To Dispatch An Event Manually In Paper.JS?

- 1 answer

What I am trying to achieve is to clone an item on the canvas when I click on it and drag the clone without releasing the mouse.

             menuItem.onMouseDown = function(event){
                var clone = this.clone();
                clone.onMouseDrag = function(event){
                    this.position+=event.delta;
                    console.log(event);
                }
                var ev = new MouseEvent('mousedrag',
                            event.event);
                ev.event.type="mousemove";
                ev.delta={x:0,y:0};
                ev.target=clone;
                ev.point=event.point;
                clone.emit('mousedrag',ev);
            };

I tried this, I believe I need something like this. So when I click the menuItem I clone it, and set up the event for the clone, and then emit an event on it. But the emitted event needs to be set up, and that is where my idea falls apart. Any thoughts on this one?

Ad

Answer

I would do things a bit differently; I wouldn't try to swap the handlers in the middle of the selection/dragging but would just logically swap the items temporarily:

menuItem = new Path.Circle(view.bounds.center, 25);
menuItem.fillColor = 'red';

var oldMenuItem = null;

menuItem.onMouseDown = function(e) {
    oldMenuItem = this.clone();
    oldMenuItem.fillColor = 'green';
}

menuItem.onMouseDrag = function(e) {
    this.position += e.delta;
}

menuItem.onMouseUp = function(e) {
    // swap menuItem and oldMenuItem to keep mouse handling on the
    // original item?
    var t = this.position;
    this.position = oldMenuItem.position;
    oldMenuItem.position = t;
}

Here's a sketch that implements something similar (I think) to what you're looking for. Just pretend the red circle is the menu item.

It is possible to construct a ToolEvent or MouseEvent (depending on the handler) but that is currently undocumented and would require a trip to the source code on github. Edit: I got curious and took a trip to github.

The MouseEvent constructor code is in the events directory but the constructor is used and the .emit function is called from the CanvasView.js module (search for new MouseEvent). But in order to simulate what you want to you'll need to simulate the entire chain of events in order to keep the internal state consistent. So you'd need to 1) emit a mouseup event on the original item, 2) emit a mousedown on the new item, and 3) emit mousemoves on the new item, and 3) detach the handler from the original item and attach a handler to the new item in between 1 & 2. (You might not need to emit the original mouseup if you detach the handler before.) If you've created a Tool you will need to create a ToolEvent rather than a MouseEvent.

Anyway, I can see why it's not documented - there is a lot to keep in mind. I wanted to update this answer to reflect your original question even though the answer is still that it is probably best to find another way to perform this action.

In case someone really wants or needs to do this:

  1. Mouse events are constructed via the code in MouseEvent.js
  2. The constructor is used, and the event emitted, in CanvasView.js
  3. Event processing is driven in View.js
  4. Tool events are constructed via code in ToolEvent.js

OTOH, emitting a frame event is easy:

view.emit('frame', {});
Ad
source: stackoverflow.com
Ad