2013-06-03 47 views
1

我想重新调整使用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> 
+0

我会让人们使用键盘上的其他键如果他们想调整大小。说'Shift'或'Ctrl'或其他什么,你永远不知道用户真正想做什么。顺便说一句,这也会使你的编码更容易。 – Sanchit

+0

如果没有任何重要事件,请重新调整圈子大小。但问题是圆形路径重新调整了整个圆圈的大小。你能帮我吗。 – chiyango

回答

3

首先,您的代码(在jsfiddle上)不能运行。

  1. paperjs外部资源返回404. https://raw.github.com/paperjs/paper.js/master/dist/paper.js适用于paperjs。
  2. 栅格来源为本地文件,而不是URI。
  3. 在onMouseDown上,project.hitTest引用未定义的hitOptions

从您的问题看来,您希望能够拖动圆片段来调整圆的大小,并且您已尝试使用两个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. 您有多个变量定义两次:path,movePathsegment
  5. 如果一个变量只能在一个函数中使用,例如,movePathsegment,那么如果在该函数中定义了变量,它将使代码更具可读性。另外,movePath仅在单个if语句中使用,该语句仅将项目添加回图层,但当圆圈最初绘制时,图层中未包含的唯一项目已被删除。由于这些物品不能被击中,击中的物品必须已经在图层中。
  6. 未使用变量segment
  7. 如果函数按逻辑顺序排列,它会使代码流动/读取更好。在这种情况下,应该先点击onMouseMove,因为它发生在按钮被点击之前。然后onMouseDown接下来,因为它必须发生在其他行动之前。然后onMouseDrag,最后是onMouseUp
  8. 而不是在onMouseDrag中创建新的圈子,然后在下一次拖动时丢弃它们,如果没有物品击中或者如果击中物品不是圆形,则在onMouseDown中创建一个更合理。然后在onMouseDown中,您只需调整该圆圈的大小。 Path.scalePath.fitBounds可以用于这种大小调整。
  9. 而不是使用多个布尔变量来跟踪当前操作(例如,调整大小vs移动),让单个变量跟踪当前操作更为合理。
  10. 取代您的代码来查找点是否在圆圈内,我正在使用的代码将临时设置圆圈'fillColor,执行hitTest,然后清除圆圈'fillColor。我这样做是因为当你中风时,圆形的形状发生变化,为此你的代码找到draggingIndex没有考虑到。