我正在现有应用程序中实现白板,该白板针对大型触摸屏(NEC显示器)进行了优化。画布本身位于可调整大小的小部件中,这意味着画布的可见部分可以从400x500 px到全屏大小不等。但是,只有视口会被调整,画布在beackround中始终为全屏尺寸(并与小部件的左上角对齐),因此在更改小部件的尺寸时,对象的尺寸和比例不会失真。这意味着,当我通过canvas.toDataUrl('png')
渲染图像时,图像始终是相同大小。
现在,我们要添加一个功能,使画布本身可以滚动,为简便起见,其尺寸为3x3全屏,这意味着如果您需要更多位置,则可以向左或向右滚动一个屏幕大小。上还是下。这并不困难,但是现在我们来问我一个问题:
是否可以调整渲染功能,以便不从整个画布大小渲染图像,而是从所有元素的“边界框”大小开始渲染。仅选择元素?这是一张要说明的图片:
在此图片中,黑色正方形代表画布的原始尺寸(因此将渲染图像),但是我正在寻找一种仅渲染红色正方形的方法(可以说所有元素加上x像素的填充) )。
以下是一种真正的黑客方式,但我不确定是否有更简单的方法:
0+padding / 0+padding
还有其他方法吗?
答案 0 :(得分:0)
对于感兴趣的人,我想出了以下解决方案。这基本上就是我上面所概述的内容,但是如果有更简单的方法,仍然会感到好奇。
renderSelection() {
const selectedObject = fabric.util.object.clone(this.canvas.getActiveObject());
const defaultPadding = 100;
this.dynamicCanvas = new fabric.Canvas('#dynamicCanvas', {
preserveObjectStacking: true
});
if ( selectedObject.type !== 'activeSelection') {
this.renderSingleSelectionDynamicCanvas(selectedObject, defaultPadding);
} else {
this.renderMultiSelectionCanvas(selectedObject, defaultPadding);
}
const renderedImage = this.dynamicCanvas.toDataURL('image/png');
}
renderSingleSelectionDynamicCanvas(selectedObject: any, defaultPadding: number) {
const totalWidth = selectedObject.width * selectedObject.scaleX;
const totalHeight = selectedObject.height * selectedObject.scaleY;
this.dynamicCanvas.setWidth(totalWidth + 2 * defaultPadding);
this.dynamicCanvas.setHeight(totalHeight + 2 * defaultPadding);
selectedObject.set({
left: defaultPadding,
top: defaultPadding
});
this.dynamicCanvas.add(selectedObject);
this.dynamicCanvas.renderAll();
}
renderMultiSelectionCanvas(multiSelectionObject: any, defaultPadding: number) {
const clonedObjects: Array<any> = [];
multiSelectionObject.forEachObject( obj => {
clonedObjects.push(fabric.util.object.clone(obj));
});
const group = new fabric.Group(clonedObjects, {
left: defaultPadding,
top: defaultPadding,
width: multiSelectionObject.width,
height: multiSelectionObject.height,
originX: multiSelectionObject.originX,
originY: multiSelectionObject.originY,
scaleX: multiSelectionObject.scaleX,
scaleY: multiSelectionObject.scaleY
});
const totalWidth = multiSelectionObject.width + 2 * defaultPadding;
const totalHeight = multiSelectionObject.height + 2 * defaultPadding;
this.dynamicCanvas.setWidth(totalWidth);
this.dynamicCanvas.setHeight(totalHeight);
this.dynamicCanvas.add(group);
this.dynamicCanvas.renderAll();
}