2013-06-03 45 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沒有考慮到。