Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

剪裁:添加自定义图片裁剪功能 #482

Open
momo2019 opened this issue Jul 17, 2024 · 1 comment
Open

剪裁:添加自定义图片裁剪功能 #482

momo2019 opened this issue Jul 17, 2024 · 1 comment

Comments

@momo2019
Copy link
Contributor

momo2019 commented Jul 17, 2024

修改SimpleClipImagePlugin.ts代码
增加自定义图片裁剪方法

const createCustomClip = (activeObject: fabric.Object, inverted: boolean, url: string) => {
  const { width = 0, height = 0, left = 0, top = 0 } = getBounds(activeObject);
  return new Promise<{ clipPath: fabric.Object; shell: fabric.Object }>((resolve) => {
    const shell = new fabric.Rect({
      fill: 'rgba(0,0,0,0)',
      originX: 'center',
      originY: 'center',
      width,
      height,
      left,
      top,
    });
    bindInfo(shell, activeObject);
    fabric.Image.fromURL(
      url,
      (clipPath) => {
        resolve({ clipPath, shell });
        clipPath.scaleX = width / (clipPath.width || width);
        clipPath.scaleY = height / (clipPath.height || height);
        shell.set({
          width: clipPath.width,
          height: clipPath.height,
          left,
          top,
          scaleX: clipPath.scaleX,
          scaleY: clipPath.scaleY,
        });
      },
      {
        absolutePositioned: true,
        originY: 'center',
        originX: 'center',
        left,
        top,
        inverted,
      }
    );
  });
};

添加switch中添加default

switch (name) {
  case 'polygon':
    clip = createPolygonClip(activeObject, isInverted);
    break;
  case 'rect':
    clip = createRectClip(activeObject, isInverted);
    break;
  case 'circle':
    clip = createCircleClip(activeObject, isInverted);
    break;
  case 'triangle':
    clip = createTriClip(activeObject, isInverted);
    break;
  default:
    clip = await createCustomClip(activeObject, isInverted, name);
    break;
}

取消选择的事件注册中将自定义图片的裁剪的处理方式和Polygon一致

shell.on('deselected', () => {
    if (clipPath instanceof fabric.Ellipse && shell instanceof fabric.Ellipse) {
      clipPath.set({ rx: shell.getRx(), ry: shell.getRy() });
      this.correctPosition(activeObject, shell, clipPath);
    } else if (shell instanceof fabric.Polygon || clipPath instanceof fabric.Image) {
      this.correctPosition(activeObject, shell, clipPath);
      const { scaleX: cSx = 1, scaleY: cSy = 1 } = clipPath;
      const { scaleX: sSx = 1, scaleY: sSy = 1 } = shell;
      clipPath.set('scaleX', cSx * sSx);
      clipPath.set('scaleY', cSy * sSy);
    } else {
      this.correctPosition(activeObject, shell, clipPath);
      clipPath.set('width', shell.getScaledWidth());
      clipPath.set('height', shell.getScaledHeight());
    }
    activeObject.set('dirty', true);
    this.canvas.remove(shell);
    this.canvas.requestRenderAll();
  });

效果视频

output.mp4

自定义图片规则,rgba图,透明值0和透明值大于0的为显示和非显示区域,例如
clip

@AliceLanniste
Copy link
Contributor

要不要提个pr呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants