feat: Add editor UI toggle functionality
- 캔버스 편집 UI 표시/숨김 기능을 추가했습니다. - 에디터 툴바에 토글 버튼을 추가하여 UI 표시 상태를 제어할 수 있습니다. - 에디터 UI가 숨겨졌을 때 캔버스에 마우스 이벤트가 전달되지 않도록 수정했습니다.
This commit is contained in:
parent
0c3c0b606e
commit
fed9dc7606
6
.idea/AICommit.xml
generated
Normal file
6
.idea/AICommit.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="com.github.blarc.ai.commits.intellij.plugin.settings.ProjectSettings">
|
||||
<option name="splitButtonActionSelectedLLMClientId" value="2f900cba-1f90-431b-acb2-e4e6ac66b31e" />
|
||||
</component>
|
||||
</project>
|
||||
30
dist/index.css
vendored
30
dist/index.css
vendored
@ -11,6 +11,36 @@
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
.editor-toolbar {
|
||||
max-width: 1600px;
|
||||
margin: 0 auto 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
.editor-toggle-btn {
|
||||
padding: 10px 20px;
|
||||
background: #383838;
|
||||
color: #e0e0e0;
|
||||
border: 2px solid #555;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.editor-toggle-btn:hover {
|
||||
background: #404040;
|
||||
border-color: #00aaff;
|
||||
}
|
||||
.editor-toggle-btn.active {
|
||||
background: #2d5a7a;
|
||||
border-color: #00aaff;
|
||||
color: #fff;
|
||||
}
|
||||
.editor-main {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
2
dist/index.css.map
vendored
2
dist/index.css.map
vendored
File diff suppressed because one or more lines are too long
49
dist/index.js
vendored
49
dist/index.js
vendored
@ -655,7 +655,8 @@ var EditorCanvas = ({
|
||||
draggingPointIndex,
|
||||
onStartDragging,
|
||||
onStopDragging,
|
||||
style: customStyle
|
||||
style: customStyle,
|
||||
showEditor = true
|
||||
}) => {
|
||||
const containerRef = (0, import_react4.useRef)(null);
|
||||
const [canvasSize, setCanvasSize] = (0, import_react4.useState)({ width: 0, height: 0 });
|
||||
@ -704,7 +705,7 @@ var EditorCanvas = ({
|
||||
);
|
||||
const handleCanvasMouseDown = (0, import_react4.useCallback)(
|
||||
(e) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
const y = (e.clientY - rect.top) / rect.height;
|
||||
@ -715,11 +716,11 @@ var EditorCanvas = ({
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
[selectedArea, isPointInPolygon]
|
||||
[showEditor, selectedArea, isPointInPolygon]
|
||||
);
|
||||
const handleMouseMove = (0, import_react4.useCallback)(
|
||||
(e) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
const y = (e.clientY - rect.top) / rect.height;
|
||||
@ -738,7 +739,7 @@ var EditorCanvas = ({
|
||||
setDragStartPos({ x, y });
|
||||
}
|
||||
},
|
||||
[draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
[showEditor, draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
);
|
||||
const handleMouseUp = (0, import_react4.useCallback)(() => {
|
||||
if (draggingPointIndex !== null) {
|
||||
@ -829,12 +830,19 @@ var EditorCanvas = ({
|
||||
{
|
||||
ref: containerRef,
|
||||
className: "editor-canvas",
|
||||
style: { width, height, position: "relative", cursor: getCursorStyle() },
|
||||
onMouseDown: handleCanvasMouseDown,
|
||||
onMouseMove: handleMouseMove,
|
||||
style: {
|
||||
width,
|
||||
height,
|
||||
position: "relative",
|
||||
cursor: showEditor ? getCursorStyle() : "default",
|
||||
pointerEvents: showEditor ? "auto" : "none"
|
||||
// 에디터 숨김 시 포인터 이벤트 비활성화
|
||||
},
|
||||
onMouseDown: showEditor ? handleCanvasMouseDown : void 0,
|
||||
onMouseMove: showEditor ? handleMouseMove : void 0,
|
||||
children: [
|
||||
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ImageDistortion, { imageSrc, areas }),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
||||
showEditor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
||||
"svg",
|
||||
{
|
||||
style: {
|
||||
@ -863,7 +871,7 @@ var EditorCanvas = ({
|
||||
})
|
||||
}
|
||||
),
|
||||
selectedArea && canvasSize.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
||||
showEditor && selectedArea && canvasSize.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
||||
"canvas",
|
||||
{
|
||||
style: {
|
||||
@ -887,7 +895,7 @@ var EditorCanvas = ({
|
||||
}
|
||||
}
|
||||
),
|
||||
selectedArea && selectedArea.basePoints.map((point, index) => {
|
||||
showEditor && selectedArea && selectedArea.basePoints.map((point, index) => {
|
||||
const handleStyle = editorStyle.pointHandle || {};
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
||||
"div",
|
||||
@ -1149,6 +1157,7 @@ var DistortionEditor = ({
|
||||
stopDragging,
|
||||
getSelectedArea
|
||||
} = useDistortionEditor(initialAreas);
|
||||
const [showEditor, setShowEditor] = (0, import_react5.useState)(true);
|
||||
(0, import_react5.useEffect)(() => {
|
||||
onAreasChange?.(state.areas);
|
||||
}, [state.areas, onAreasChange]);
|
||||
@ -1182,7 +1191,17 @@ var DistortionEditor = ({
|
||||
}
|
||||
};
|
||||
const selectedArea = getSelectedArea();
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "distortion-editor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "editor-main", children: [
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "distortion-editor", children: [
|
||||
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
||||
"button",
|
||||
{
|
||||
className: `editor-toggle-btn ${showEditor ? "active" : ""}`,
|
||||
onClick: () => setShowEditor(!showEditor),
|
||||
title: showEditor ? "\uC5D0\uB514\uD130 \uC228\uAE30\uAE30 (\uC65C\uACE1 \uD6A8\uACFC\uB9CC \uBCF4\uAE30)" : "\uC5D0\uB514\uD130 \uD45C\uC2DC",
|
||||
children: showEditor ? "\u{1F441}\uFE0F \uC5D0\uB514\uD130 \uC228\uAE30\uAE30" : "\u270F\uFE0F \uC5D0\uB514\uD130 \uD45C\uC2DC"
|
||||
}
|
||||
) }),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "editor-main", children: [
|
||||
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "editor-canvas-container", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
||||
EditorCanvas,
|
||||
{
|
||||
@ -1196,7 +1215,8 @@ var DistortionEditor = ({
|
||||
draggingPointIndex: state.draggingPointIndex,
|
||||
onStartDragging: startDragging,
|
||||
onStopDragging: stopDragging,
|
||||
style: canvasStyle
|
||||
style: canvasStyle,
|
||||
showEditor
|
||||
}
|
||||
) }),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "editor-sidebar", children: [
|
||||
@ -1212,7 +1232,8 @@ var DistortionEditor = ({
|
||||
),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ParameterPanel, { area: selectedArea, onUpdateArea: handleUpdateArea })
|
||||
] })
|
||||
] }) });
|
||||
] })
|
||||
] });
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
|
||||
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
51
dist/index.mjs
vendored
51
dist/index.mjs
vendored
@ -459,7 +459,7 @@ var ImageDistortion = ({
|
||||
};
|
||||
|
||||
// src/editor/DistortionEditor.tsx
|
||||
import { useEffect as useEffect4 } from "react";
|
||||
import { useEffect as useEffect4, useState as useState4 } from "react";
|
||||
|
||||
// src/editor/hooks/useDistortionEditor.ts
|
||||
import { useState as useState2, useCallback as useCallback2 } from "react";
|
||||
@ -609,7 +609,8 @@ var EditorCanvas = ({
|
||||
draggingPointIndex,
|
||||
onStartDragging,
|
||||
onStopDragging,
|
||||
style: customStyle
|
||||
style: customStyle,
|
||||
showEditor = true
|
||||
}) => {
|
||||
const containerRef = useRef3(null);
|
||||
const [canvasSize, setCanvasSize] = useState3({ width: 0, height: 0 });
|
||||
@ -658,7 +659,7 @@ var EditorCanvas = ({
|
||||
);
|
||||
const handleCanvasMouseDown = useCallback3(
|
||||
(e) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
const y = (e.clientY - rect.top) / rect.height;
|
||||
@ -669,11 +670,11 @@ var EditorCanvas = ({
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
[selectedArea, isPointInPolygon]
|
||||
[showEditor, selectedArea, isPointInPolygon]
|
||||
);
|
||||
const handleMouseMove = useCallback3(
|
||||
(e) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
const y = (e.clientY - rect.top) / rect.height;
|
||||
@ -692,7 +693,7 @@ var EditorCanvas = ({
|
||||
setDragStartPos({ x, y });
|
||||
}
|
||||
},
|
||||
[draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
[showEditor, draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
);
|
||||
const handleMouseUp = useCallback3(() => {
|
||||
if (draggingPointIndex !== null) {
|
||||
@ -783,12 +784,19 @@ var EditorCanvas = ({
|
||||
{
|
||||
ref: containerRef,
|
||||
className: "editor-canvas",
|
||||
style: { width, height, position: "relative", cursor: getCursorStyle() },
|
||||
onMouseDown: handleCanvasMouseDown,
|
||||
onMouseMove: handleMouseMove,
|
||||
style: {
|
||||
width,
|
||||
height,
|
||||
position: "relative",
|
||||
cursor: showEditor ? getCursorStyle() : "default",
|
||||
pointerEvents: showEditor ? "auto" : "none"
|
||||
// 에디터 숨김 시 포인터 이벤트 비활성화
|
||||
},
|
||||
onMouseDown: showEditor ? handleCanvasMouseDown : void 0,
|
||||
onMouseMove: showEditor ? handleMouseMove : void 0,
|
||||
children: [
|
||||
/* @__PURE__ */ jsx2(ImageDistortion, { imageSrc, areas }),
|
||||
/* @__PURE__ */ jsx2(
|
||||
showEditor && /* @__PURE__ */ jsx2(
|
||||
"svg",
|
||||
{
|
||||
style: {
|
||||
@ -817,7 +825,7 @@ var EditorCanvas = ({
|
||||
})
|
||||
}
|
||||
),
|
||||
selectedArea && canvasSize.width > 0 && /* @__PURE__ */ jsx2(
|
||||
showEditor && selectedArea && canvasSize.width > 0 && /* @__PURE__ */ jsx2(
|
||||
"canvas",
|
||||
{
|
||||
style: {
|
||||
@ -841,7 +849,7 @@ var EditorCanvas = ({
|
||||
}
|
||||
}
|
||||
),
|
||||
selectedArea && selectedArea.basePoints.map((point, index) => {
|
||||
showEditor && selectedArea && selectedArea.basePoints.map((point, index) => {
|
||||
const handleStyle = editorStyle.pointHandle || {};
|
||||
return /* @__PURE__ */ jsx2(
|
||||
"div",
|
||||
@ -1103,6 +1111,7 @@ var DistortionEditor = ({
|
||||
stopDragging,
|
||||
getSelectedArea
|
||||
} = useDistortionEditor(initialAreas);
|
||||
const [showEditor, setShowEditor] = useState4(true);
|
||||
useEffect4(() => {
|
||||
onAreasChange?.(state.areas);
|
||||
}, [state.areas, onAreasChange]);
|
||||
@ -1136,7 +1145,17 @@ var DistortionEditor = ({
|
||||
}
|
||||
};
|
||||
const selectedArea = getSelectedArea();
|
||||
return /* @__PURE__ */ jsx5("div", { className: "distortion-editor", children: /* @__PURE__ */ jsxs4("div", { className: "editor-main", children: [
|
||||
return /* @__PURE__ */ jsxs4("div", { className: "distortion-editor", children: [
|
||||
/* @__PURE__ */ jsx5("div", { className: "editor-toolbar", children: /* @__PURE__ */ jsx5(
|
||||
"button",
|
||||
{
|
||||
className: `editor-toggle-btn ${showEditor ? "active" : ""}`,
|
||||
onClick: () => setShowEditor(!showEditor),
|
||||
title: showEditor ? "\uC5D0\uB514\uD130 \uC228\uAE30\uAE30 (\uC65C\uACE1 \uD6A8\uACFC\uB9CC \uBCF4\uAE30)" : "\uC5D0\uB514\uD130 \uD45C\uC2DC",
|
||||
children: showEditor ? "\u{1F441}\uFE0F \uC5D0\uB514\uD130 \uC228\uAE30\uAE30" : "\u270F\uFE0F \uC5D0\uB514\uD130 \uD45C\uC2DC"
|
||||
}
|
||||
) }),
|
||||
/* @__PURE__ */ jsxs4("div", { className: "editor-main", children: [
|
||||
/* @__PURE__ */ jsx5("div", { className: "editor-canvas-container", children: /* @__PURE__ */ jsx5(
|
||||
EditorCanvas,
|
||||
{
|
||||
@ -1150,7 +1169,8 @@ var DistortionEditor = ({
|
||||
draggingPointIndex: state.draggingPointIndex,
|
||||
onStartDragging: startDragging,
|
||||
onStopDragging: stopDragging,
|
||||
style: canvasStyle
|
||||
style: canvasStyle,
|
||||
showEditor
|
||||
}
|
||||
) }),
|
||||
/* @__PURE__ */ jsxs4("div", { className: "editor-sidebar", children: [
|
||||
@ -1166,7 +1186,8 @@ var DistortionEditor = ({
|
||||
),
|
||||
/* @__PURE__ */ jsx5(ParameterPanel, { area: selectedArea, onUpdateArea: handleUpdateArea })
|
||||
] })
|
||||
] }) });
|
||||
] })
|
||||
] });
|
||||
};
|
||||
export {
|
||||
ANIMATION_CONFIG,
|
||||
|
||||
2
dist/index.mjs.map
vendored
2
dist/index.mjs.map
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { DistortionArea } from '../types/area';
|
||||
import { DistortionEditorProps } from './types';
|
||||
import { useDistortionEditor } from './hooks/useDistortionEditor';
|
||||
@ -28,6 +28,9 @@ export const DistortionEditor: React.FC<DistortionEditorProps> = ({
|
||||
getSelectedArea,
|
||||
} = useDistortionEditor(initialAreas);
|
||||
|
||||
// 에디터 모드 토글 상태
|
||||
const [showEditor, setShowEditor] = useState(true);
|
||||
|
||||
// 영역 변경 시 콜백 호출
|
||||
useEffect(() => {
|
||||
onAreasChange?.(state.areas);
|
||||
@ -72,6 +75,17 @@ export const DistortionEditor: React.FC<DistortionEditorProps> = ({
|
||||
|
||||
return (
|
||||
<div className="distortion-editor">
|
||||
{/* 에디터 모드 토글 버튼 */}
|
||||
<div className="editor-toolbar">
|
||||
<button
|
||||
className={`editor-toggle-btn ${showEditor ? 'active' : ''}`}
|
||||
onClick={() => setShowEditor(!showEditor)}
|
||||
title={showEditor ? '에디터 숨기기 (왜곡 효과만 보기)' : '에디터 표시'}
|
||||
>
|
||||
{showEditor ? '👁️ 에디터 숨기기' : '✏️ 에디터 표시'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="editor-main">
|
||||
{/* 왼쪽: 캔버스 */}
|
||||
<div className="editor-canvas-container">
|
||||
@ -87,6 +101,7 @@ export const DistortionEditor: React.FC<DistortionEditorProps> = ({
|
||||
onStartDragging={startDragging}
|
||||
onStopDragging={stopDragging}
|
||||
style={canvasStyle}
|
||||
showEditor={showEditor}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ interface EditorCanvasProps {
|
||||
onStopDragging: () => void;
|
||||
/** 에디터 캔버스 스타일 커스터마이징 */
|
||||
style?: EditorCanvasStyle;
|
||||
/** 에디터 UI 표시 여부 (기본값: true) */
|
||||
showEditor?: boolean;
|
||||
}
|
||||
|
||||
export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
@ -31,6 +33,7 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
onStartDragging,
|
||||
onStopDragging,
|
||||
style: customStyle,
|
||||
showEditor = true,
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [canvasSize, setCanvasSize] = useState({width: 0, height: 0});
|
||||
@ -93,7 +96,8 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
// 캔버스 클릭 (사각형 내부 클릭 감지)
|
||||
const handleCanvasMouseDown = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
// 에디터가 숨겨진 상태면 동작하지 않음
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
@ -107,12 +111,13 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
[selectedArea, isPointInPolygon]
|
||||
[showEditor, selectedArea, isPointInPolygon]
|
||||
);
|
||||
|
||||
const handleMouseMove = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
if (!selectedArea || !containerRef.current) return;
|
||||
// 에디터가 숨겨진 상태면 동작하지 않음
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
@ -139,7 +144,7 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
setDragStartPos({ x, y }); // 다음 프레임을 위해 시작 위치 업데이트
|
||||
}
|
||||
},
|
||||
[draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
[showEditor, draggingPointIndex, isDraggingArea, dragStartPos, selectedArea, onUpdatePoint, onUpdateArea]
|
||||
);
|
||||
|
||||
const handleMouseUp = useCallback(() => {
|
||||
@ -270,14 +275,21 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="editor-canvas"
|
||||
style={{width, height, position: 'relative', cursor: getCursorStyle()}}
|
||||
onMouseDown={handleCanvasMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
style={{
|
||||
width,
|
||||
height,
|
||||
position: 'relative',
|
||||
cursor: showEditor ? getCursorStyle() : 'default',
|
||||
pointerEvents: showEditor ? 'auto' : 'none', // 에디터 숨김 시 포인터 이벤트 비활성화
|
||||
}}
|
||||
onMouseDown={showEditor ? handleCanvasMouseDown : undefined}
|
||||
onMouseMove={showEditor ? handleMouseMove : undefined}
|
||||
>
|
||||
{/* ImageDistortion 컴포넌트 */}
|
||||
<ImageDistortion imageSrc={imageSrc} areas={areas}/>
|
||||
|
||||
{/* 오버레이 SVG */}
|
||||
{/* 오버레이 SVG - 에디터 모드일 때만 표시 */}
|
||||
{showEditor && (
|
||||
<svg
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@ -310,9 +322,10 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
);
|
||||
})}
|
||||
</svg>
|
||||
)}
|
||||
|
||||
{/* 선택된 영역의 타원 가이드 (Canvas로 그리기) */}
|
||||
{selectedArea && canvasSize.width > 0 && (
|
||||
{/* 선택된 영역의 타원 가이드 (Canvas로 그리기) - 에디터 모드일 때만 표시 */}
|
||||
{showEditor && selectedArea && canvasSize.width > 0 && (
|
||||
<canvas
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@ -336,8 +349,8 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 선택된 영역의 포인트 핸들 */}
|
||||
{selectedArea &&
|
||||
{/* 선택된 영역의 포인트 핸들 - 에디터 모드일 때만 표시 */}
|
||||
{showEditor && selectedArea &&
|
||||
selectedArea.basePoints.map((point, index) => {
|
||||
const handleStyle = editorStyle.pointHandle || {};
|
||||
return (
|
||||
|
||||
59
src/editor/constants.ts
Normal file
59
src/editor/constants.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { EditorCanvasStyle } from './types';
|
||||
|
||||
/**
|
||||
* 기본 에디터 캔버스 스타일
|
||||
*/
|
||||
export const DEFAULT_EDITOR_CANVAS_STYLE: EditorCanvasStyle = {
|
||||
// 3단계 원 스타일 (외부 -> 내부)
|
||||
circleLevels: [
|
||||
{
|
||||
radius: 0.5,
|
||||
opacity: 0.3,
|
||||
lineWidth: 2,
|
||||
color: 'rgba(255, 200, 0, 1)',
|
||||
dashPattern: [8, 4],
|
||||
},
|
||||
{
|
||||
radius: 0.33,
|
||||
opacity: 0.6,
|
||||
lineWidth: 2.5,
|
||||
color: 'rgba(255, 200, 0, 1)',
|
||||
dashPattern: [8, 4],
|
||||
},
|
||||
{
|
||||
radius: 0.167,
|
||||
opacity: 0.9,
|
||||
lineWidth: 3,
|
||||
color: 'rgba(255, 200, 0, 1)',
|
||||
dashPattern: [8, 4],
|
||||
},
|
||||
],
|
||||
// 원 내부 채우기
|
||||
circleFillColor: 'rgba(255, 200, 0, 0.08)',
|
||||
// 중심점
|
||||
centerPoint: {
|
||||
radius: 5,
|
||||
fillColor: 'rgba(255, 200, 0, 1)',
|
||||
strokeColor: 'rgba(255, 255, 255, 0.8)',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
// 포인트 핸들
|
||||
pointHandle: {
|
||||
size: 16,
|
||||
fillColor: '#00aaff',
|
||||
strokeColor: 'white',
|
||||
strokeWidth: 2,
|
||||
labelColor: '#00aaff',
|
||||
labelFontSize: 11,
|
||||
},
|
||||
// 영역 외곽선
|
||||
areaOutline: {
|
||||
selectedColor: '#00aaff',
|
||||
unselectedColor: '#888',
|
||||
selectedWidth: 2,
|
||||
unselectedWidth: 1,
|
||||
unselectedDashPattern: [5, 5],
|
||||
selectedFillColor: 'rgba(0, 170, 255, 0.08)', // 선택된 영역 배경 (연한 파란색)
|
||||
unselectedFillColor: 'rgba(136, 136, 136, 0.03)', // 선택 안된 영역 배경 (연한 회색)
|
||||
},
|
||||
};
|
||||
@ -7,6 +7,41 @@
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* 에디터 툴바 */
|
||||
.editor-toolbar {
|
||||
max-width: 1600px;
|
||||
margin: 0 auto 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.editor-toggle-btn {
|
||||
padding: 10px 20px;
|
||||
background: #383838;
|
||||
color: #e0e0e0;
|
||||
border: 2px solid #555;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.editor-toggle-btn:hover {
|
||||
background: #404040;
|
||||
border-color: #00aaff;
|
||||
}
|
||||
|
||||
.editor-toggle-btn.active {
|
||||
background: #2d5a7a;
|
||||
border-color: #00aaff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.editor-main {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user