如何在 Paper.JS 中手动发送事件?

How to dispatch an event manually in Paper.JS?

我想要实现的是在 canvas 上克隆一个项目,当我点击它并在不释放鼠标的情况下拖动克隆。

             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);
            };

我试过了,我相信我需要这样的东西。因此,当我单击 menuItem 时,我会克隆它,并为克隆设置事件,然后 emit 在其上设置事件。但是需要设置发出的事件,这就是我的想法失败的地方。对这个有什么想法吗?

我会做一些不同的事情;我不会尝试在 selection/dragging 中间交换处理程序,但会暂时从逻辑上交换项目:

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;
}

这是一个 sketch,它实现了(我认为)与您正在寻找的东西类似的东西。假设红色圆圈是菜单项。

可以构建 ToolEvent 或 MouseEvent(取决于处理程序),但目前尚未记录,需要访问 github 上的源代码。编辑:我很好奇并去了 github.

MouseEvent 构造函数代码在 events 目录中,但使用了构造函数并且从 CanvasView.js 模块调用了 .emit 函数(搜索 new MouseEvent) .但是为了模拟你想要的东西,你需要模拟整个事件链,以保持内部状态的一致性。因此,您需要 1) 在原始项目上发出 mouseup 事件,2) 在新项目上发出 mousedown,以及 3) 在新项目上发出 mousemoves,以及 3) 从原始项目分离处理程序并附加一个处理程序到 1 和 2 之间的新项目。(如果您之前分离处理程序,则可能不需要发出原始 mouseup。)如果您创建了 Tool,则需要创建一个 ToolEvent 而不是 MouseEvent.

无论如何,我明白为什么它没有记录在案 - 有很多需要记住的地方。我想更新此答案以反映您的原始问题,尽管答案仍然是最好找到另一种方法来执行此操作。

如果有人真的想要或需要这样做:

  1. 鼠标事件通过MouseEvent.js
  2. 中的代码构建
  3. CanvasView.js
  4. 中使用构造函数并发出事件
  5. 事件处理在View.js
  6. 中驱动
  7. 工具事件是通过 ToolEvent.js
  8. 中的代码构造的

OTOH,发出帧事件很容易:

view.emit('frame', {});