[英]Maintaining object size and position for new fabric js objects like text,etc., (acoording to general canvas)
[英]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.