1

我正在尝试使用 papeJS 重新调整圆圈的大小,但是由于我使用了两个onMouseDrag函数,因此如果发生冲突。我无法创建它。谁能帮我。这是带圆圈的小提琴

这是代码。

<script type="text/paperscript" canvas="canvas">
        var raster = new Raster({
            source: 'Chrysanthemum.jpg',
            position: view.center
        });
        var path = null;
        var circles = [];
        var isDrawing = false;
        var draggingIndex = -1;
        var segment, movePath;
        var resize = false;
        project.activeLayer.selected = false;
        function onMouseDrag(event) {
            if (!isDrawing && circles.length > 0) {
                for (var ix = 0; ix < circles.length; ix++) {
                    if (circles[ix].contains(event.point)) {
                        draggingIndex = ix;
                        break;
                    }
                }
            }
            if (draggingIndex > -1) {
                circles[draggingIndex].position = event.point;
            } else {
                path = new Path.Circle({
                    center: event.point,
                    radius: (event.downPoint - event.point).length,
                    fillColor: null,
                    strokeColor: 'black',
                    strokeWidth: 10
                });

                path.removeOnDrag();
                isDrawing = true;
            }
        }
        ;

        function onMouseUp(event) {
            if (isDrawing) {
                circles.push(path);
            }
            isDrawing = false;
            draggingIndex = -1;
        }
        ;

        function onMouseMove(event) {
            project.activeLayer.selected = false;
            if (event.item)
                event.item.selected = true;
            resize = true;
        }

        var segment, path;
        var movePath = false;
        function onMouseDown(event) {
            segment = path = null;
            var hitResult = project.hitTest(event.point, hitOptions);
            if (!hitResult)
                return;

            if (hitResult) {
                path = hitResult.item;
                if (hitResult.type == 'segment') {
                    segment = hitResult.segment;
                } else if (hitResult.type == 'stroke') {
                    var location = hitResult.location;
                    segment = path.insert(location.index + 1, event.point);
                    path.smooth();
                }
            }
            movePath = hitResult.type == 'fill';
            if (movePath)
                project.activeLayer.addChild(hitResult.item);
        }
</script>
4

1 回答 1

3

首先,您的代码(在 jsfiddle 上)没有运行。

  1. paperjs 外部资源返回 404。https://raw.github.com/paperjs/paper.js/master/dist/paper.js适用于 paperjs。
  2. 光栅源用于本地文件,而不是 URI。
  3. 在 onMouseDown 中,project.hitTest引用一个 undefined hitOptions

从您的问题看来,您希望能够拖动圆段来调整圆的大小,并且您尝试使用两个onMouseDrag函数来做到这一点,但这是行不通的。相反,这两个操作应该在同一个onMouseDrag中,使用 if-then-else 在它们之间进行选择。为了使这项工作按预期进行,应将被击中的项目存储在onMouseDown而不是代码在开头找到的任何圆圈中onMouseDrag。例如,这里onMouseDrag可以“移动”或“调整大小”(此处为 jsfiddle):

<script type="text/paperscript" canvas="myCanvas">
    var raster = new Raster({
        source: 'http://i140.photobucket.com/albums/r10/Array39/Chrysanthemum.jpg',
        position: view.center
    });
    var circles = [];
    var hitItem = null;
    var currentAction = null;

    function onMouseMove(event) {
        project.activeLayer.selected = false;
        if (event.item) {
            event.item.selected = true;
        }
    }

    function onMouseDown(event) {
        hitItem = null;
        var aColor = new Color('black');
        for (var i = 0; i < circles.length; i++) {
            circles[i].fillColor = aColor;
        }
        view.draw();
        var hitResult = project.hitTest(event.point);
        for (var i = 0; i < circles.length; i++) {
            circles[i].fillColor = null;
        }
        view.draw();
        if (!hitResult) {
            return; //only happens if we don't even hit the raster
        }
        hitItem = hitResult.item;
        if (circles.indexOf(hitItem) < 0) {
            var newCircle = new Path.Circle({
                center: event.point,
                radius: 2,
                strokeColor: 'black',
                strokeWidth: 10
            });
            hitItem = newCircle;
            circles.push(hitItem);
            currentAction = 'resize';
            return;
        }
        if (hitResult.type == 'segment') {
            currentAction = 'resize';
        } else if (hitResult.type == 'stroke') {
            hitItem.insert(hitResult.location.index + 1, event.point);
            hitItem.smooth();
            currentAction = 'resize';
        } else if (hitResult.type == 'fill') {
            currentAction = 'move';
        }
    }

    function onMouseDrag(event) {
        if (!hitItem) {
            return;
        }
        if (currentAction == 'move') {
            hitItem.position = event.point;
        } else if (currentAction == 'resize') {
            if ((event.downPoint - event.point).length >= 1) {
            hitItem.fitBounds(new Rectangle(event.downPoint, event.point), true);
            }
        }
    };
</script>
<canvas id="myCanvas"></canvas>

另请注意:

  1. onMouseDown中,函数返回 if !hitResult,因此您不需要if (hitResult)在此之后立即进行测试return立即进行测试。
  2. 将变量命名为与对象相同会使搜索更加困难,例如,在您的代码path中是Path.
  3. 将相同的变量用于不同的目的会使代码更难解析,例如,在您的代码path中用于创建新的圆圈以及存储已选择的圆圈。
  4. 您有多个变量定义了两次:pathmovePathsegment
  5. 如果一个变量只在一个函数中使用,例如movePathand segment,那么如果在该函数中定义了变量,它会使代码更具可读性。此外,movePath仅在单个 if 语句中使用,它只是将项目添加回图层,但在最初绘制圆圈时,图层中唯一的项目已被删除。由于这些项目无法被击中,因此被击中的项目必须已经在图层中。
  6. segment未使用该变量。
  7. 如果函数按逻辑排序,它会使代码流动/阅读更好。在这种情况下,onMouseMove应该先走,因为它发生在单击按钮之前。然后onMouseDown下一步,因为它必须在其他动作之前发生。然后onMouseDrag,最后onMouseUp
  8. 与其在其中创建新圆圈onMouseDrag然后在下一次拖动时将其丢弃,onMouseDown不如在没有命中项目或命中项目不是圆圈时创建一个更有意义。然后在 中onMouseDown,您只需调整该圆圈的大小。 Path.scalePath.fitBounds可用于此类调整大小。
  9. 与使用多个布尔变量来跟踪当前操作(例如,调整大小与移动)不同,使用单个变量来跟踪当前操作更为合乎逻辑。
  10. 我使用的代码不是您的代码来查找该点是否在一个圆圈内,而是临时设置 circles' fillColor,执行 hitTest,然后清除 circles' fillColor。我这样做是因为当您击中笔画时,圆圈的形状会发生变化,而您的代码draggingIndex却没有考虑到这一点。
于 2013-08-05T18:10:50.560 回答