canvas-react-easy 1.1.2 → 1.1.4
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.
- package/dist/components/Border.js +2 -2
- package/dist/components/Canvas.js +7 -21
- package/dist/components/Tools.js +1 -1
- package/dist/store/CanvasState.js +0 -1
- package/dist/store/ToolState.js +0 -1
- package/dist/tools/TextHoverTool.js +12 -23
- package/dist/types/components/Border.d.ts +1 -4
- package/dist/types/components/Canvas.d.ts +1 -4
- package/dist/types/components/Tools.d.ts +1 -4
- package/dist/types/tools/TextHoverTool.d.ts +4 -5
- package/package.json +1 -1
- package/src/components/Border.tsx +4 -11
- package/src/components/Canvas.tsx +7 -29
- package/src/components/Tools.tsx +1 -5
- package/src/store/CanvasState.ts +0 -1
- package/src/store/ToolState.ts +1 -2
- package/src/tools/TextHoverTool.ts +48 -55
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Tools from "./Tools";
|
|
3
3
|
import Canvas from "./Canvas";
|
|
4
|
-
const Border = (
|
|
5
|
-
return (_jsxs("div", { style: { position: "relative" }, children: [_jsx(Tools, {
|
|
4
|
+
const Border = () => {
|
|
5
|
+
return (_jsxs("div", { style: { position: "relative" }, children: [_jsx(Tools, {}), _jsx(Canvas, {})] }));
|
|
6
6
|
};
|
|
7
7
|
export default Border;
|
|
@@ -3,28 +3,14 @@ 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
|
-
|
|
7
|
-
const Canvas = ({ userName = "Гость" }) => {
|
|
6
|
+
const Canvas = () => {
|
|
8
7
|
const canvasRef = useRef(null);
|
|
9
8
|
useEffect(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
toolState.setTool(brush);
|
|
17
|
-
// Подключаем TextHoverTool сразу после монтирования, если нужно
|
|
18
|
-
const hoverTool = new TextHoverTool(canvas, userName);
|
|
19
|
-
hoverTool.listen();
|
|
20
|
-
// Если нужно оставить hoverTool активным
|
|
21
|
-
toolState.setTool(hoverTool);
|
|
22
|
-
// Очистка при размонтировании
|
|
23
|
-
return () => {
|
|
24
|
-
hoverTool.clearEvents();
|
|
25
|
-
brush.clearEvents();
|
|
26
|
-
};
|
|
27
|
-
}, [userName]);
|
|
28
|
-
return (_jsx("canvas", { ref: canvasRef, width: 1600, height: 900, style: { border: "1px solid black" } }));
|
|
9
|
+
if (canvasRef.current) {
|
|
10
|
+
CanvasState.setCanvas(canvasRef.current);
|
|
11
|
+
toolState.setTool(new Brush(canvasRef.current));
|
|
12
|
+
}
|
|
13
|
+
}, []);
|
|
14
|
+
return (_jsx("canvas", { ref: canvasRef, width: 1600, height: 900, style: { border: "1px solid black", display: "block" } }));
|
|
29
15
|
};
|
|
30
16
|
export default Canvas;
|
package/dist/components/Tools.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Rectangle } from "../tools/Rectangle";
|
|
|
6
6
|
import { Circle } from "../tools/Circle";
|
|
7
7
|
import { TextTool } from "../tools/Text";
|
|
8
8
|
import { ImageTool } from "../tools/ImageTool";
|
|
9
|
-
const Tools = (
|
|
9
|
+
const Tools = () => {
|
|
10
10
|
const selectTool = (ToolClass) => {
|
|
11
11
|
var _a, _b;
|
|
12
12
|
if (!CanvasState.canvas)
|
package/dist/store/ToolState.js
CHANGED
|
@@ -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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.
|
|
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 = (
|
|
22
|
-
|
|
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
|
-
|
|
25
|
+
// Типизируем addEventListener как MouseEvent
|
|
26
|
+
this.overlayCanvas.addEventListener("mousemove", moveHandler);
|
|
34
27
|
}
|
|
35
28
|
clearEvents() {
|
|
36
29
|
super.clearEvents();
|
|
37
|
-
|
|
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
|
|
2
|
+
export default class TextHoverTool extends Tool {
|
|
3
3
|
userName: string;
|
|
4
4
|
fontSize: number;
|
|
5
5
|
fontFamily: string;
|
|
6
6
|
color: string;
|
|
7
|
-
|
|
8
|
-
|
|
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,19 +1,12 @@
|
|
|
1
|
-
import 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
|
-
|
|
9
|
-
userName?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const Border: React.FC<BorderProps> = ({ userName = "Гость" }) => {
|
|
5
|
+
const Border: React.FC = () => {
|
|
13
6
|
return (
|
|
14
7
|
<div style={{ position: "relative" }}>
|
|
15
|
-
<Tools
|
|
16
|
-
<Canvas
|
|
8
|
+
<Tools />
|
|
9
|
+
<Canvas />
|
|
17
10
|
</div>
|
|
18
11
|
);
|
|
19
12
|
};
|
|
@@ -2,45 +2,23 @@ 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 TextHoverTool from "../tools/TextHoverTool";
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
userName?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const Canvas: React.FC<CanvasProps> = ({ userName = "Гость" }) => {
|
|
6
|
+
const Canvas: React.FC = () => {
|
|
12
7
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
13
8
|
|
|
14
9
|
useEffect(() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// По умолчанию кисть
|
|
21
|
-
const brush = new Brush(canvas);
|
|
22
|
-
toolState.setTool(brush);
|
|
23
|
-
|
|
24
|
-
// Подключаем TextHoverTool сразу после монтирования, если нужно
|
|
25
|
-
const hoverTool = new TextHoverTool(canvas, userName);
|
|
26
|
-
hoverTool.listen();
|
|
27
|
-
|
|
28
|
-
// Если нужно оставить hoverTool активным
|
|
29
|
-
toolState.setTool(hoverTool);
|
|
30
|
-
|
|
31
|
-
// Очистка при размонтировании
|
|
32
|
-
return () => {
|
|
33
|
-
hoverTool.clearEvents();
|
|
34
|
-
brush.clearEvents();
|
|
35
|
-
};
|
|
36
|
-
}, [userName]);
|
|
10
|
+
if (canvasRef.current) {
|
|
11
|
+
CanvasState.setCanvas(canvasRef.current);
|
|
12
|
+
toolState.setTool(new Brush(canvasRef.current));
|
|
13
|
+
}
|
|
14
|
+
}, []);
|
|
37
15
|
|
|
38
16
|
return (
|
|
39
17
|
<canvas
|
|
40
18
|
ref={canvasRef}
|
|
41
19
|
width={1600}
|
|
42
20
|
height={900}
|
|
43
|
-
style={{ border: "1px solid black" }}
|
|
21
|
+
style={{ border: "1px solid black", display: "block" }}
|
|
44
22
|
/>
|
|
45
23
|
);
|
|
46
24
|
};
|
package/src/components/Tools.tsx
CHANGED
|
@@ -7,11 +7,7 @@ import { Circle } from "../tools/Circle";
|
|
|
7
7
|
import { TextTool } from "../tools/Text";
|
|
8
8
|
import { ImageTool } from "../tools/ImageTool";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
userName?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const Tools: React.FC<ToolsProps> = ({ userName = "Гость" }) => {
|
|
10
|
+
const Tools: React.FC = () => {
|
|
15
11
|
const selectTool = (ToolClass: any) => {
|
|
16
12
|
if (!CanvasState.canvas) return;
|
|
17
13
|
|
package/src/store/CanvasState.ts
CHANGED
package/src/store/ToolState.ts
CHANGED
|
@@ -1,58 +1,51 @@
|
|
|
1
1
|
import Tool from "./Tool";
|
|
2
2
|
|
|
3
|
-
export class TextHoverTool extends Tool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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;
|