canvas-react-easy 1.1.2 → 1.1.3

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,30 +1,37 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef } from "react";
3
3
  import CanvasState from "../store/CanvasState";
4
4
  import toolState from "../store/ToolState";
5
5
  import { Brush } from "../tools/Brush";
6
6
  import TextHoverTool from "../tools/TextHoverTool";
7
7
  const Canvas = ({ userName = "Гость" }) => {
8
- const canvasRef = useRef(null);
8
+ const mainRef = useRef(null);
9
+ const overlayRef = useRef(null);
9
10
  useEffect(() => {
10
- const canvas = canvasRef.current;
11
- if (!canvas)
11
+ const mainCanvas = mainRef.current;
12
+ const overlayCanvas = overlayRef.current;
13
+ if (!mainCanvas || !overlayCanvas)
12
14
  return;
13
- CanvasState.setCanvas(canvas);
14
- // По умолчанию кисть
15
- const brush = new Brush(canvas);
15
+ CanvasState.setCanvas(mainCanvas);
16
+ // По умолчанию включаем кисть
17
+ const brush = new Brush(mainCanvas);
16
18
  toolState.setTool(brush);
17
- // Подключаем TextHoverTool сразу после монтирования, если нужно
18
- const hoverTool = new TextHoverTool(canvas, userName);
19
- hoverTool.listen();
20
- // Если нужно оставить hoverTool активным
21
- toolState.setTool(hoverTool);
19
+ // Подключаем TextHoverTool для отображения имени пользователя
20
+ const hover = new TextHoverTool(mainCanvas, overlayCanvas, userName);
21
+ hover.listen();
22
+ // Ставим hover tool как текущий инструмент (можно потом переключать через кнопки)
23
+ toolState.setTool(hover);
22
24
  // Очистка при размонтировании
23
25
  return () => {
24
- hoverTool.clearEvents();
25
26
  brush.clearEvents();
27
+ hover.clearEvents();
26
28
  };
27
29
  }, [userName]);
28
- return (_jsx("canvas", { ref: canvasRef, width: 1600, height: 900, style: { border: "1px solid black" } }));
30
+ return (_jsxs("div", { style: { position: "relative" }, children: [_jsx("canvas", { ref: mainRef, width: 1600, height: 900, style: { border: "1px solid black", display: "block" } }), _jsx("canvas", { ref: overlayRef, width: 1600, height: 900, style: {
31
+ position: "absolute",
32
+ top: 0,
33
+ left: 0,
34
+ pointerEvents: "none",
35
+ } })] }));
29
36
  };
30
37
  export default Canvas;
@@ -1,43 +1,32 @@
1
1
  import Tool from "./Tool";
