2013-03-16 38 views
0

我正在使用FabricJS開發簡單的平面圖編輯器。在畫布上添加一條線條(應該是牆壁)時,我希望能夠僅控制線條的長度,而不是寬度高度。FabricJS - 將線添加到畫布並僅控制其長度

我試過設置lockScalingY: true,但問題是,當添加一行時,控制手柄彼此之間非常接近以至於我不能僅與水平控制手柄交互......角手柄實際上會阻擋水平手柄...

這怎麼辦?

+0

上http://fabricjs.com即使看演示看來,它是越野車(無論如何Chrome) – 2013-03-16 23:39:46

回答

2

的相鄰FabricJS線

的方式圖形程序如Photoshop處理這個共同的問題是讓用戶位置線附近所需的路口,然後使用arrowkeys爲「微調」精細控制一次一行地放置一個像素。

下面的代碼說明了粗溶液,做同樣的事情FabricJS行:

  1. 用戶選擇的線。
  2. 關閉控制手柄和邊框。
  3. 讓用戶「將」線條「完美」對齊(這裏線條的長度會增加)。
  4. 重新打開控制手柄和邊框。

這只是「概念驗證」代碼。在您的生產應用程序中:

  • 您可能想使用箭頭鍵而不是按鈕來「微調」。
  • 我一次做了10px的微動 - 你可能一次只做1px。
  • 當用戶開始微調時,您將自動關閉手柄和邊框。

這裏是代碼和一個小提琴:http://jsfiddle.net/m1erickson/dd742/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
<script type="text/javascript" src="fabric.min.js"></script> 

<style> 
    body{ background-color: ivory; padding:30px; } 
    canvas{border: 1px solid red; } 
</style> 

<script> 
    $(function(){ 

     var canvas = new fabric.Canvas('canvas'); 
     var selectedLine; 

     var line1=newLine(50,100,150,100,"red"); 
     var line2=newLine(160,50,160,150,"green"); 
     canvas.add(line1,line2); 

     function newLine(x1,y1,x2,y2,color){ 
      var line=new fabric.Line(
       [x1,y1,x2,y2], 
       {fill:color,strokeWidth:15,selectable:true} 
      ); 
      return(line); 
     }; 

     $("#hOff").click(function(){ 
      selectedLine.hasBorders=false; 
      selectedLine.hasControls=false; 
      canvas.renderAll(); 
     }); 

     $("#hOn").click(function(){ 
      selectedLine.hasBorders=false; 
      selectedLine.hasControls=true; 
      canvas.renderAll(); 
     }); 

     $("#shorter").click(function(){ 
      changeLineLength(selectedLine,-10); 
      canvas.renderAll(); 
     }); 

     $("#longer").click(function(){ 
      changeLineLength(selectedLine,10); 
      canvas.renderAll(); 
     }); 

     function changeLineLength(line,adjustment){ 
      if(!selectedLine){return;} 
      if(line.get("y1")==line.get("y2")){ // line is horizontal 
       line.set("x2",line.get("x2")+adjustment); 
      }else 
      if(line.get("x1")==line.get("x2")){ // line is vertical 
       line.set("y2",line.get("y2")+adjustment); 
      }else{ // line is diagonal 
       line.set("x2",line.get("x2")+adjustment); 
       line.set("y2",line.get("y2")+adjustment); 
      } 
     } 

     canvas.observe('object:selected', function(eventTarget) { 
      var event=eventTarget.e; 
      var target=eventTarget.target; 
      selectedLine=target; 
     }); 

    }); // end $(function(){}); 
</script> 

</head> 

<body> 
    <p>Select a line,</p><br/> 
    <p>Turn handles Off</p><br/> 
    <p>Make lines intersect by pressing longer/shorter</p><br/> 
    <canvas id="canvas" width="600" height="200"></canvas> 
    <button id="hOff">Handles Off</button> 
    <button id="shorter">Shorter</button> 
    <button id="longer">Longer</button><br/> 
    <button id="hOn">Handles On</button> 
</body> 
</html> 
+0

感謝您與這個答案的努力。這不是我想要的界面,因爲我想讓用戶使用鼠標更改牆的長度,但這是一個有趣的替代解決方案。有沒有辦法只隱藏一些控制手柄? – Light 2013-03-18 13:21:47

+0

不,控制手柄顯示爲一組,而沒有對各個手柄進行精細控制。所以這些選項是這個黑客的精煉版本,或者修改源代碼是你的選擇。順便說一句,如果你想去那裏,源代碼可用並且有很好的評論;) – markE 2013-03-18 13:57:51

0

可能幫助別人。

添加處理程序事件

'object:selected': _objSelected 

然後在處理程序中設置不必要的控制爲假。

function _objSelected(e) 
{ 
    if(e.target.objectType == 'line') 
    { 
     var cv = e.target._controlsVisibility; 
     // mt - middle top, tl - top left and etc. 
     cv.mt = cv.mb = cv.tl = cv.bl = cv.tr = cv.br = false; 
    } 
} 

而且我添加的objectType(自定義屬性)和填充(美容),以新的對象行

var obj = new fabric.Line([50, 50, 150, 50], { padding: 10, objectType: 'line' });