我正在尝试将Fabric.js与Fabric 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
答案 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仍可以在上部画布上绘制,并且在某些情况下,当上下文清除后,画笔仍会继续绘制上部画布。