尝试创建一个自定义类,该类将在Fabric矩形的左上角显示图像。
扩展结构类并调用ctx.drawImage
不会显示任何内容。
var CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
const image = new Image();
image.src = signBtn;
this.callSuper('initialize', options);
this.set('label', options.label || '');
this.set('image', image);
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
ctx.drawImage(this.image, this.left+10, this.top-5, 15, 15);
}
});
fillText
工作正常,并且标签显示正确。
尝试了几种不同的方法,认为未加载图像。它作为SVG导入。我已经将其显示为其他方式,但更喜欢让自定义类来处理此事件,而不是事件处理程序。
答案 0 :(得分:1)
您需要在加载后设置图像。您可以使用image.onload事件回调,也可以使用fabric.util.loadImage
演示
PathPrefix
myDomain.demo:7479/neo4j/myNeo/browser
fabric.CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'customRect',
initialize: function(options) {
options || (options = { });
var that = this;
this.imageLoaded = false;
fabric.util.loadImage(options.signBtn,function(img){
that.set('image', img);
that.imageLoaded = true;
that.dirty = true;
//if canvas is global
canvas.renderAll();
},{
crossOrigin : 'annonymous'
});
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.label,
image : this.image
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
this.imageLoaded && ctx.drawImage(this.image, 10, -5, 15, 15);
}
});
fabric.CustomRect.fromObject = function(object, callback) {
return fabric.Object._fromObject('CustomRect', object, callback);
};
var url = 'https://upload.wikimedia.org/wikipedia/en/8/80/Wikipedia-logo-v2.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.CustomRect({
signBtn: url,
left : 10,
top : 10,
width : 200,
height: 200,
fill: 'green',
label : 'test'
});
canvas.add(rect);
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
答案 1 :(得分:1)
我相信还有一些缺少的值,例如this.width
和this.height
?
除此之外,您还必须等到图像加载后才能绘制图像。您可以执行以下操作:
var CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
const image = new Image();
image.src = 'https://i.stack.imgur.com/CYp8Y.jpg';
this.callSuper('initialize', options);
image.onload = (function() {
this.width = image.width;
this.height = image.height;
this.image_loaded = true;
}).bind(this);
this.set('label', options.label || '');
this.set('image', image);
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
if (this.image_loaded) {
this.callSuper('_render', ctx);
console.log(-this.width / 2, -this.height / 2);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
}
}
});
请注意这两个更改:
image.onload = (function() {
this.width = image.width;
this.height = image.height;
this.image_loaded = true;
}).bind(this);
加载图像后,我在image_loaded
方法中将initialize
设置为true。然后,在_render
方法中,检查图像是否已加载,然后绘制图像。
if(this.loaded){
//............
ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
}
这是一个小提琴:https://jsfiddle.net/nimeshka/enL61g0w/55/
您可能需要单击画布以触发render
事件。否则,您将不会在输出框中看到该矩形。 (我没有添加)
希望对您有所帮助:)