2013-03-16 95 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' });