Compare commits

...

2 Commits

Author SHA1 Message Date
wallace
86bff774e6 반응형 2024-11-18 22:54:42 +09:00
wallace
dcdc2ee2ca 반응형 2024-11-18 22:39:24 +09:00
3 changed files with 104 additions and 12 deletions

View File

@ -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);

View 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]);
};

View File

@ -1,14 +1,23 @@
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,
}: {
interface UseEditorProps {
initialCanvas: fabric.Canvas;
initialContainer: HTMLDivElement,
}) => {
initialContainer: HTMLDivElement;
}
export const useEditor = () => {
const[canvas, setCanvas] = useState<fabric.Canvas | null>(null);
const[container, setContatiner] = useState<HTMLDivElement | null>(null);
useAutoResize({
canvas,
container,
});
const init = useCallback(
({initialCanvas,initialContainer}: UseEditorProps) => {
fabric.Object.prototype.set({
cornerColor: "#FFF",
cornerStyle: "circle",
@ -17,7 +26,8 @@ export const useEditor = () => {
transparentCorners: false,
borderOpacityWhenMoving: 1,
cornerStrokeColor: "#3b82f6",
})
}
)
const initialWorkspace = new fabric.Rect({
width: 900,
@ -28,7 +38,7 @@ export const useEditor = () => {
hasControls: false,
shadow: new fabric.Shadow({
color: "rgba(0,0,0,0.8)",
blur: 5,
blur: 5
})
})
@ -39,6 +49,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,
@ -48,8 +61,7 @@ export const useEditor = () => {
initialCanvas.add(test);
initialCanvas.centerObject(test);
},
[]
);
[]);
return { init };
};