반응형
This commit is contained in:
parent
41777c9440
commit
dcdc2ee2ca
@ -5,6 +5,7 @@ import { useEditor } from "@/features/editor/hooks/use-editor";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export const Editor = () => {
|
||||
|
||||
const { init } = useEditor();
|
||||
|
||||
const canvasRef = useRef(null);
|
||||
|
79
image-ai/src/features/editor/hooks/use-auto-resize.ts
Normal file
79
image-ai/src/features/editor/hooks/use-auto-resize.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { fabric } from "fabric";
|
||||
|
||||
interface UseAutoResizeProps {
|
||||
canvas: fabric.Canvas | null;
|
||||
container: HTMLDivElement | null;
|
||||
};
|
||||
|
||||
export const useAutoResize = ({canvas,container}:
|
||||
UseAutoResizeProps) => {
|
||||
const autoZoom = useCallback(() => {
|
||||
if(!canvas || !container) return;
|
||||
|
||||
const width = container.offsetWidth;
|
||||
const height = container.offsetHeight;
|
||||
|
||||
canvas.setWidth(width);
|
||||
canvas.setHeight(height);
|
||||
|
||||
const center = canvas.getCenter();
|
||||
|
||||
const zoomRatio = 0.85;
|
||||
const localWorkspace = canvas.getObjects()
|
||||
.find((object) => object.name === "clip");
|
||||
|
||||
//@ts-ignore
|
||||
const scale = fabric.util.findScaleToFit(localWorkspace, {
|
||||
width : width,
|
||||
height: height,
|
||||
});
|
||||
|
||||
const zoom = zoomRatio * scale;
|
||||
|
||||
canvas.setViewportTransform(fabric.iMatrix.concat());
|
||||
canvas.zoomToPoint(new fabric.Point(center.left,center.top),zoom);
|
||||
|
||||
if (!localWorkspace) return;
|
||||
|
||||
const workspaceCenter = localWorkspace.getCenterPoint();
|
||||
const viewportTransform = canvas.viewportTransform;
|
||||
|
||||
if( canvas.width === undefined ||
|
||||
canvas.height === undefined ||
|
||||
!viewportTransform) {
|
||||
return;
|
||||
}
|
||||
|
||||
viewportTransform[4] = canvas.width / 2 - workspaceCenter.x *
|
||||
viewportTransform[0];
|
||||
|
||||
viewportTransform[5] = canvas.height / 2 - workspaceCenter.y *
|
||||
viewportTransform[3];
|
||||
|
||||
canvas.setViewportTransform(viewportTransform);
|
||||
|
||||
localWorkspace.clone((cloned: fabric.Rect) => {
|
||||
canvas.clipPath = cloned;
|
||||
canvas.requestRenderAll();
|
||||
});
|
||||
},[canvas, container]);
|
||||
|
||||
useEffect(() => {
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
|
||||
if (canvas && container) {
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
autoZoom();
|
||||
});
|
||||
|
||||
resizeObserver.observe(container);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect();
|
||||
}
|
||||
};
|
||||
}, [canvas,container,autoZoom]);
|
||||
};
|
@ -1,11 +1,17 @@
|
||||
import { fabric } from "fabric";
|
||||
import { useCallback } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useAutoResize } from "./use-auto-resize";
|
||||
|
||||
export const useEditor = () => {
|
||||
const init = useCallback(({
|
||||
initialCanvas,
|
||||
initialContainer,
|
||||
}: {
|
||||
const[canvas, setCanvas] = useState(null);
|
||||
const[container, setContatiner] = useState<HTMLDivElement | null>(null);
|
||||
|
||||
useAutoResize({
|
||||
canvas,
|
||||
container,
|
||||
});
|
||||
|
||||
const init = useCallback(({ initialCanvas,initialContainer}: {
|
||||
initialCanvas: fabric.Canvas;
|
||||
initialContainer: HTMLDivElement,
|
||||
}) => {
|
||||
@ -39,6 +45,9 @@ export const useEditor = () => {
|
||||
initialCanvas.centerObject(initialWorkspace);
|
||||
initialCanvas.clipPath = initialWorkspace; // clip the canvas to the workspace
|
||||
|
||||
setCanvas(initialCanvas);
|
||||
setContatiner(initialContainer);
|
||||
|
||||
const test = new fabric.Rect({
|
||||
height: 100,
|
||||
width: 100,
|
||||
|
Loading…
Reference in New Issue
Block a user