使用paperJS重新调整圆圈大小

时间:2013-06-03 03:39:18

标签: javascript paperjs

我正在尝试使用papeJS重新调整圆圈的大小但是因为我使用了两个onMouseDrag函数,如果冲突了。我无法创建它。谁能帮我。 Here is the fiddle with circle

这是代码。

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

1 个答案:

答案 0 :(得分:3)

首先,你的代码(在jsfiddle上)不会运行。

  1. paperjs外部资源返回404. https://raw.github.com/paperjs/paper.js/master/dist/paper.js适用于paperjs。
  2. 栅格源是本地文件,而不是URI。
  3. 在onMouseDown中,project.hitTest引用了未定义的hitOptions
  4. 从您的问题看来,您希望能够拖动圆弧段以调整圆圈的大小,并且您尝试使用两个onMouseDrag函数来执行此操作,这是行不通的。相反,两个操作应该在同一个onMouseDrag中,使用if-then-else在它们之间进行选择。为了使其按预期工作,被点击的项目应存储在onMouseDown中,而不是代码在onMouseDrag开头找到的任何圈子。例如,此处onMouseDrag可以“移动”或“调整大小”(jsfiddle here):

    <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中,该函数会在!hitResult时返回,因此您无需在if (hitResult)之后立即测试return
    2. 与对象相同的命名变量使搜索更加困难,例如,在代码中pathPath的实例。
    3. 为不同目的使用相同的变量会使代码更难解析,例如,在代码中path用于创建新的圆圈以及存储已选择的圆圈。
    4. 您有两次定义的多个变量:pathmovePathsegment
    5. 如果变量仅用于单个函数,例如movePathsegment,那么如果在该函数中定义变量,则它使代码更具可读性。此外,movePath仅用于单个if语句,它只是将项目添加回图层,但最初绘制圆圈时,仅删除了图层中没有的项目。由于无法点击这些项目,因此已命中的项目必须已在图层中。
    6. 未使用变量segment
    7. 如果按逻辑顺序排列函数,它会使代码流/读更好。在这种情况下,onMouseMove应首先出现,因为它在单击按钮之前发生。然后onMouseDown接下来因为它必须在其他动作之前发生。然后是onMouseDrag,最后是onMouseUp
    8. 不是在onMouseDrag中创建新的圈子,然后在下一次拖动时扔掉它们,如果没有项目命中,或者命中项目是,则在onMouseDown中创建一个更有意义不是一个圆圈。然后在onMouseDown中,您只需调整该圈的大小。 Path.scalePath.fitBounds可用于此类调整大小。
    9. 不是使用多个布尔变量来跟踪当前操作(例如,调整大小和移动),而是让单个变量跟踪当前操作更合乎逻辑。
    10. 代替您的代码来查找该点是否在一个圆圈内,我正在使用的代码暂时设置圆圈“fillColor”,执行hitTest,然后清除圆圈“fillColor。我之所以这样做是因为当您点击笔划时,圆圈的形状会发生变化,而找不到draggingIndex的代码则不会考虑。