@deepnoid/canvas 0.1.30 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useRef, useState } from 'react';
4
4
  import Canvas from './Canvas';
5
5
  import { usePanZoom } from '../hooks/usePanZoom';
@@ -8,117 +8,74 @@ import { drawCanvas, resolutionCanvas } from '../utils/graphic';
8
8
  const AnnotatedCanvas = ({ image, coordinates, panZoomable = false, ZoomButton, resetOnImageChange = true, editable = false, timeout = 10000, onImageLoadSuccess, onImageLoadError, }) => {
9
9
  const canvasRef = useRef(null);
10
10
  const imageRef = useRef(new Image());
11
- const [isLoading, setIsLoading] = useState(false);
12
- const [isError, setIsError] = useState(false);
13
11
  const { width, height } = useResizeObserver({ ref: canvasRef });
14
- const { moveX, moveY, zoom, initZoom, zoomX, zoomY, dx, dy, dw, dh, imageOnloadCount, setImageOnloadCount, init, initCanvas, clearCanvas, handleWheel, handleMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, } = usePanZoom({
15
- canvasRef,
16
- imageRef,
17
- panZoomable,
18
- });
19
- useEffect(() => {
20
- const redraw = () => {
21
- if (canvasRef.current) {
22
- drawCanvas(moveX, moveY, zoomX, zoomY, zoom, dx, dy, resolutionCanvas(canvasRef.current), imageRef.current, true);
23
- }
24
- };
25
- redraw();
26
- }, [moveX, moveY, zoomX, zoomY, zoom, dx, dy, dw, dh, imageOnloadCount]);
27
- // --------
28
- // useEffect(() => {
29
- // if (!imageRef?.current || !canvasRef?.current || !width || !height) return;
30
- // const canvasEl = resolutionCanvas(canvasRef.current);
31
- // if (!canvasEl) return;
32
- // const isFirstLoad = imageOnloadCount === 0;
33
- // if (isFirstLoad) {
34
- // init(canvasEl, imageRef.current);
35
- // setImageOnloadCount((prev) => prev + 1);
36
- // return;
37
- // }
38
- // if (resetOnImageChange) {
39
- // init(canvasEl, imageRef.current);
40
- // } else {
41
- // drawCanvas(moveX, moveY, zoomX, zoomY, zoom, dx, dy, canvasEl, imageRef.current, true);
42
- // }
43
- // setImageOnloadCount((prev) => prev + 1);
44
- // }, [imageRef?.current, width, height, resetOnImageChange]);
45
- // ----------
12
+ const [displayCoordinates, setDisplayCoordinates] = useState();
13
+ const { canvasState, init, initCanvas, clearCanvas, preserveZoomAndPosition, handleWheel, handleMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, imageOnloadCount, setImageOnloadCount, } = usePanZoom({ canvasRef, imageRef, panZoomable });
46
14
  useEffect(() => {
47
15
  if (!image || image.trim() === '') {
48
- setIsLoading(false);
49
- setIsError(false);
50
16
  clearCanvas();
17
+ setDisplayCoordinates([]);
51
18
  return;
52
19
  }
53
- setIsLoading(true);
54
- imageRef.current.src = image;
55
- imageRef.current.onload = () => {
56
- console.log('> ======================= useEffect onload ============================');
57
- setIsLoading(false);
58
- setIsError(false);
20
+ const tempImage = new Image();
21
+ let cancelled = false;
22
+ tempImage.src = image;
23
+ tempImage.onload = () => {
24
+ if (cancelled)
25
+ return;
59
26
  onImageLoadSuccess?.();
60
- // const canvas = resolutionCanvas(canvasRef.current);
61
- // if (canvas) init(canvas, imageRef.current);
62
- // setImageOnloadCount((prev) => prev + 1);
63
- console.log('> canvasRef.current : ', canvasRef.current);
64
27
  const canvas = resolutionCanvas(canvasRef.current);
65
- console.log(' > canvas :', canvas);
66
28
  if (!canvas)
67
29
  return;
68
- if (resetOnImageChange)
30
+ imageRef.current = tempImage;
31
+ if (resetOnImageChange) {
69
32
  init(canvas, imageRef.current);
33
+ }
34
+ else {
35
+ preserveZoomAndPosition(canvas, imageRef.current, canvasState.zoom / canvasState.initZoom);
36
+ }
70
37
  setImageOnloadCount((prev) => prev + 1);
71
- // if (prevImageRef.current !== image) {
72
- // // prevImageRef.current = image;
73
- // prevImageRef.current = imageRef.current.src;
74
- // const canvas = resolutionCanvas(canvasRef.current);
75
- // const isFirstLoad = imageOnloadCount === 0;
76
- // console.log('> onload - isFirstLoad : ', isFirstLoad);
77
- // // if (canvas && isFirstLoad) {
78
- // // init(canvas, imageRef.current);
79
- // // setImageOnloadCount((prev) => prev + 1);
80
- // // }
81
- // if (!canvas) return;
82
- // if (isFirstLoad) {
83
- // init(canvas, imageRef.current);
84
- // setImageOnloadCount((prev) => prev + 1);
85
- // return;
86
- // }
87
- // console.log('> !!!!!!!!!!!!!!!! resetOnImageChange : ', resetOnImageChange);
88
- // if (resetOnImageChange) {
89
- // init(canvas, imageRef.current);
90
- // } else {
91
- // // drawCanvas(moveX, moveY, zoomX, zoomY, zoom, dx, dy, canvas, imageRef.current, true);
92
- // }
93
- // setImageOnloadCount((prev) => prev + 1);
94
- // // if (canvas) init(canvas, imageRef.current);
95
- // }
96
- // setImageOnloadCount((prev) => prev + 1);
38
+ setDisplayCoordinates(coordinates);
97
39
  };
98
- imageRef.current.onerror = () => {
99
- setIsLoading(false);
100
- setIsError(true);
40
+ tempImage.onerror = () => {
41
+ if (cancelled)
42
+ return;
101
43
  const err = new Error(`Failed to load image: ${image}`);
102
44
  onImageLoadError?.(err);
103
45
  clearCanvas();
46
+ setDisplayCoordinates([]);
104
47
  };
105
- }, [image, canvasRef.current]);
48
+ return () => {
49
+ cancelled = true;
50
+ };
51
+ }, [image, resetOnImageChange]);
106
52
  useEffect(() => {
107
- console.log('> ======================= useEffect width, height !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
108
- if (image || !isError) {
109
- imageRef.current.src = image;
110
- if (!resetOnImageChange) {
111
- const canvas = resolutionCanvas(canvasRef.current);
112
- if (canvas)
113
- init(canvas, imageRef.current);
114
- setImageOnloadCount((prev) => prev + 1);
115
- }
53
+ if (image && width && height) {
54
+ const canvas = resolutionCanvas(canvasRef.current);
55
+ if (canvas)
56
+ init(canvas, imageRef.current);
116
57
  }
117
58
  }, [width, height]);
118
- return (_jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flex: 1 }, children: _jsx("div", { onWheel: handleWheel, onMouseMove: handleMouseMove, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseLeave: handleMouseLeave, style: {
59
+ useEffect(() => {
60
+ if (!canvasRef.current)
61
+ return;
62
+ const redraw = (canvas) => {
63
+ drawCanvas(canvasState.moveX, canvasState.moveY, canvasState.zoomX, canvasState.zoomY, canvasState.zoom, canvasState.dx, canvasState.dy, canvas, imageRef.current, true);
64
+ };
65
+ const canvas = resolutionCanvas(canvasRef.current);
66
+ if (canvas)
67
+ redraw(canvas);
68
+ }, [canvasState, imageOnloadCount]);
69
+ return (_jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flex: 1 }, children: _jsxs("div", { onWheel: handleWheel, onMouseMove: handleMouseMove, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseLeave: handleMouseLeave, style: {
119
70
  flex: 1,
120
71
  position: 'relative',
121
72
  cursor: panZoomable ? 'grab' : 'default',
122
- }, children: imageRef.current.src && !isLoading && !isError && (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, style: { position: 'absolute', width: '100%', height: '100%', left: 0, top: 0 } }), _jsx(Canvas, { moveX: moveX, moveY: moveY, zoomX: zoomX, zoomY: zoomY, zoom: zoom, dx: dx, dy: dy, dw: dw, dh: dh, coordinates: coordinates, editable: editable }), ZoomButton && _jsx(ZoomButton, { onClick: initCanvas, children: `${Math.round((zoom / initZoom) * 100)}%` })] })) }) }));
73
+ }, children: [_jsx("canvas", { ref: canvasRef, style: {
74
+ position: 'absolute',
75
+ width: '100%',
76
+ height: '100%',
77
+ left: 0,
78
+ top: 0,
79
+ } }), _jsx(Canvas, { ...canvasState, coordinates: displayCoordinates, editable: editable }), ZoomButton && canvasState.initZoom > 0 && (_jsx(ZoomButton, { onClick: initCanvas, children: `${Math.round((canvasState.zoom / canvasState.initZoom) * 100)}%` }))] }) }));
123
80
  };
