Compare commits

...

2 Commits

Author SHA1 Message Date
wallace
0ecea1fd5d responsive canvas 2024-11-04 21:50:35 +09:00
wallace
e1143ef471 3강 완료 2024-10-29 21:30:58 +09:00
9 changed files with 4687 additions and 15 deletions

Binary file not shown.

4584
image-ai/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,8 @@
"@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"fabric": "5.3.0-browser",
"jsdom": "^25.0.1",
"lucide-react": "^0.453.0", "lucide-react": "^0.453.0",
"next": "15.0.0", "next": "15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020", "react": "19.0.0-rc-65a56d0e-20241020",
@ -20,13 +22,14 @@
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5", "@types/fabric": "5.3.0",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "15.0.0",
"postcss": "^8", "postcss": "^8",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"eslint": "^8", "typescript": "^5"
"eslint-config-next": "15.0.0"
} }
} }

View File

@ -1,9 +0,0 @@
const BlogPage = () => {
return (
<div>
Blog Page
</div>
);
};
export default BlogPage; // 이 부분을 작성하지 않으면 오류가 발생합니다.

View File

@ -0,0 +1,7 @@
import { Editor } from "@/features/editor/components/editor";
const EditorprojectIdPage = () => {
return <Editor />;
};
export default EditorprojectIdPage;

View File

@ -2,8 +2,9 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
body { html,
font-family: Arial, Helvetica, sans-serif; boby{
height: 100%;
} }
@layer base { @layer base {

View File

@ -6,7 +6,6 @@ export default function Home() {
<Button size ="sm"> <Button size ="sm">
Click me! Click me!
</Button> </Button>
Hello World!
</div> </div>
); );
}; };

View File

@ -0,0 +1,32 @@
"use client";
import { fabric } from "fabric";
import { useEditor } from "@/features/editor/hooks/use-editor";
import { useEffect, useRef } from "react";
export const Editor = () => {
const { init } = useEditor();
const canvasRef = useRef(null);
const ContainerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const canvas = new fabric.Canvas(canvasRef.current, {
controlsAboveOverlay: true,
preserveObjectStacking: true,
});
init({
initialCanvas: canvas,
initialContainer: ContainerRef.current!,
});
}, [init]);
return (
<div className="h-full flex flex-col">
<div className="flex-1 h-full bg-muted" ref={ContainerRef}>
<canvas ref={canvasRef} />
</div>
</div>
);
};

View File

@ -0,0 +1,55 @@
import { fabric } from "fabric";
import { useCallback } from "react";
export const useEditor = () => {
const init = useCallback(({
initialCanvas,
initialContainer, //이부분 개빡치네 왜 안되는거야
}: {
initialCanvas: fabric.Canvas;
initialContainer: HTMLDivElement,
}) => {
fabric.Object.prototype.set({
cornerColor: "#FFF",
cornerStyle: "circle",
borderColor: "#3b82f6",
borderScaleFactor: 1.5,
transparentCorners: false,
borderOpacityWhenMoving: 1,
cornerStrokeColor: "#3b82f6",
})
const initialWorkspace = new fabric.Rect({
width: 900,
height: 1200,
name: "clip",
fill: "white",
selectable: false,
hasControls: false,
shadow: new fabric.Shadow({
color: "rgba(0,0,0,0.8)",
blur: 5,
})
})
initialCanvas.setWidth(900); //시부레 initialContainer.offsetWidth로 하면 왜 안되는거야
initialCanvas.setHeight(1200);
initialCanvas.add(initialWorkspace);
initialCanvas.centerObject(initialWorkspace);
initialCanvas.clipPath = initialWorkspace; // clip the canvas to the workspace
const test = new fabric.Rect({
height: 100,
width: 100,
fill: "black",
});
initialCanvas.add(test);
initialCanvas.centerObject(test);
},
[]
);
return { init };
};