canvas-react-easy 1.0.2 → 1.0.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.
- package/package.json +6 -5
- package/src/components/Tools.tsx +17 -10
- package/src/tools/Circle.ts +39 -0
- package/src/tools/ImageTool.ts +28 -0
- package/src/tools/Rectangle.ts +40 -0
- package/src/tools/Text.ts +25 -0
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvas-react-easy",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/types/index.d.ts",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"peerDependencies": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"mobx": "^6.0.0",
|
|
9
|
+
"mobx-react-lite": "^3.0.0 || ^4.0.0",
|
|
10
|
+
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
|
11
11
|
},
|
|
12
|
-
|
|
13
12
|
"scripts": {
|
|
14
13
|
"build": "tsc"
|
|
15
14
|
},
|
|
16
15
|
"devDependencies": {
|
|
16
|
+
"@types/react": "^19.2.14",
|
|
17
|
+
"@types/react-dom": "^19.2.3",
|
|
17
18
|
"typescript": "^5.9.3"
|
|
18
19
|
}
|
|
19
20
|
}
|
package/src/components/Tools.tsx
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import toolState from "../store/ToolState";
|
|
2
3
|
import CanvasState from "../store/CanvasState";
|
|
3
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";
|
|
4
9
|
|
|
5
10
|
const Tools = () => {
|
|
11
|
+
const selectBrush = () => CanvasState.canvas && toolState.setTool(new Brush(CanvasState.canvas));
|
|
12
|
+
const selectRectangle = () => CanvasState.canvas && toolState.setTool(new Rectangle(CanvasState.canvas));
|
|
13
|
+
const selectCircle = () => CanvasState.canvas && toolState.setTool(new Circle(CanvasState.canvas));
|
|
14
|
+
const selectText = () => CanvasState.canvas && toolState.setTool(new TextTool(CanvasState.canvas));
|
|
15
|
+
const selectImage = () => CanvasState.canvas && toolState.setTool(new ImageTool(CanvasState.canvas));
|
|
16
|
+
|
|
6
17
|
return (
|
|
7
|
-
<div>
|
|
8
|
-
<button
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}}
|
|
14
|
-
>
|
|
15
|
-
Кисть
|
|
16
|
-
</button>
|
|
18
|
+
<div style={{ marginBottom: "10px" }}>
|
|
19
|
+
<button onClick={selectBrush}>Кисть</button>
|
|
20
|
+
<button onClick={selectRectangle}>Прямоугольник</button>
|
|
21
|
+
<button onClick={selectCircle}>Круг</button>
|
|
22
|
+
<button onClick={selectText}>Текст</button>
|
|
23
|
+
<button onClick={selectImage}>Изображение</button>
|
|
17
24
|
</div>
|
|
18
25
|
);
|
|
19
26
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
|
|
3
|
+
export class Circle extends Tool {
|
|
4
|
+
private startX = 0;
|
|
5
|
+
private startY = 0;
|
|
6
|
+
private mouseDown = false;
|
|
7
|
+
|
|
8
|
+
constructor(canvas: HTMLCanvasElement) {
|
|
9
|
+
super(canvas);
|
|
10
|
+
this.listen();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
listen() {
|
|
14
|
+
this.canvas.onmousedown = this.onMouseDownHandler.bind(this);
|
|
15
|
+
this.canvas.onmouseup = this.onMouseUpHandler.bind(this);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
onMouseDownHandler(e: MouseEvent) {
|
|
19
|
+
this.mouseDown = true;
|
|
20
|
+
const target = e.target as HTMLCanvasElement;
|
|
21
|
+
this.startX = e.pageX - target.offsetLeft;
|
|
22
|
+
this.startY = e.pageY - target.offsetTop;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
onMouseUpHandler(e: MouseEvent) {
|
|
26
|
+
if (!this.mouseDown) return;
|
|
27
|
+
this.mouseDown = false;
|
|
28
|
+
|
|
29
|
+
const target = e.target as HTMLCanvasElement;
|
|
30
|
+
const endX = e.pageX - target.offsetLeft;
|
|
31
|
+
const endY = e.pageY - target.offsetTop;
|
|
32
|
+
|
|
33
|
+
const radius = Math.sqrt(Math.pow(endX - this.startX, 2) + Math.pow(endY - this.startY, 2));
|
|
34
|
+
|
|
35
|
+
this.ctx.beginPath();
|
|
36
|
+
this.ctx.arc(this.startX, this.startY, radius, 0, 2 * Math.PI);
|
|
37
|
+
this.ctx.stroke();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
|
|
3
|
+
export class ImageTool extends Tool {
|
|
4
|
+
constructor(canvas: HTMLCanvasElement) {
|
|
5
|
+
super(canvas);
|
|
6
|
+
this.listen();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
listen() {
|
|
10
|
+
this.canvas.onclick = this.onClickHandler.bind(this);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async onClickHandler(e: MouseEvent) {
|
|
14
|
+
const target = e.target as HTMLCanvasElement;
|
|
15
|
+
const x = e.pageX - target.offsetLeft;
|
|
16
|
+
const y = e.pageY - target.offsetTop;
|
|
17
|
+
|
|
18
|
+
const url = prompt("Введите URL изображения");
|
|
19
|
+
if (!url) return;
|
|
20
|
+
|
|
21
|
+
const img = new Image();
|
|
22
|
+
img.src = url;
|
|
23
|
+
|
|
24
|
+
img.onload = () => {
|
|
25
|
+
this.ctx.drawImage(img, x, y, img.width, img.height);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
|
|
3
|
+
export class Rectangle extends Tool {
|
|
4
|
+
private startX = 0;
|
|
5
|
+
private startY = 0;
|
|
6
|
+
private mouseDown = false;
|
|
7
|
+
|
|
8
|
+
constructor(canvas: HTMLCanvasElement) {
|
|
9
|
+
super(canvas);
|
|
10
|
+
this.listen();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
listen() {
|
|
14
|
+
this.canvas.onmousedown = this.onMouseDownHandler.bind(this);
|
|
15
|
+
this.canvas.onmouseup = this.onMouseUpHandler.bind(this);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
onMouseDownHandler(e: MouseEvent) {
|
|
19
|
+
this.mouseDown = true;
|
|
20
|
+
const target = e.target as HTMLCanvasElement;
|
|
21
|
+
this.startX = e.pageX - target.offsetLeft;
|
|
22
|
+
this.startY = e.pageY - target.offsetTop;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
onMouseUpHandler(e: MouseEvent) {
|
|
26
|
+
if (!this.mouseDown) return;
|
|
27
|
+
this.mouseDown = false;
|
|
28
|
+
|
|
29
|
+
const target = e.target as HTMLCanvasElement;
|
|
30
|
+
const endX = e.pageX - target.offsetLeft;
|
|
31
|
+
const endY = e.pageY - target.offsetTop;
|
|
32
|
+
|
|
33
|
+
const width = endX - this.startX;
|
|
34
|
+
const height = endY - this.startY;
|
|
35
|
+
|
|
36
|
+
this.ctx.beginPath();
|
|
37
|
+
this.ctx.rect(this.startX, this.startY, width, height);
|
|
38
|
+
this.ctx.stroke();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
|
|
3
|
+
export class TextTool extends Tool {
|
|
4
|
+
constructor(canvas: HTMLCanvasElement) {
|
|
5
|
+
super(canvas);
|
|
6
|
+
this.listen();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
listen() {
|
|
10
|
+
this.canvas.onclick = this.onClickHandler.bind(this);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
onClickHandler(e: MouseEvent) {
|
|
14
|
+
const target = e.target as HTMLCanvasElement;
|
|
15
|
+
const x = e.pageX - target.offsetLeft;
|
|
16
|
+
const y = e.pageY - target.offsetTop;
|
|
17
|
+
|
|
18
|
+
const text = prompt("Введите текст");
|
|
19
|
+
if (!text) return;
|
|
20
|
+
|
|
21
|
+
this.ctx.font = "20px Arial";
|
|
22
|
+
this.ctx.fillStyle = "black";
|
|
23
|
+
this.ctx.fillText(text, x, y);
|
|
24
|
+
}
|
|
25
|
+
}
|