Typescript fabric.js通过toDataUrl()自定义渲染图像的大小

Typescript fabric.js通过toDataUrl()自定义渲染图像的大小,typescript,canvas,fabricjs,Typescript,Canvas,Fabricjs,我正在现有的应用程序中实现一个白板,该应用程序针对大型触摸屏(NEC显示器)进行了优化。画布本身位于一个可调整大小的小部件中,这意味着画布的可见部分可以从400x500像素到全屏大小不等。但是,只有视口得到调整,画布在beackround中始终为全屏大小(并与小部件的左上角对齐),因此在更改小部件的大小时,对象的大小和比例不会发生扭曲。这意味着,当我通过canvas.toDataUrl('png')渲染图像时,图像的大小总是相同的 现在我们想添加一个特性,画布本身可以滚动,为了方便起见,让我们说

我正在现有的应用程序中实现一个白板,该应用程序针对大型触摸屏(NEC显示器)进行了优化。画布本身位于一个可调整大小的小部件中,这意味着画布的可见部分可以从400x500像素到全屏大小不等。但是,只有视口得到调整,画布在beackround中始终为全屏大小(并与小部件的左上角对齐),因此在更改小部件的大小时,对象的大小和比例不会发生扭曲。这意味着,当我通过canvas.toDataUrl('png')渲染图像时,图像的大小总是相同的

现在我们想添加一个特性,画布本身可以滚动,为了方便起见,让我们说它的尺寸是3x3全屏,这意味着如果你需要更多的地方,你可以分别向左或向右滚动一个屏幕大小。顶部或底部。这并不难,但现在我们来问我的问题:

是否可以调整渲染功能,使图像不会从整个画布大小渲染,而是从所有元素的“边界框”大小渲染。只有选定的元素?下面是一张图片来解释:

在这张图片中,黑色正方形代表画布的实际大小(因此也代表渲染的图像),但我正在寻找一种只渲染红色正方形的方法(假设所有元素加上x像素的填充)

下面是一个真正令人讨厌的方法,但我不确定是否有更简单的方法:

  • 创建不可见的“imageRenderCanvas”
  • 在渲染时,计算最上角和最左角以及最右角和最下角,计算此“边界框”的大小 并在每侧添加2 x填充,并将此大小设置为 图像渲染器
  • 将(选定)对象置于位置
    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();
    }
    
    renderSelection(){
    const selectedObject=fabric.util.object.clone(this.canvas.getActiveObject());
    常数defaultPadding=100;
    this.dynamicCanvas=new fabric.Canvas(“#dynamicCanvas”{
    对:对
    });
    如果(selectedObject.type!=='activeSelection'){
    this.renderSingleSelectionDynamicCanvas(selectedObject,defaultPadding);
    }否则{
    此.renderMultiSelectionCanvas(selectedObject,defaultPadding);
    }
    const renderImage=this.dynamicCanvas.toDataURL('image/png');
    }
    renderSingleSelectionDynamicCanvas(selectedObject:any,默认填充:number){
    const totalWidth=selectedObject.width*selectedObject.scaleX;
    const totalHeight=selectedObject.height*selectedObject.scaleY;
    this.dynamicCanvas.setWidth(totalWidth+2*defaultPadding);
    this.dynamicCanvas.setHeight(总高度+2*defaultPadding);
    selectedObject.set({
    左:默认填充,
    顶部:默认填充
    });
    this.dynamicCanvas.add(selectedObject);
    this.dynamicCanvas.renderAll();
    }
    renderMultiSelectionCanvas(multiSelectionObject:any,默认填充:number){
    常量clonedObjects:Array=[];
    multiSelectionObject.forEachObject(对象=>{
    push(fabric.util.object.clone(obj));
    });
    const group=new fabric.group(克隆对象{
    左:默认填充,
    顶部:默认填充,
    宽度:multiSelectionObject.width,
    高度:多选对象高度,
    originX:multiSelectionObject.originX,
    原创:多选对象。原创,
    scaleX:multiSelectionObject.scaleX,
    scaleY:multiSelectionObject.scaleY
    });
    const totalWidth=multiSelectionObject.width+2*defaultPadding;
    const totalHeight=multiSelectionObject.height+2*defaultPadding;
    这个.dynamicCanvas.setWidth(totalWidth);
    此.dynamicCanvas.setHeight(总高度);
    this.dynamicCanvas.add(组);
    this.dynamicCanvas.renderAll();
    }
    
    我想实现“cropX,cropY”来实现您想要的功能,但是您的实现中有JSF吗?