在 PaperJS 中,当鼠标离开项目时,如何 link onMouseUp 事件到 onMouseDown 事件的起源

In PaperJS how to link onMouseUp event to origin of onMouseDown event when mouse has moved away from item

在我的 PaperJS 项目中,我有一堆对象,它们有一个与之关联的圆形路径。这些路径均具有鼠标功能。

我想做的是在单击一个圆圈、拖动鼠标并在另一个圆圈上释放鼠标按钮时在两个圆圈之间创建链接。

为此,我使用了 PaperJS onMouseDownonMouseUp 事件,在对象内部实现如下:

function CircleObj() { // the object constructor
   this.circle = new Path(...);
   this.circle.onMouseDown = function(event) {
      //eventstuff
   }
}

其中 this.circle 是圆形路径。

问题是,当我释放鼠标按钮时,它不再链接到圆圈,因此 onMouseUp 函数不会执行,直到我再次单击实际的圆圈。因此,这不允许您拖放到另一个圆圈上,因为 'drop' 操作未注册。

如何让 onMouseUp 活动注册并链接到 onMouseDown 活动发生的圈子?

如果你想让你的鼠标事件与你的构造函数相关联,我认为最简单的方法是将初始点保存在一个全局变量中。它肯定比在视图中添加和删除 Tool Event 并检查命中对象是圆而不是线或其他对象要干净。

var firstPoint = null;

function circleObj(p) {
    this.circle = new Path.Circle({
       center: p,
       radius: 20,
       fillColor: 'red'
    });
    this.circle.onMouseDown = function(event) {
            firstPoint = this.position;
    }
    this.circle.onMouseUp = function(event) {
        if (firstPoint !== null){
            var path = new Path.Line({
                from: firstPoint,
                to: this.position,
                strokeColor: 'black',
                strokeWidth: 40,
                strokeCap: 'butt'
            });
            path.sendToBack();
            firstPoint = null;
        }
    }
}

function onMouseDown(event){
    if (!event.item){
        circleObj(event.point);
        firstPoint = null;
    }
}

这有点复杂,但它通过将问题封装在一个对象中来避免全局变量。请注意草图版本底部的 new Tool() - 这仅在 sketch.paperjs.org 中是必需的,以便覆盖处理程序草图安装。

function Circles() {
    this.group = new Group();
    this.circleNumber = 0;
    this.downItem = null;

    view.on('mousedown', function(e) {
        var hit = this.group.hitTest(e.point);
        // if we didn't hit this group add a circle
        if (!hit) {
            var circle = new Path.Circle({
                center: e.point,
                radius: 20,
                fillColor: 'red',
                name: 'circle' + this.circleNumber
            });
            this.group.addChild(circle);
            this.circleNumber++; 
            this.downItem = circle;
            return;
        }
        // we hit a circle
        this.downItem = hit.item;
    }.bind(this));

    view.on('mouseup', function(e) {
        var hit = this.group.hitTest(e.point);
        // if we hit a circle and it's not the same
        // as the downItem circle
        if (hit && hit.item !== this.downItem) {
            var line = new Path.Line({
                from: this.downItem.position,
                to: hit.item.position,
                strokeColor: 'black',
                strokeWidth: 20,
                strokeCap: 'butt'
            });
            line.sendToBack();
            this.downItem = null;
        }
    }.bind(this));
}

circles = new Circles();

这里有一个 sketch 如果你想玩的话。