1

FabricJS を使用して、単純なフロア プラン エディターを開発しています。キャンバスに線 (壁である必要があります) を追加するとき、幅と高さではなく、線の長さだけを制御する機能が必要です。

設定を試みlockScalingY: trueましたが、問題は、線を追加するときにコントロールハンドルが互いに非常に接近しているため、水平コントロールハンドルのみと対話できないことです...コーナーハンドルは実際に水平ハンドルをブロックします...

これはどのように行うことができますか?

4

2 に答える 2

2

隣接する FabricJS ラインの微調整

Photoshop などのグラフィックス プログラムがこの一般的な問題に対処する方法は、ユーザーが目的の交点の近くに線を配置し、矢印キーを使用して線を一度に 1 ピクセルずつ配置することです。

以下のコードは、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 に答える