Fabric.JS 和 Fabric-Brush - 无法添加到较低的 canvas
Fabric.JS and Fabric-Brush - Can't add to lower canvas
我正在尝试使用 Fabric.js with Fabric Brush 我 运行 遇到的这个问题是 Fabric Brush 只将笔触放在顶部 Canvas 而不是底部 canvas。 (fabric.js 中的库存画笔保存到底部 canvas)我想我需要将 "this.canvas.contextTop.canvas" 转换为一个对象并将该对象添加到较低的 canvas。有什么想法吗?
我试过了运行:
this.canvas.add(this.canvas.contextTop)
在
onMouseUp: function (pointer) {this.canvas.add(this.canvas.contextTop)}
但我收到错误
Uncaught TypeError: obj._set is not a function
因此 contextTop 是 CanvasHTMLElement 上下文。你不能添加它。
您可以添加到 fabricJS canvas 只是 fabric.Object 派生的 类.
目前看来是不可能的。
它们以像素效果绘制,然后允许您导出为图像。
扩展 fabricJS 画笔接口以创建可重绘对象会很好。
截至目前,使用 fabricJS 和特定版本的织物刷,您唯一可以做的是:
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 创建图像并添加为对象。
我采用了 AndreaBogazzi 建议的方法并修改了 Fabric Brush,以便它在 Fabric Brush 内部进行从上到下的转移 canvas(作为图像)。我还使用了一些我发现的代码,这些代码将图像裁剪为更小的边界框,使其小于 canvas 的完整大小。 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
功能是因为Fabric Brush在mouseup事件发生后仍然可以绘制到上层canvas,并且有时会继续绘制上层canvas 在其上下文被清除后。
我正在尝试使用 Fabric.js with Fabric Brush 我 运行 遇到的这个问题是 Fabric Brush 只将笔触放在顶部 Canvas 而不是底部 canvas。 (fabric.js 中的库存画笔保存到底部 canvas)我想我需要将 "this.canvas.contextTop.canvas" 转换为一个对象并将该对象添加到较低的 canvas。有什么想法吗?
我试过了运行:
this.canvas.add(this.canvas.contextTop)
在
onMouseUp: function (pointer) {this.canvas.add(this.canvas.contextTop)}
但我收到错误
Uncaught TypeError: obj._set is not a function
因此 contextTop 是 CanvasHTMLElement 上下文。你不能添加它。 您可以添加到 fabricJS canvas 只是 fabric.Object 派生的 类.
目前看来是不可能的。 它们以像素效果绘制,然后允许您导出为图像。 扩展 fabricJS 画笔接口以创建可重绘对象会很好。
截至目前,使用 fabricJS 和特定版本的织物刷,您唯一可以做的是:
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 创建图像并添加为对象。
我采用了 AndreaBogazzi 建议的方法并修改了 Fabric Brush,以便它在 Fabric Brush 内部进行从上到下的转移 canvas(作为图像)。我还使用了一些我发现的代码,这些代码将图像裁剪为更小的边界框,使其小于 canvas 的完整大小。 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
功能是因为Fabric Brush在mouseup事件发生后仍然可以绘制到上层canvas,并且有时会继续绘制上层canvas 在其上下文被清除后。