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

FabricJS:如何同步旋转矩形与其裁剪图片(非分组方式)

FabricJS矩形与图片双向旋转同步实现方案

这是个很常见的FabricJS对象联动需求,既要实现旋转时的双向同步,又不能分组,还要保证图片基于矩形的旋转原点旋转,我来给你一步步拆解核心逻辑和具体代码实现:

核心思路拆解

要完美实现需求,得解决三个关键问题:

  • 避免旋转事件的循环触发(矩形转→图片转→矩形再转的死循环)
  • 统一二者的旋转原点,确保图片旋转时完全基于矩形的原点
  • 计算正确的同步角度:矩形旋转时,图片角度=矩形当前角度+图片初始偏移角度;图片旋转时,矩形角度=图片当前角度-图片初始偏移角度

具体代码实现

1. 初始化画布与对象

先创建画布、红色矩形和目标图片,统一二者的旋转原点,并保存图片相对于矩形的初始角度偏移:

// 初始化FabricJS画布
const canvas = new fabric.Canvas('canvas');

// 创建红色矩形容器
const rect = new fabric.Rect({
  left: 100,
  top: 100,
  width: 200,
  height: 200,
  fill: 'red',
  originX: 'center',
  originY: 'center', // 统一旋转原点为中心
  hasRotatingPoint: true
});

// 加载并初始化图片(替换为你的图片URL即可)
fabric.Image.fromURL('https://picsum.photos/200/200', (img) => {
  img.set({
    left: rect.left,
    top: rect.top,
    width: rect.width,
    height: rect.height,
    originX: 'center',
    originY: 'center', // 和矩形保持相同的旋转原点
    hasRotatingPoint: true
  });

  // 保存图片相对于矩形的初始角度差(初始状态下二者角度一致,偏移量为0)
  img.initialAngleOffset = img.angle - rect.angle;

  // 添加到画布并绑定旋转同步事件
  canvas.add(rect, img);
  bindRotationSync(rect, img);
});

2. 绑定旋转同步事件

通过一个标记位避免循环触发,实现双向同步逻辑:

function bindRotationSync(rect, img) {
  let isRotating = false; // 防止事件循环触发的核心标记

  // 矩形旋转时同步图片角度
  rect.on('rotating', () => {
    if (isRotating) return;
    isRotating = true;

    // 图片最终角度 = 矩形当前角度 + 初始角度偏移量
    img.set('angle', rect.angle + img.initialAngleOffset);
    img.setCoords(); // 更新图片交互坐标,确保旋转点位置正确
    canvas.renderAll();

    isRotating = false;
  });

  // 图片旋转时同步矩形角度
  img.on('rotating', () => {
    if (isRotating) return;
    isRotating = true;

    // 矩形最终角度 = 图片当前角度 - 初始角度偏移量
    rect.set('angle', img.angle - img.initialAngleOffset);
    rect.setCoords();
    canvas.renderAll();

    isRotating = false;
  });
}

关键细节说明

  • 统一旋转原点:将originX和originY都设为center(或你需要的自定义原点),确保图片旋转时完全贴合矩形的旋转中心,不会出现偏移错位。
  • 初始角度偏移量:initialAngleOffset用来记录图片相对于矩形的初始角度差,就算初始时图片已经有预设旋转角度,也能正确计算同步后的角度。
  • 防循环标记:isRotating标记位是核心,避免矩形旋转触发图片旋转后,图片的旋转事件又反过来触发矩形旋转,造成死循环。
  • 更新交互坐标:每次修改角度后调用setCoords(),保证对象的旋转控制点、边界框等交互元素正确更新,避免操作时出现异常。

内容的提问来源于stack exchange,提问作者Eugene Vilder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:55:08