1

我正在使用 FabricJS 开发一个简单的平面图编辑器。在画布上添加线条(应该是墙)时,我希望能够仅控制线条的长度,而不是宽度高度。

我尝试过设置lockScalingY: true,但问题是当添加一条线时,控制手柄彼此如此接近,以至于我不能只与水平控制手柄交互......角落手柄实际上挡住了水平手柄......

如何才能做到这一点?

4

2 回答 2

2

精细控制相邻的 FabricJS 生产线

像 Photoshop 这样的图形程序处理这个常见问题的方式是让用户在所需的交叉点附近定位线,然后使用箭头键将线“轻推”到一个像素的位置。

下面的代码说明了一个粗略的解决方案,它对 FabricJS 行做同样的事情:

  1. 用户选择一条线。
  2. 关闭控制手柄和边框。
  3. 让用户“轻推”线条完美对齐(此处线条长度增加)。
  4. 重新打开控制手柄和边框。

这只是“概念证明”代码。在您的生产应用程序中:

  • 您可能希望使用箭头键而不是按钮来“轻推”。
  • 我一次轻推 10 像素——你可能一次做 1 像素。
  • 当用户开始轻推时,您将自动关闭它们的手柄和边框。

这是代码和小提琴: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>
于 2013-03-17T22:03:56.140 回答
0

可能会帮助某人。

将处理程序添加到事件

'object:selected': _objSelected

然后在处理程序将不需要的控制设置为 false。

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

我还向新对象 Line 添加了 objectType(自定义属性)和 padding(为了美观)

var obj = new fabric.Line([50, 50, 150, 50], { padding: 10, objectType: 'line' });
于 2016-02-17T09:23:39.147 回答