使在画布上绘制的形状不可移动(fabric.js)

Posted

技术标签:

【中文标题】使在画布上绘制的形状不可移动(fabric.js)【英文标题】:Make shapes drawn on canvas unmovable(fabric.js) 【发布时间】:2014-12-07 21:16:19 【问题描述】:

我今天开始使用fabric.js 在我的画布上使用不同的模式进行绘图。这意味着当我单击 lines 按钮时,我将能够在画布上绘制直线。当我按下 rectangles 按钮时,我将能够绘制矩形,并且与 freehand 按钮相同。我能够画出所有这些。

问题来了。一旦我绘制了任何形状并尝试在旧形状附近绘制其他东西,之前的形状就会变得可移动。

这是我的代码

<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
    <style>
        #myCanvas  background:url("images/<s:property value="userImageFileName"/>") ;
                 background-size: 100% 100%;
                 background-repeat: no-repeat;
    </style>    
    <script type="text/javascript" src="fabric.js"></script>
    <script type="text/javascript" src="jscolor.js"></script>
</head>
<body>
    <img id="result" src="images/<s:property value="userImageFileName"/>" hidden="true"   class="annotatable"/>
    <canvas id="myCanvas"   style="border:1px solid #d3d3d3;">Please use a modern browser like Firefox, Chrome, Safari</canvas>

    <div >Choose Color</div>
    <input class="color" id="selectedColor">

    <input type="button" value="rectangles" onClick="operate('rectangles')">
    <input type="button" value="freehand"   onClick="operate('freehand')">
    <input type="button" value="lines"      onClick="operate('lines')">
    <input type="submit" value="save"       onClick="save()">
    <br>
    <canvas id="canvas2"  ></canvas>
    <img id="canvasImg" >

    <script>
        var canvas = new fabric.Canvas('myCanvas',  selection: false );
        var drawRectangle = false;
        var color;

        function operate(mode)
        
            var line, mouseClicked = false;

            canvas.on('mouse:down', function(o)
            
                mouseClicked = true;
                var pointer = canvas.getPointer(o.e);
                color=document.getElementById("selectedColor").value;

                if(mode=="freehand")
                
                    canvas.isDrawingMode    = true;
                    drawRectangle           = false;

                    canvas.freeDrawingBrush.width = 5;
                    canvas.freeDrawingBrush.color = '#'+color;
                

                else if(mode=="lines")
                
                    canvas.isDrawingMode    = false;
                    drawRectangle           = false;

                    var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
                    line = new fabric.Line(points, 
                        strokeWidth: 5,
                        fill: 'red',
                        stroke: 'red',
                        originX: 'center',
                        originY: 'center'
                    );
                    canvas.add(line);
                

                else if(mode=="rectangles")
                
                    canvas.isDrawingMode = false;
                    drawRectangle = true;

                    origX = pointer.x;
                    origY = pointer.y;
                    var pointer = canvas.getPointer(o.e);
                    rect = new fabric.Rect(
                        left: origX,
                        top: origY,
                        originX: 'left',
                        originY: 'top',
                        width: pointer.x-origX,
                        height: pointer.y-origY,
                        angle: 0,
                        transparentCorners: false,
                        stroke: "red",
                        fill:"transparent",
                        strokeWidth: 5
                    );
                    canvas.add(rect);
                

            );

            canvas.on('mouse:move', function(o)
            
                if (!mouseClicked) return;
                var pointer = canvas.getPointer(o.e);

                if(mode=="lines")
                
                      line.set( x2: pointer.x, y2: pointer.y );
                      canvas.renderAll();
                

                else if(mode=="rectangles")
                
                     if(origX>pointer.x)
                        rect.set( left: Math.abs(pointer.x) );
                     
                     if(origY>pointer.y)
                        rect.set( top: Math.abs(pointer.y) );
                     

                     rect.set( width: Math.abs(origX - pointer.x) );
                     rect.set( height: Math.abs(origY - pointer.y) );

                     canvas.renderAll();
                

            );

            canvas.on('mouse:up', function(o)
              mouseClicked = false;
            );
        

        function save()
            var canvas2 = document.getElementById('canvas2');
            var context2 = canvas2.getContext('2d');

            var img=document.getElementById("result");
            context2.drawImage(img, 0, 0, 565, 584);
            context2.drawImage(canvas, 0, 0);

            var canvasData = canvas2.toDataURL();
            //document.write(dataURL);
            document.getElementById('canvasImg').src = canvasData;

        ;

    </script>
</body>
</html>

我也遇到了将画布保存为图像的问题。给定代码中的 saving 代码是我的旧代码,在我切换到 fabric.js 之前运行良好。

在图像中你可以看到允许我移动那个形状的形状的轮廓。但我不想要那个。我怎样才能摆脱它。

【问题讨论】:

【参考方案1】:

嗯,这似乎有点贵,但考虑将画布上的所有其他对象设置为将其selectableevented 属性设置为false。这样做可以确保他们不会在您绘图时对任何鼠标输入做出反应。

selectable 控制是否可以物理选择对象,而evented 阻止它对任何事件做出反应。

就您的save() 函数而言,您似乎正在访问常规HTML5 Canvas API 的toDataURL() 方法。这似乎可行,但请记住,fabric 在幕后使用 两个 画布元素。您可能不会获得完整的图像。使用您在代码顶部声明的fabric.Canvas 实例的toDataURL 方法,这应该就是您所需要的。您也不需要找到画布的context 或类似的东西。

【讨论】:

感谢您的回答,但我停止使用fabric,因为在一天结束时我才知道,fabric 中没有橡皮擦,很难写,也很难保存。跨度>

以上是关于使在画布上绘制的形状不可移动(fabric.js)的主要内容,如果未能解决你的问题,请参考以下文章

确定绘制到画布中的形状/图形的边界

Fabric.js 将画布(或对象组)剪辑到多边形

拖放事件时在画布上绘制的形状移动太远

缩放 fabric.js 画布对象

fabric.js 调整画布大小以适应屏幕

在 Fabric.js 中分层画布对象