feat: Add area selection functionality
- EditorCanvas 컴포넌트에 영역 선택 콜백(onSelectArea) 추가 - 비선택 영역 클릭 시 해당 영역을 선택하는 기능 구현 - 드래그 시작 조건에서 showEditor만 확인하도록 수정 (selectedArea 불필요) - package.json 버전 1.2.0에서 1.2.1로 업데이트
This commit is contained in:
parent
317c7c5c92
commit
6b6c8d8fd0
2
dist/index.d.mts
vendored
2
dist/index.d.mts
vendored
@ -332,6 +332,8 @@ interface EditorCanvasProps {
|
||||
style?: EditorCanvasStyle;
|
||||
/** 에디터 UI 표시 여부 (기본값: true) */
|
||||
showEditor?: boolean;
|
||||
/** 영역 선택 콜백 (비선택 영역 클릭 시) */
|
||||
onSelectArea?: (areaId: string) => void;
|
||||
}
|
||||
declare const EditorCanvas: React$1.FC<EditorCanvasProps>;
|
||||
|
||||
|
||||
2
dist/index.d.ts
vendored
2
dist/index.d.ts
vendored
@ -332,6 +332,8 @@ interface EditorCanvasProps {
|
||||
style?: EditorCanvasStyle;
|
||||
/** 에디터 UI 표시 여부 (기본값: true) */
|
||||
showEditor?: boolean;
|
||||
/** 영역 선택 콜백 (비선택 영역 클릭 시) */
|
||||
onSelectArea?: (areaId: string) => void;
|
||||
}
|
||||
declare const EditorCanvas: React$1.FC<EditorCanvasProps>;
|
||||
|
||||
|
||||
20
dist/index.js
vendored
20
dist/index.js
vendored
@ -1316,7 +1316,8 @@ var EditorCanvas = ({
|
||||
onStartDragging,
|
||||
onStopDragging,
|
||||
style: customStyle,
|
||||
showEditor = true
|
||||
showEditor = true,
|
||||
onSelectArea
|
||||
}) => {
|
||||
const containerRef = (0, import_react6.useRef)(null);
|
||||
const [canvasSize, setCanvasSize] = (0, import_react6.useState)({ width: 0, height: 0 });
|
||||
@ -1365,7 +1366,7 @@ var EditorCanvas = ({
|
||||
);
|
||||
const handleCanvasDown = (0, import_react6.useCallback)(
|
||||
(e) => {
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
let clientX, clientY;
|
||||
if ("touches" in e) {
|
||||
@ -1379,13 +1380,24 @@ var EditorCanvas = ({
|
||||
const x = (clientX - rect.left) / rect.width;
|
||||
const y = (clientY - rect.top) / rect.height;
|
||||
const clickPoint = { x, y };
|
||||
if (isPointInPolygon2(clickPoint, selectedArea.basePoints)) {
|
||||
if (selectedArea && isPointInPolygon2(clickPoint, selectedArea.basePoints)) {
|
||||
setIsDraggingArea(true);
|
||||
setDragStartPos(clickPoint);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (onSelectArea) {
|
||||
for (let i = areas.length - 1; i >= 0; i--) {
|
||||
const area = areas[i];
|
||||
if (area.id !== selectedAreaId && isPointInPolygon2(clickPoint, area.basePoints)) {
|
||||
onSelectArea(area.id);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[showEditor, selectedArea, isPointInPolygon2]
|
||||
[showEditor, selectedArea, selectedAreaId, areas, isPointInPolygon2, onSelectArea]
|
||||
);
|
||||
const handleMove = (0, import_react6.useCallback)(
|
||||
(e) => {
|
||||
|
||||
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
20
dist/index.mjs
vendored
20
dist/index.mjs
vendored
@ -1256,7 +1256,8 @@ var EditorCanvas = ({
|
||||
onStartDragging,
|
||||
onStopDragging,
|
||||
style: customStyle,
|
||||
showEditor = true
|
||||
showEditor = true,
|
||||
onSelectArea
|
||||
}) => {
|
||||
const containerRef = useRef5(null);
|
||||
const [canvasSize, setCanvasSize] = useState4({ width: 0, height: 0 });
|
||||
@ -1305,7 +1306,7 @@ var EditorCanvas = ({
|
||||
);
|
||||
const handleCanvasDown = useCallback5(
|
||||
(e) => {
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
let clientX, clientY;
|
||||
if ("touches" in e) {
|
||||
@ -1319,13 +1320,24 @@ var EditorCanvas = ({
|
||||
const x = (clientX - rect.left) / rect.width;
|
||||
const y = (clientY - rect.top) / rect.height;
|
||||
const clickPoint = { x, y };
|
||||
if (isPointInPolygon2(clickPoint, selectedArea.basePoints)) {
|
||||
if (selectedArea && isPointInPolygon2(clickPoint, selectedArea.basePoints)) {
|
||||
setIsDraggingArea(true);
|
||||
setDragStartPos(clickPoint);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (onSelectArea) {
|
||||
for (let i = areas.length - 1; i >= 0; i--) {
|
||||
const area = areas[i];
|
||||
if (area.id !== selectedAreaId && isPointInPolygon2(clickPoint, area.basePoints)) {
|
||||
onSelectArea(area.id);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[showEditor, selectedArea, isPointInPolygon2]
|
||||
[showEditor, selectedArea, selectedAreaId, areas, isPointInPolygon2, onSelectArea]
|
||||
);
|
||||
const handleMove = useCallback5(
|
||||
(e) => {
|
||||
|
||||
2
dist/index.mjs.map
vendored
2
dist/index.mjs.map
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@baekryang/responsive-image-canvas",
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"publishConfig": {
|
||||
"registry": "https://git.bnovalab.com/api/packages/baekryang/npm/"
|
||||
},
|
||||
|
||||
@ -19,6 +19,8 @@ export interface EditorCanvasProps {
|
||||
style?: EditorCanvasStyle;
|
||||
/** 에디터 UI 표시 여부 (기본값: true) */
|
||||
showEditor?: boolean;
|
||||
/** 영역 선택 콜백 (비선택 영역 클릭 시) */
|
||||
onSelectArea?: (areaId: string) => void;
|
||||
}
|
||||
|
||||
export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
@ -34,6 +36,7 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
onStopDragging,
|
||||
style: customStyle,
|
||||
showEditor = true,
|
||||
onSelectArea,
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [canvasSize, setCanvasSize] = useState({width: 0, height: 0});
|
||||
@ -97,7 +100,7 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
const handleCanvasDown = useCallback(
|
||||
(e: React.MouseEvent | React.TouchEvent) => {
|
||||
// 에디터가 숨겨진 상태면 동작하지 않음
|
||||
if (!showEditor || !selectedArea || !containerRef.current) return;
|
||||
if (!showEditor || !containerRef.current) return;
|
||||
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
|
||||
@ -116,14 +119,28 @@ export const EditorCanvas: React.FC<EditorCanvasProps> = ({
|
||||
const y = (clientY - rect.top) / rect.height;
|
||||
const clickPoint = { x, y };
|
||||
|
||||
// 사각형 내부를 클릭했는지 확인
|
||||
if (isPointInPolygon(clickPoint, selectedArea.basePoints)) {
|
||||
// 선택된 영역 내부를 클릭했는지 확인 (드래그 시작)
|
||||
if (selectedArea && isPointInPolygon(clickPoint, selectedArea.basePoints)) {
|
||||
setIsDraggingArea(true);
|
||||
setDragStartPos(clickPoint);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// 비선택 영역 클릭 시 해당 영역 선택
|
||||
if (onSelectArea) {
|
||||
// 역순으로 검사 (위에 그려진 영역 우선)
|
||||
for (let i = areas.length - 1; i >= 0; i--) {
|
||||
const area = areas[i];
|
||||
if (area.id !== selectedAreaId && isPointInPolygon(clickPoint, area.basePoints)) {
|
||||
onSelectArea(area.id);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[showEditor, selectedArea, isPointInPolygon]
|
||||
[showEditor, selectedArea, selectedAreaId, areas, isPointInPolygon, onSelectArea]
|
||||
);
|
||||
|
||||
// 이동 (마우스/터치 공통)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user