124
81
  export default AnnotatedCanvas;
@@ -1,25 +1,29 @@
1
1
  import { RefObject, WheelEvent, MouseEvent } from 'react';
2
+ type CanvasState = {
3
+ dx: number;
4
+ dy: number;
5
+ dw: number;
6
+ dh: number;
7
+ moveX: number;
8
+ moveY: number;
9
+ zoomX: number;
10
+ zoomY: number;
11
+ zoom: number;
12
+ initZoom: number;
13
+ };
2
14
  type UsePanZoomProps = {
3
15
  canvasRef: RefObject<HTMLCanvasElement | null>;
4
16
  imageRef: RefObject<HTMLImageElement>;
5
17
  panZoomable?: boolean;
6
18
  };
7
19
  export declare function usePanZoom({ canvasRef, imageRef, panZoomable }: UsePanZoomProps): {
8
- moveX: number;
9
- moveY: number;
10
- zoom: number;
11
- initZoom: number;
12
- zoomX: number;
13
- zoomY: number;
14
- dx: number;
15
- dy: number;
16
- dw: number;
17
- dh: number;
20
+ canvasState: CanvasState;
18
21
  imageOnloadCount: number;
19
22
  setImageOnloadCount: import("react").Dispatch<import("react").SetStateAction<number>>;
20
23
  init: (canvas: HTMLCanvasElement, image: HTMLImageElement) => void;
21
24
  initCanvas: () => void;
22
25
  clearCanvas: () => void;
26
+ preserveZoomAndPosition: (canvas: HTMLCanvasElement, image: HTMLImageElement, zoomRatio: number) => void;
23
27
  handleWheel: (event: WheelEvent) => void;
24
28
  handleMouseDown: (event: MouseEvent) => void;
25
29
  handleMouseMove: (event: MouseEvent) => void;
@@ -1,89 +1,94 @@
1
1
  'use client';
2
- import { useCallback, useState } from 'react';
3
- import { resolutionCanvas, getMousePointTransform, canvasCenterPoint } from '../utils/graphic';
2
+ import { useState } from 'react';
3
+ import { resolutionCanvas, getMousePointTransform, canvasCenterPoint, calculatorZoomPoint, calculateInitZoom, } from '../utils/graphic';
4
4
  import { MouseStatus } from '../enum/common';
5
5
  export function usePanZoom({ canvasRef, imageRef, panZoomable = false }) {
6
6
  const ZOOM_UNIT = 0.9;
7
7
  const MAX_ZOOM = 4;
8
8
  const MIN_ZOOM = 0.5;
9
- const [initZoom, setInitZoom] = useState(0);
10
- const [zoom, setZoom] = useState(0);
11
- const [zoomX, setZoomX] = useState(0);
12
- const [zoomY, setZoomY] = useState(0);
13
- const [dx, setDx] = useState(0);
14
- const [dy, setDy] = useState(0);
15
- const [dw, setDw] = useState(0);
16
- const [dh, setDh] = useState(0);
17
- const [moveX, setMoveX] = useState(0);
18
- const [moveY, setMoveY] = useState(0);
9
+ const [canvasState, setCanvasState] = useState({
10
+ dx: 0,
11
+ dy: 0,
12
+ dw: 0,
13
+ dh: 0,
14
+ moveX: 0,
15
+ moveY: 0,
16
+ zoomX: 0,
17
+ zoomY: 0,
18
+ zoom: 0,
19
+ initZoom: 0,
20
+ });
19
21
  const [status, setStatus] = useState('');
20
22
  const [imageOnloadCount, setImageOnloadCount] = useState(0);
21
23
  const [startMousePoint, setStartMousePoint] = useState();
22
- const calculatorZoomPoint = useCallback((canvas, movementX, movementY, dx, dy) => {
23
- let x = 0;
24
- let y = 0;
25
- if (canvas) {
26
- x = -dx - movementX + canvas.width / 2;
27
- y = -dy - movementY + canvas.height / 2;
28
- }
29
- return { x, y };
30
- }, []);
31
- const calculateInitZoom = useCallback((canvas, image) => {
32
- if (!canvas || !image)
33
- return 1;
34
- const canvasRatio = canvas.clientWidth / canvas.clientHeight;
35
- const imageRatio = image.naturalWidth / image.naturalHeight;
36
- return canvasRatio < imageRatio
37
- ? canvas.clientWidth / image.naturalWidth
38
- : canvas.clientHeight / image.naturalHeight;
39
- }, []);
40
24
  const init = (canvas, image) => {
41
- if (!canvas || !image)
42
- return;
43
25
  const point = canvasCenterPoint(canvas, image);
44
- setDx(point.x);
45
- setDy(point.y);
46
- setDw(image.width);
47
- setDh(image.height);
48
- setMoveX(0);
49
- setMoveY(0);
50
- const init_zoom = calculateInitZoom(canvas, image);
51
- setZoom(init_zoom);
52
- setInitZoom(init_zoom);
53
26
  const zoomPoint = calculatorZoomPoint(canvas, 0, 0, point.x, point.y);
54
- setZoomX(zoomPoint.x);
55
- setZoomY(zoomPoint.y);
27
+ const initZoomValue = calculateInitZoom(canvas, image);
28
+ setCanvasState({
29
+ dx: point.x,
30
+ dy: point.y,
31
+ dw: image.width,
32
+ dh: image.height,
33
+ moveX: 0,
34
+ moveY: 0,
35
+ zoomX: zoomPoint.x,
36
+ zoomY: zoomPoint.y,
37
+ zoom: initZoomValue,
38
+ initZoom: initZoomValue,
39
+ });
40
+ };
41
+ const preserveZoomAndPosition = (canvas, image, zoomRatio) => {
42
+ const prevZoomRatio = zoomRatio || 1;
43
+ const point = canvasCenterPoint(canvas, image);
44
+ const newInitZoom = calculateInitZoom(canvas, image);
45
+ const zoomPoint = calculatorZoomPoint(canvas, canvasState.moveX, canvasState.moveY, point.x, point.y);
46
+ setCanvasState({
47
+ dx: point.x,
48
+ dy: point.y,
49
+ dw: image.width,
50
+ dh: image.height,
51
+ moveX: canvasState.moveX,
52
+ moveY: canvasState.moveY,
53
+ zoomX: zoomPoint.x,
54
+ zoomY: zoomPoint.y,
55
+ zoom: newInitZoom * prevZoomRatio,
56
+ initZoom: newInitZoom,
57
+ });
56
58
  };
57
59
  const initCanvas = () => {
58
- if (!canvasRef.current || !imageRef.current)
60
+ if (!canvasRef.current)
59
61
  return;
60
62
  const canvas = resolutionCanvas(canvasRef.current);
61
- if (canvas) {
62
- init(canvas, imageRef.current);
63
- setImageOnloadCount((prev) => prev + 1);
64
- }
63
+ if (!canvas)
64
+ return;
65
+ init(canvas, imageRef.current);
66
+ setImageOnloadCount((prev) => prev + 1);
65
67
  };
66
68
  const clearCanvas = () => {
67
69
  if (!canvasRef.current)
68
70
  return;
69
71
  const canvas = resolutionCanvas(canvasRef.current);
70
- if (canvas) {
71
- const ctx = canvas.getContext('2d');
72
- ctx?.clearRect(0, 0, canvas.width, canvas.height);
73
- }
72
+ if (!canvas)
73
+ return;
74
+ const ctx = canvas.getContext('2d');
75
+ ctx?.clearRect(0, 0, canvas.width, canvas.height);
74
76
  };
75
77
  const handleWheel = (event) => {
76
- if (!panZoomable || !canvasRef.current)
78
+ if (!panZoomable || !canvasRef.current || canvasState.initZoom <= 0)
77
79
  return;
78
- let calc_zoom = event.deltaY < 0 ? (zoom || 1) * (1 / ZOOM_UNIT) : (zoom || 1) * ZOOM_UNIT;
79
- if (initZoom * MAX_ZOOM < zoom * ZOOM_UNIT)
80
- calc_zoom = calc_zoom * ZOOM_UNIT;
81
- if (initZoom * MIN_ZOOM > zoom * ZOOM_UNIT)
82
- calc_zoom = calc_zoom * (1 / ZOOM_UNIT);
83
- const zoomPoint = calculatorZoomPoint(canvasRef.current, moveX, moveY, dx, dy);
84
- setZoomX(zoomPoint.x);
85
- setZoomY(zoomPoint.y);
86
- setZoom(calc_zoom);
80
+ let calcZoom = event.deltaY < 0 ? canvasState.zoom * (1 / ZOOM_UNIT) : canvasState.zoom * ZOOM_UNIT;
81
+ if (canvasState.initZoom * MAX_ZOOM < canvasState.zoom * ZOOM_UNIT)
82
+ calcZoom = calcZoom * ZOOM_UNIT;
83
+ if (canvasState.initZoom * MIN_ZOOM > canvasState.zoom * ZOOM_UNIT)
84
+ calcZoom = calcZoom * (1 / ZOOM_UNIT);
85
+ const zoomPoint = calculatorZoomPoint(canvasRef.current, canvasState.moveX, canvasState.moveY, canvasState.dx, canvasState.dy);
86
+ setCanvasState({
87
+ ...canvasState,
88
+ zoomX: zoomPoint.x,
89
+ zoomY: zoomPoint.y,
90
+ zoom: calcZoom,
91
+ });
87
92
  };
88
93
  const handleMouseMove = (event) => {
89
94
  if (!panZoomable || !canvasRef.current || status !== MouseStatus.MOVE)
@@ -92,18 +97,21 @@ export function usePanZoom({ canvasRef, imageRef, panZoomable = false }) {
92
97
  const rect = canvas.getBoundingClientRect();
93
98
  const mouseX = event.clientX - rect.left;
94
99
  const mouseY = event.clientY - rect.top;
95
- const mouse = getMousePointTransform({ x: mouseX, y: mouseY }, { x: moveX, y: moveY }, { x: zoomX, y: zoomY }, { x: dx, y: dy }, zoom || 1, canvas);
100
+ const mouse = getMousePointTransform({ x: mouseX, y: mouseY }, { x: canvasState.moveX, y: canvasState.moveY }, { x: canvasState.zoomX, y: canvasState.zoomY }, { x: canvasState.dx, y: canvasState.dy }, canvasState.zoom || 1, canvas);
96
101
  let x = mouse.x;
97
102
  let y = mouse.y;
98
103
  if (startMousePoint) {
99
104
  x -= startMousePoint.x;
100
105
  y -= startMousePoint.y;
101
106
  }
102
- setMoveX(moveX + x);
103
- setMoveY(moveY + y);
104
- const zoomPoint = calculatorZoomPoint(canvas, moveX + x, moveY + y, dx, dy);
105
- setZoomX(zoomPoint.x);
106
- setZoomY(zoomPoint.y);
107
+ const zoomPoint = calculatorZoomPoint(canvas, canvasState.moveX + x, canvasState.moveY + y, canvasState.dx, canvasState.dy);
108
+ setCanvasState({
109
+ ...canvasState,
110
+ moveX: canvasState.moveX + x,
111
+ moveY: canvasState.moveY + y,
112
+ zoomX: zoomPoint.x,
113
+ zoomY: zoomPoint.y,
114
+ });
107
115
  event.preventDefault();
108
116
  };
109
117
  const handleMouseDown = (event) => {
@@ -114,7 +122,7 @@ export function usePanZoom({ canvasRef, imageRef, panZoomable = false }) {
114
122
  const rect = canvas.getBoundingClientRect();
115
123
  const mouseX = event.clientX - rect.left;
116
124
  const mouseY = event.clientY - rect.top;
117
- const mouse = getMousePointTransform({ x: mouseX, y: mouseY }, { x: moveX, y: moveY }, { x: zoomX, y: zoomY }, { x: dx, y: dy }, zoom || 1, canvas);
125
+ const mouse = getMousePointTransform({ x: mouseX, y: mouseY }, { x: canvasState.moveX, y: canvasState.moveY }, { x: canvasState.zoomX, y: canvasState.zoomY }, { x: canvasState.dx, y: canvasState.dy }, canvasState.zoom || 1, canvas);
118
126
  setStartMousePoint({ x: mouse.x, y: mouse.y });
119
127
  event.preventDefault();
120
128
  };
@@ -131,21 +139,13 @@ export function usePanZoom({ canvasRef, imageRef, panZoomable = false }) {
131
139
  event.preventDefault();
132
140
  };
133
141
  return {
134
- moveX,
135
- moveY,
136
- zoom,
137
- initZoom,
138
- zoomX,
139
- zoomY,
140
- dx,
141
- dy,
142
- dw,
143
- dh,
142
+ canvasState,
144
143
  imageOnloadCount,
145
144
  setImageOnloadCount,
146
145
  init,
147
146
  initCanvas,
148
147
  clearCanvas,
148
+ preserveZoomAndPosition,
149
149
  handleWheel,
150
150
  handleMouseDown,
151
151
  handleMouseMove,
@@ -14,14 +14,14 @@ const useResizeObserver = (opts = {}) => {
14
14
  didUnmount.current = true;
15
15
  };
16
16
  }, []);
17
- const refCallback = useResolvedElement(useCallback(element => {
17
+ const refCallback = useResolvedElement(useCallback((element) => {
18
18
  if (!resizeObserverRef.current ||
19
19
  resizeObserverRef.current.box !== opts.box ||
20
20
  resizeObserverRef.current.round !== round) {
21
21
  resizeObserverRef.current = {
22
22
  box: opts.box,
23
23
  round,
24
- instance: new ResizeObserver(entries => {
24
+ instance: new ResizeObserver((entries) => {
25
25
  const entry = entries[0];
26
26
  const boxProp = opts.box === 'border-box'
27
27
  ? 'borderBoxSize'
@@ -102,7 +102,7 @@ function useResolvedElement(subscriber, refOrElement) {
102
102
  }
103
103
  };
104
104
  }, []);
105
- return useCallback(element => {
105
+ return useCallback((element) => {
106
106
  cbElementRef.current = element;
107
107
  evaluateSubscription();
108
108
  }, [evaluateSubscription]);
@@ -3,6 +3,11 @@ export declare const canvasCenterPoint: (canvas: HTMLCanvasElement, image: HTMLI
3
3
  x: number;
4
4
  y: number;
5
5
  };
6
+ export declare const calculatorZoomPoint: (canvas: HTMLCanvasElement, movementX: number, movementY: number, dx: number, dy: number) => {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ export declare const calculateInitZoom: (canvas: HTMLCanvasElement, image: HTMLImageElement) => number;
6
11
  export declare const drawCanvas: (moveX: number, moveY: number, zoomX: number, zoomY: number, zoom: number, dx: number, dy: number, canvas_el?: HTMLCanvasElement, image?: HTMLImageElement, isClear?: boolean) => void;
7
12
  export declare const drawRect: (context: CanvasRenderingContext2D, coordinate: Coordinate) => void;
8
13
  export declare const setRectangleStyle: (context: CanvasRenderingContext2D, coordinate: Coordinate) => void;
@@ -5,6 +5,22 @@ export const canvasCenterPoint = (canvas, image) => {
5
5
  const centerY = canvas.height / 2 - image.height / 2;
6
6
  return { x: centerX, y: centerY };
7
7
  };
8
+ export const calculatorZoomPoint = (canvas, movementX, movementY, dx, dy) => {
9
+ let x = 0;
10
+ let y = 0;
11
+ if (canvas) {
12
+ x = -dx - movementX + canvas.width / 2;
13
+ y = -dy - movementY + canvas.height / 2;
14
+ }
15
+ return { x, y };
16
+ };
17
+ export const calculateInitZoom = (canvas, image) => {
18
+ if (!canvas || !image.naturalWidth)
19
+ return 1;
20
+ const canvasRatio = canvas.clientWidth / canvas.clientHeight;
21
+ const imageRatio = image.naturalWidth / image.naturalHeight;
22
+ return canvasRatio < imageRatio ? canvas.clientWidth / image.naturalWidth : canvas.clientHeight / image.naturalHeight;
23
+ };
8
24
  // [캔버스] 그리기
9
25
  export const drawCanvas = (moveX, moveY, zoomX, zoomY, zoom, dx, dy, canvas_el, image, isClear) => {
10
26
  if (canvas_el) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepnoid/canvas",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",