2
- export class TextHoverTool extends Tool {
3
- constructor(canvas, userName) {
2
+ export default class TextHoverTool extends Tool {
3
+ constructor(canvas, overlayCanvas, userName) {
4
4
  super(canvas);
5
5
  this.fontSize = 18;
6
6
  this.fontFamily = "Arial";
7
7
  this.color = "black";
8
8
  this.userName = userName;
9
- // Создаём overlay-канвас поверх основного
10
- this.overlayCanvas = document.createElement("canvas");
11
- this.overlayCanvas.width = canvas.width;
12
- this.overlayCanvas.height = canvas.height;
13
- this.overlayCanvas.style.position = "absolute";
14
- this.overlayCanvas.style.left = canvas.offsetLeft + "px";
15
- this.overlayCanvas.style.top = canvas.offsetTop + "px";
16
- this.overlayCanvas.style.pointerEvents = "none"; // мышь проходит через него
17
- canvas.parentElement.appendChild(this.overlayCanvas);
18
- this.overlayCtx = this.overlayCanvas.getContext("2d");
9
+ this.overlayCanvas = overlayCanvas;
10
+ const ctx = overlayCanvas.getContext("2d");
11
+ if (!ctx)
12
+ throw new Error("Cannot get 2D context for overlay");
13
+ this.overlayCtx = ctx;
19
14
  }
20
15
  listen() {
21
- const moveHandler = (evt) => {
22
- const e = evt; // кастим к MouseEvent
23
- // Очищаем overlay
16
+ const moveHandler = (e) => {
17
+ // очищаем overlay
24
18
  this.overlayCtx.clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
25
- // Координаты мыши относительно канваса
26
19
  const x = e.pageX - this.canvas.offsetLeft;
27
20
  const y = e.pageY - this.canvas.offsetTop;
28
- // Рисуем имя чуть выше курсора
29
21
  this.overlayCtx.font = `${this.fontSize}px ${this.fontFamily}`;
30
22
  this.overlayCtx.fillStyle = this.color;
31
23
  this.overlayCtx.fillText(this.userName, x, y - 20);
32
24
  };
33
- this.addListener("mousemove", moveHandler);
25
+ // Типизируем addEventListener как MouseEvent
26
+ this.overlayCanvas.addEventListener("mousemove", moveHandler);
34
27
  }
35
28
  clearEvents() {
36
29
  super.clearEvents();
37
- // Удаляем overlay с DOM
38
- if (this.overlayCanvas.parentElement) {
39
- this.overlayCanvas.parentElement.removeChild(this.overlayCanvas);
40
- }
30
+ this.overlayCtx.clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
41
31
  }
42
32
  }
43
- export default TextHoverTool;
@@ -1,13 +1,12 @@
1
1
  import Tool from "./Tool";
2
- export declare class TextHoverTool extends Tool {
2
+ export default class TextHoverTool extends Tool {
3
3
  userName: string;
4
4
  fontSize: number;
5
5
  fontFamily: string;
6
6
  color: string;
7
- private overlayCanvas;
8
- private overlayCtx;
9
- constructor(canvas: HTMLCanvasElement, userName: string);
7
+ overlayCanvas: HTMLCanvasElement;
8
+ overlayCtx: CanvasRenderingContext2D;
9
+ constructor(canvas: HTMLCanvasElement, overlayCanvas: HTMLCanvasElement, userName: string);
10
10
  listen(): void;
11
11
  clearEvents(): void;
12
12
  }
13
- export default TextHoverTool;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvas-react-easy",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/types/index.d.ts",
6
6
  "license": "MIT",
@@ -1,9 +1,6 @@
1
- import React, { useEffect } from "react";
1
+ import React from "react";
2
2
  import Tools from "./Tools";
3
3
  import Canvas from "./Canvas";
4
- import toolState from "../store/ToolState";
5
- import CanvasState from "../store/CanvasState";
6
- import TextHoverTool from "../tools/TextHoverTool";
7
4
 
8
5
  interface BorderProps {
9
6
  userName?: string;
@@ -2,6 +2,10 @@ import React, { useEffect, useRef } from "react";
2
2
  import CanvasState from "../store/CanvasState";
3
3
  import toolState from "../store/ToolState";
4
4
  import { Brush } from "../tools/Brush";
5
+ import { Rectangle } from "../tools/Rectangle";
6
+ import { Circle } from "../tools/Circle";
7
+ import { TextTool } from "../tools/Text";
8
+ import { ImageTool } from "../tools/ImageTool";
5
9
  import TextHoverTool from "../tools/TextHoverTool";
6
10
 
7
11
  interface CanvasProps {
@@ -9,39 +13,54 @@ interface CanvasProps {
9
13
  }
10
14
 
11
15
  const Canvas: React.FC<CanvasProps> = ({ userName = "Гость" }) => {
12
- const canvasRef = useRef<HTMLCanvasElement>(null);
16
+ const mainRef = useRef<HTMLCanvasElement>(null);
17
+ const overlayRef = useRef<HTMLCanvasElement>(null);
13
18
 
14
19
  useEffect(() => {
15
- const canvas = canvasRef.current;
16
- if (!canvas) return;
20
+ const mainCanvas = mainRef.current;
21
+ const overlayCanvas = overlayRef.current;
22
+ if (!mainCanvas || !overlayCanvas) return;
17
23
 
18
- CanvasState.setCanvas(canvas);
24
+ CanvasState.setCanvas(mainCanvas);
19
25
 
20
- // По умолчанию кисть
21
- const brush = new Brush(canvas);
26
+ // По умолчанию включаем кисть
27
+ const brush = new Brush(mainCanvas);
22
28
  toolState.setTool(brush);
23
29
 
24
- // Подключаем TextHoverTool сразу после монтирования, если нужно
25
- const hoverTool = new TextHoverTool(canvas, userName);
26
- hoverTool.listen();
30
+ // Подключаем TextHoverTool для отображения имени пользователя
31
+ const hover = new TextHoverTool(mainCanvas, overlayCanvas, userName);
32
+ hover.listen();
27
33
 
28
- // Если нужно оставить hoverTool активным
29
- toolState.setTool(hoverTool);
34
+ // Ставим hover tool как текущий инструмент (можно потом переключать через кнопки)
35
+ toolState.setTool(hover);
30
36
 
31
37
  // Очистка при размонтировании
32
38
  return () => {
33
- hoverTool.clearEvents();
34
39
  brush.clearEvents();
40
+ hover.clearEvents();
35
41
  };
36
42
  }, [userName]);
37
43
 
38
44
  return (
39
- <canvas
40
- ref={canvasRef}
41
- width={1600}
42
- height={900}
43
- style={{ border: "1px solid black" }}
44
- />
45
+ <div style={{ position: "relative" }}>
46
+ <canvas
47
+ ref={mainRef}
48
+ width={1600}
49
+ height={900}
50
+ style={{ border: "1px solid black", display: "block" }}
51
+ />
52
+ <canvas
53
+ ref={overlayRef}
54
+ width={1600}
55
+ height={900}
56
+ style={{
57
+ position: "absolute",
58
+ top: 0,
59
+ left: 0,
60
+ pointerEvents: "none",
61
+ }}
62
+ />
63
+ </div>
45
64
  );
46
65
  };
47
66
 
@@ -1,58 +1,51 @@
1
1
  import Tool from "./Tool";
2
2
 
3
- export class TextHoverTool extends Tool {
4
- userName: string;
5
- fontSize: number = 18;
6
- fontFamily: string = "Arial";
7
- color: string = "black";
8
-
9
- private overlayCanvas!: HTMLCanvasElement;
10
- private overlayCtx!: CanvasRenderingContext2D;
11
-
12
- constructor(canvas: HTMLCanvasElement, userName: string) {
13
- super(canvas);
14
- this.userName = userName;
15
-
16
- // Создаём overlay-канвас поверх основного
17
- this.overlayCanvas = document.createElement("canvas");
18
- this.overlayCanvas.width = canvas.width;
19
- this.overlayCanvas.height = canvas.height;
20
- this.overlayCanvas.style.position = "absolute";
21
- this.overlayCanvas.style.left = canvas.offsetLeft + "px";
22
- this.overlayCanvas.style.top = canvas.offsetTop + "px";
23
- this.overlayCanvas.style.pointerEvents = "none"; // мышь проходит через него
24
- canvas.parentElement!.appendChild(this.overlayCanvas);
25
-
26
- this.overlayCtx = this.overlayCanvas.getContext("2d")!;
27
- }
28
-
29
- listen() {
30
- const moveHandler = (evt: Event) => {
31
- const e = evt as MouseEvent; // кастим к MouseEvent
32
-
33
- // Очищаем overlay
34
- this.overlayCtx.clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
35
-
36
- // Координаты мыши относительно канваса
37
- const x = e.pageX - this.canvas.offsetLeft;
38
- const y = e.pageY - this.canvas.offsetTop;
39
-
40
- // Рисуем имя чуть выше курсора
41
- this.overlayCtx.font = `${this.fontSize}px ${this.fontFamily}`;
42
- this.overlayCtx.fillStyle = this.color;
43
- this.overlayCtx.fillText(this.userName, x, y - 20);
44
- };
45
-
46
- this.addListener("mousemove", moveHandler);
47
- }
48
-
49
- clearEvents() {
50
- super.clearEvents();
51
- // Удаляем overlay с DOM
52
- if (this.overlayCanvas.parentElement) {
53
- this.overlayCanvas.parentElement.removeChild(this.overlayCanvas);
54
- }
55
- }
3
+ export default class TextHoverTool extends Tool {
4
+ userName: string;
5
+ fontSize = 18;
6
+ fontFamily = "Arial";
7
+ color = "black";
8
+
9
+ overlayCanvas: HTMLCanvasElement;
10
+ overlayCtx: CanvasRenderingContext2D;
11
+
12
+ constructor(
13
+ canvas: HTMLCanvasElement,
14
+ overlayCanvas: HTMLCanvasElement,
15
+ userName: string
16
+ ) {
17
+ super(canvas);
18
+ this.userName = userName;
19
+ this.overlayCanvas = overlayCanvas;
20
+ const ctx = overlayCanvas.getContext("2d");
21
+ if (!ctx) throw new Error("Cannot get 2D context for overlay");
22
+ this.overlayCtx = ctx;
23
+ }
24
+
25
+ listen() {
26
+ const moveHandler = (e: MouseEvent) => {
27
+ // очищаем overlay
28
+ this.overlayCtx.clearRect(
29
+ 0,
30
+ 0,
31
+ this.overlayCanvas.width,
32
+ this.overlayCanvas.height
33
+ );
34
+
35
+ const x = e.pageX - this.canvas.offsetLeft;
36
+ const y = e.pageY - this.canvas.offsetTop;
37
+
38
+ this.overlayCtx.font = `${this.fontSize}px ${this.fontFamily}`;
39
+ this.overlayCtx.fillStyle = this.color;
40
+ this.overlayCtx.fillText(this.userName, x, y - 20);
41
+ };
42
+
43
+ // Типизируем addEventListener как MouseEvent
44
+ this.overlayCanvas.addEventListener("mousemove", moveHandler as EventListener);
45
+ }
46
+
47
+ clearEvents() {
48
+ super.clearEvents();
49
+ this.overlayCtx.clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
50
+ }
56
51
  }
57
-
58
- export default TextHoverTool;