You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fabric.js组缩放时固定部分对象尺寸并同步位置的实现方法

Solution for Keeping a Child Object Fixed-Sized in a Scaling Fabric.js Group

Got it, let's fix this issue where your circle gets stretched into an oval when scaling the group. The core problem is that all child objects in a Fabric.js group inherit the group's scale by default—we need to override that behavior for your linkBtn and keep its position tied to the rectangle's top center.

Here's the modified code with explanations:

var r = 15;
var rect = new fabric.Rect({ left: 50, top: 50, fill: 'blue', width: 100, height: 100 });
var linkBtn = new fabric.Circle({ 
  left: 50 + rect.width / 2 - r, 
  top: 50 - r, 
  strokeWidth: 1, 
  radius: r, 
  fill: '#fff', 
  stroke: '#666' 
});
var g = new fabric.Group([rect, linkBtn]);
g.hasRotatingPoint = false;

// Listen for scaling changes on the group
g.on('scaling', function() {
  // Cancel out the group's scale to keep the circle round and fixed-size
  linkBtn.scaleX = 1 / this.scaleX;
  linkBtn.scaleY = 1 / this.scaleY;
  
  // Recalculate the circle's position to stay at the top center of the scaled rectangle
  const scaledRectWidth = rect.width * this.scaleX;
  linkBtn.left = rect.left + scaledRectWidth / 2 - (r * this.scaleX);
  linkBtn.top = rect.top - (r * this.scaleY);
  
  // Update the object's coordinates to ensure proper interaction
  linkBtn.setCoords();
  this.setCoords();
});

canvas.add(g);

How this works:

  • Preventing shape distortion: By setting linkBtn.scaleX/Y to the inverse of the group's scale, we undo the stretching effect of the group. This keeps the circle's radius fixed at r no matter how you scale the group.
  • Maintaining position: We calculate the scaled width of the rectangle, then adjust the circle's left to stay centered above it. The top position is adjusted to stay exactly r units above the rectangle, accounting for the group's scale to avoid drifting.
  • Updating coordinates: Calling setCoords() ensures Fabric.js recognizes the new position and scale, so the circle behaves correctly during interactions.

If you're using a newer version of Fabric.js, you could also explore using lockScalingX/Y on the circle, but combining that with the position update would still require the event listener to keep it aligned with the rectangle. The above approach is reliable across most Fabric.js versions.

内容的提问来源于stack exchange,提问作者Pablo Sanchez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:53:38