Fabric.JS和Fabric-Brush-无法添加到下部画布

时间:2018-10-19 03:27:41

标签: javascript html5-canvas fabricjs

我正在尝试将Fabric.jsFabric Brush一起使用,我遇到的这个问题是Fabric Brush仅将画笔描边放到Top Canvas而不是下部Canvas上。 (fabric.js中的备用画笔保存到底部画布)我想我需要将“ this.canvas.contextTop.canvas”转换为对象并将该对象添加到下部画布。有什么想法吗?

我尝试跑步:

this.canvas.add(this.canvas.contextTop)

  onMouseUp: function (pointer) {this.canvas.add(this.canvas.contextTop)}

但是我遇到了错误

Uncaught TypeError: obj._set is not a function

2 个答案:

答案 0 :(得分:1)

所以contextTop是CanvasHTMLElement上下文。您无法添加。 您可以仅将fabric.Object派生类添加到fabricJS画布。

看起来现在不可能。 它们绘制为像素效果,然后允许您导出为图像。 扩展fabricJS笔刷接口以创建可重绘的对象会很好。

到目前为止,使用fabricJS和特定版本的fabric brush,您唯一可以做的是:

var canvas = new fabric.Canvas(document.getElementById('c'))

canvas.freeDrawingBrush = new fabric.CrayonBrush(canvas, {
  width: 70,
  opacity: 0.6,
  color: "#ff0000"
});

canvas.isDrawingMode = true

canvas.on('mouse:up', function(opt) {
  if (canvas.isDrawingMode) {
    var c = fabric.util.copyCanvasElement(canvas.upperCanvasEl);
    var img = new fabric.Image(c);
    canvas.contextTopDirty = true;
    canvas.add(img);
    canvas.isDrawingMode = false;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.1/fabric.min.js"></script>
<script src="https://tennisonchan.github.io/fabric-brush/bower_components/fabric-brush/dist/fabric-brush.min.js"></script>
<button>Enter free drawing</button>
<canvas id="c" width="500" height="500" ></canvas>

那只是从contextTop创建图像并添加为对象。

答案 1 :(得分:0)

我采用了AndreaBogazzi建议的方法,并修改了“织物刷”,以便它可以在“织物刷”内部从上到下画布(作为图像)进行传输。我还使用了一些发现的代码,该代码将图像裁剪到一个较小的边框上,从而小于画布的整个大小。 Fabric Brush中的每个画笔都有一个onMouseUp函数,应在其中放置代码。使用SprayBrush的情况,此处的原始代码为:

onMouseUp: function(pointer) { },

并用以下代码替换:

    onMouseUp: function(pointer){
        function trimbrushandcopytocanvas() {
            let ctx = this.canvas.contextTop;
            let pixels = ctx.getImageData(0, 0, canvas.upperCanvasEl.width, canvas.upperCanvasEl.height),
                l = pixels.data.length,
                bound = {
                    top: null,
                    left: null,
                    right: null,
                    bottom: null
                },
                x, y;
            // Iterate over every pixel to find the highest
            // and where it ends on every axis ()
            for (let i = 0; i < l; i += 4) {
                if (pixels.data[i + 3] !== 0) {
                    x = (i / 4) % canvas.upperCanvasEl.width;
                    y = ~~((i / 4) / canvas.upperCanvasEl.width);

                    if (bound.top === null) {
                        bound.top = y;
                    }

                    if (bound.left === null) {
                        bound.left = x;
                    } else if (x < bound.left) {
                        bound.left = x;
                    }

                    if (bound.right === null) {
                        bound.right = x;
                    } else if (bound.right < x) {
                        bound.right = x;
                    }

                    if (bound.bottom === null) {
                        bound.bottom = y;
                    } else if (bound.bottom < y) {
                        bound.bottom = y;
                    }
                }
            }
            // Calculate the height and width of the content
            var trimHeight = bound.bottom - bound.top,
                trimWidth = bound.right - bound.left,
                trimmed = ctx.getImageData(bound.left, bound.top, trimWidth, trimHeight);
            // generate a second canvas
            var renderer = document.createElement('canvas');
            renderer.width = trimWidth;
            renderer.height = trimHeight;
            // render our ImageData on this canvas
            renderer.getContext('2d').putImageData(trimmed, 0, 0);
            var img = new fabric.Image(renderer,{
                scaleY: 1./fabric.devicePixelRatio,
                scaleX: 1./fabric.devicePixelRatio,
                left: bound.left/fabric.devicePixelRatio,
                top:bound.top/fabric.devicePixelRatio
            });
            this.canvas.clearContext(ctx);
            canvas.add(img);
        }
        setTimeout(trimbrushandcopytocanvas, this._interval); // added delay because last spray was on delay and may not have finished
    },

之所以使用setTimeout函数,是因为在发生mouseup事件之后,Fabric Brush仍可以在上部画布上绘制,并且在某些情况下,当上下文清除后,画笔仍会继续绘制上部画布。