簡體   English   中英

在放大結構js時維護對象大小

[英]Maintaining object size while zooming in fabric js

即使用戶放大或縮小,是否有任何維持對象大小的解決方案? 我希望在谷歌地圖行為上實現。 因此,如果我有一個高度和寬度為20的對象(對象組),即使我放大它,它默認仍然應該是20像素。 現在我的行​​為是當用戶放大或縮小圖像時變得更大/更小。 我也在畫布上循環了所有對象,然后為它設置了scaleX和scaleY,但結果對我來說太遲了。

 var canvas = new fabric.Canvas('c') ; var circle = new fabric.Circle({ radius: 20, fill: 'red', left: 100, top: 100 }); var triangle = new fabric.Triangle({ fill: 'red', left: 200, top: 200 }); canvas.add(circle, triangle) ; //canvas.zoomToPoint(new fabric.Point(canvas.getCenter().left, canvas.getCenter().top,1)) ; $(function(){ $('#zoomIn').click(function(){ canvas.setZoom(canvas.getZoom() * 1.1 ) ; }) ; $('#zoomOut').click(function(){ canvas.setZoom(canvas.getZoom() / 1.1 ) ; }) ; }) ; 
 #canvasContainer {border: dotted gray thin ;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script> <button id="zoomIn">+</button> <button id="zoomOut">-</button> <div id="canvasContainer"> <canvas id="c" width="400" height="400"></canvas> </div> 

這不是fabricjs的內置功能,您必須通過繼承或修改fabric.Object類的標准代碼來解決它。

我將舉例說明您可以使用它來找到更適合您項目的解決方案。

因此,對於整個畫布,有一個縮放階段,然后每個對象都有自己的轉換。 這發生在fabric.Object.prototype.transform 此時縮放已完成,您無法真正避免它。 您可以做的是在繪制之前放大相反的方向。

因此,標記您不需要使用新屬性ignoreZoom默認為false進行縮放的對象。

以這種方式修改fabric.Object.prototype.transform:

transform: function(ctx, fromLeft) {
      if (this.group && !this.group._transformDone && this.group === this.canvas._activeGroup) {
        this.group.transform(ctx);
      }
      // ADDED CODE FOR THE ANSWER
      if (this.ignoreZoom && !this.group && this.canvas) {
        var zoom = 1 / this.canvas.getZoom();
        ctx.scale(zoom, zoom);
      }
      // END OF ADDED CODE FOR THE ANSWER
      var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint();
      ctx.translate(center.x, center.y);
      this.angle && ctx.rotate(degreesToRadians(this.angle));
      ctx.scale(
        this.scaleX * (this.flipX ? -1 : 1),
        this.scaleY * (this.flipY ? -1 : 1)
      );
      this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0);
      this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0);
    },

這解決了渲染問題,但沒有解決控件和緩存問題。 緩存更難理解,所以我建議您只禁用不需要縮放的對象的緩存。

對於控件我稍后會回來,不是超級簡單。

 fabric.Object.prototype.ignoreZoom = false; fabric.Object.prototype.transform = function(ctx, fromLeft) { if (this.group && !this.group._transformDone && this.group === this.canvas._activeGroup) { this.group.transform(ctx); } // ADDED CODE FOR THE ANSWER if (this.ignoreZoom && !this.group && this.canvas) { var zoom = 1 / this.canvas.getZoom(); ctx.scale(zoom, zoom); } // END OF ADDED CODE FOR THE ANSWER var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); ctx.translate(center.x, center.y); this.angle && ctx.rotate(degreesToRadians(this.angle)); ctx.scale( this.scaleX * (this.flipX ? -1 : 1), this.scaleY * (this.flipY ? -1 : 1) ); this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0); this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0); }; var canvas = new fabric.Canvas('c') ; var circle = new fabric.Circle({ radius: 20, fill: 'red', left: 100, top: 100, ignoreZoom: true }); var triangle = new fabric.Triangle({ fill: 'red', left: 200, top: 200 }); canvas.add(circle, triangle) ; //canvas.zoomToPoint(new fabric.Point(canvas.getCenter().left, canvas.getCenter().top,1)) ; $(function(){ $('#zoomIn').click(function(){ canvas.setZoom(canvas.getZoom() * 1.1 ) ; }) ; $('#zoomOut').click(function(){ canvas.setZoom(canvas.getZoom() / 1.1 ) ; }) ; }) ; 
 #canvasContainer {border: dotted gray thin ;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script> <button id="zoomIn">+</button> <button id="zoomOut">-</button> <div id="canvasContainer"> <canvas id="c" width="400" height="400"></canvas> </div> 

以下是我們如何解決此問題的以下步驟:

1.獲得比例 - (1 / zoomLevel)。 我默認將它設置為“1”。

循環所有組對象並將“scaleX”和“scaleY”設置為此類計算。

objects.forEach(object => {
  object.scaleX = (scale || 1) * 2.5;
  object.scaleY = (scale || 1) * 2.5;
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM