canvas-react-easy 1.0.4 → 1.0.6
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/Tools.js +16 -6
- package/dist/tools/Circle.js +32 -0
- package/dist/tools/ImageTool.js +34 -0
- package/dist/tools/Rectangle.js +33 -0
- package/dist/tools/Text.js +32 -0
- package/dist/tools/Tool.js +4 -7
- package/dist/types/components/Border.d.ts +3 -1
- package/dist/types/components/Canvas.d.ts +1 -1
- package/dist/types/components/Tools.d.ts +1 -1
- package/dist/types/store/ToolState.d.ts +1 -0
- package/dist/types/tools/Circle.d.ts +10 -0
- package/dist/types/tools/ImageTool.d.ts +6 -0
- package/dist/types/tools/Rectangle.d.ts +10 -0
- package/dist/types/tools/Text.d.ts +6 -0
- package/dist/types/tools/Tool.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/Tools.tsx +17 -10
- package/src/store/ToolState.ts +1 -0
- package/src/tools/Text.ts +12 -1
- package/src/tools/Tool.ts +10 -15
package/dist/components/Tools.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import toolState from "../store/ToolState";
|
|
3
3
|
import CanvasState from "../store/CanvasState";
|
|
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
|
const Tools = () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const selectTool = (ToolClass) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const canvas = CanvasState.canvas;
|
|
13
|
+
if (!canvas)
|
|
14
|
+
return;
|
|
15
|
+
// Очищаем события старого инструмента
|
|
16
|
+
(_a = toolState.tool) === null || _a === void 0 ? void 0 : _a.clearEvents();
|
|
17
|
+
// Устанавливаем новый инструмент
|
|
18
|
+
toolState.setTool(new ToolClass(canvas));
|
|
19
|
+
};
|
|
20
|
+
return (_jsxs("div", { style: { marginBottom: "10px" }, children: [_jsx("button", { onClick: () => selectTool(Brush), children: "\u041A\u0438\u0441\u0442\u044C" }), _jsx("button", { onClick: () => selectTool(Rectangle), children: "\u041F\u0440\u044F\u043C\u043E\u0443\u0433\u043E\u043B\u044C\u043D\u0438\u043A" }), _jsx("button", { onClick: () => selectTool(Circle), children: "\u041A\u0440\u0443\u0433" }), _jsx("button", { onClick: () => selectTool(TextTool), children: "\u0422\u0435\u043A\u0441\u0442" }), _jsx("button", { onClick: () => selectTool(ImageTool), children: "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435" })] }));
|
|
11
21
|
};
|
|
12
22
|
export default Tools;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
export class Circle extends Tool {
|
|
3
|
+
constructor(canvas) {
|
|
4
|
+
super(canvas);
|
|
5
|
+
this.startX = 0;
|
|
6
|
+
this.startY = 0;
|
|
7
|
+
this.mouseDown = false;
|
|
8
|
+
this.listen();
|
|
9
|
+
}
|
|
10
|
+
listen() {
|
|
11
|
+
this.canvas.onmousedown = this.onMouseDownHandler.bind(this);
|
|
12
|
+
this.canvas.onmouseup = this.onMouseUpHandler.bind(this);
|
|
13
|
+
}
|
|
14
|
+
onMouseDownHandler(e) {
|
|
15
|
+
this.mouseDown = true;
|
|
16
|
+
const target = e.target;
|
|
17
|
+
this.startX = e.pageX - target.offsetLeft;
|
|
18
|
+
this.startY = e.pageY - target.offsetTop;
|
|
19
|
+
}
|
|
20
|
+
onMouseUpHandler(e) {
|
|
21
|
+
if (!this.mouseDown)
|
|
22
|
+
return;
|
|
23
|
+
this.mouseDown = false;
|
|
24
|
+
const target = e.target;
|
|
25
|
+
const endX = e.pageX - target.offsetLeft;
|
|
26
|
+
const endY = e.pageY - target.offsetTop;
|
|
27
|
+
const radius = Math.sqrt(Math.pow(endX - this.startX, 2) + Math.pow(endY - this.startY, 2));
|
|
28
|
+
this.ctx.beginPath();
|
|
29
|
+
this.ctx.arc(this.startX, this.startY, radius, 0, 2 * Math.PI);
|
|
30
|
+
this.ctx.stroke();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import Tool from "./Tool";
|
|
11
|
+
export class ImageTool extends Tool {
|
|
12
|
+
constructor(canvas) {
|
|
13
|
+
super(canvas);
|
|
14
|
+
this.listen();
|
|
15
|
+
}
|
|
16
|
+
listen() {
|
|
17
|
+
this.canvas.onclick = this.onClickHandler.bind(this);
|
|
18
|
+
}
|
|
19
|
+
onClickHandler(e) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const target = e.target;
|
|
22
|
+
const x = e.pageX - target.offsetLeft;
|
|
23
|
+
const y = e.pageY - target.offsetTop;
|
|
24
|
+
const url = prompt("Введите URL изображения");
|
|
25
|
+
if (!url)
|
|
26
|
+
return;
|
|
27
|
+
const img = new Image();
|
|
28
|
+
img.src = url;
|
|
29
|
+
img.onload = () => {
|
|
30
|
+
this.ctx.drawImage(img, x, y, img.width, img.height);
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
export class Rectangle extends Tool {
|
|
3
|
+
constructor(canvas) {
|
|
4
|
+
super(canvas);
|
|
5
|
+
this.startX = 0;
|
|
6
|
+
this.startY = 0;
|
|
7
|
+
this.mouseDown = false;
|
|
8
|
+
this.listen();
|
|
9
|
+
}
|
|
10
|
+
listen() {
|
|
11
|
+
this.canvas.onmousedown = this.onMouseDownHandler.bind(this);
|
|
12
|
+
this.canvas.onmouseup = this.onMouseUpHandler.bind(this);
|
|
13
|
+
}
|
|
14
|
+
onMouseDownHandler(e) {
|
|
15
|
+
this.mouseDown = true;
|
|
16
|
+
const target = e.target;
|
|
17
|
+
this.startX = e.pageX - target.offsetLeft;
|
|
18
|
+
this.startY = e.pageY - target.offsetTop;
|
|
19
|
+
}
|
|
20
|
+
onMouseUpHandler(e) {
|
|
21
|
+
if (!this.mouseDown)
|
|
22
|
+
return;
|
|
23
|
+
this.mouseDown = false;
|
|
24
|
+
const target = e.target;
|
|
25
|
+
const endX = e.pageX - target.offsetLeft;
|
|
26
|
+
const endY = e.pageY - target.offsetTop;
|
|
27
|
+
const width = endX - this.startX;
|
|
28
|
+
const height = endY - this.startY;
|
|
29
|
+
this.ctx.beginPath();
|
|
30
|
+
this.ctx.rect(this.startX, this.startY, width, height);
|
|
31
|
+
this.ctx.stroke();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
export class TextTool extends Tool {
|
|
3
|
+
constructor(canvas) {
|
|
4
|
+
super(canvas);
|
|
5
|
+
this.listen();
|
|
6
|
+
}
|
|
7
|
+
listen() {
|
|
8
|
+
const handler = (e) => {
|
|
9
|
+
const target = e.target;
|
|
10
|
+
const x = e.pageX - target.offsetLeft;
|
|
11
|
+
const y = e.pageY - target.offsetTop;
|
|
12
|
+
const text = prompt("Введите текст");
|
|
13
|
+
if (text) {
|
|
14
|
+
this.ctx.fillText(text, x, y);
|
|
15
|
+
}
|
|
16
|
+
// убираем событие после первого использования
|
|
17
|
+
target.removeEventListener("mousedown", handler);
|
|
18
|
+
};
|
|
19
|
+
this.canvas.addEventListener("mousedown", handler);
|
|
20
|
+
}
|
|
21
|
+
onClickHandler(e) {
|
|
22
|
+
const target = e.target;
|
|
23
|
+
const x = e.pageX - target.offsetLeft;
|
|
24
|
+
const y = e.pageY - target.offsetTop;
|
|
25
|
+
const text = prompt("Введите текст");
|
|
26
|
+
if (!text)
|
|
27
|
+
return;
|
|
28
|
+
this.ctx.font = "20px Arial";
|
|
29
|
+
this.ctx.fillStyle = "black";
|
|
30
|
+
this.ctx.fillText(text, x, y);
|
|
31
|
+
}
|
|
32
|
+
}
|
package/dist/tools/Tool.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
export default class Tool {
|
|
2
2
|
constructor(canvas) {
|
|
3
3
|
this.canvas = canvas;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
throw new Error("Canvas context is null");
|
|
7
|
-
this.ctx = context;
|
|
8
|
-
this.destroyEvents();
|
|
4
|
+
this.ctx = canvas.getContext("2d");
|
|
5
|
+
this.clearEvents();
|
|
9
6
|
}
|
|
10
|
-
|
|
11
|
-
this.canvas.onmousemove = null;
|
|
7
|
+
clearEvents() {
|
|
12
8
|
this.canvas.onmousedown = null;
|
|
13
9
|
this.canvas.onmouseup = null;
|
|
10
|
+
this.canvas.onmousemove = null;
|
|
14
11
|
}
|
|
15
12
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const Canvas: () =>
|
|
1
|
+
declare const Canvas: () => import("react/jsx-runtime").JSX.Element;
|
|
2
2
|
export default Canvas;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const Tools: () =>
|
|
1
|
+
declare const Tools: () => import("react/jsx-runtime").JSX.Element;
|
|
2
2
|
export default Tools;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
export declare class Circle extends Tool {
|
|
3
|
+
private startX;
|
|
4
|
+
private startY;
|
|
5
|
+
private mouseDown;
|
|
6
|
+
constructor(canvas: HTMLCanvasElement);
|
|
7
|
+
listen(): void;
|
|
8
|
+
onMouseDownHandler(e: MouseEvent): void;
|
|
9
|
+
onMouseUpHandler(e: MouseEvent): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Tool from "./Tool";
|
|
2
|
+
export declare class Rectangle extends Tool {
|
|
3
|
+
private startX;
|
|
4
|
+
private startY;
|
|
5
|
+
private mouseDown;
|
|
6
|
+
constructor(canvas: HTMLCanvasElement);
|
|
7
|
+
listen(): void;
|
|
8
|
+
onMouseDownHandler(e: MouseEvent): void;
|
|
9
|
+
onMouseUpHandler(e: MouseEvent): void;
|
|
10
|
+
}
|
package/package.json
CHANGED
package/src/components/Tools.tsx
CHANGED
|
@@ -8,19 +8,26 @@ import { TextTool } from "../tools/Text";
|
|
|
8
8
|
import { ImageTool } from "../tools/ImageTool";
|
|
9
9
|
|
|
10
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
11
|
|
|
12
|
+
const selectTool = (ToolClass: any) => {
|
|
13
|
+
const canvas = CanvasState.canvas;
|
|
14
|
+
if (!canvas) return;
|
|
15
|
+
|
|
16
|
+
// Очищаем события старого инструмента
|
|
17
|
+
toolState.tool?.clearEvents();
|
|
18
|
+
|
|
19
|
+
// Устанавливаем новый инструмент
|
|
20
|
+
toolState.setTool(new ToolClass(canvas));
|
|
21
|
+
};
|
|
22
|
+
|
|
17
23
|
return (
|
|
18
24
|
<div style={{ marginBottom: "10px" }}>
|
|
19
|
-
<button onClick={
|
|
20
|
-
<button onClick={
|
|
21
|
-
<button onClick={
|
|
22
|
-
<button onClick={
|
|
23
|
-
<button onClick={
|
|
25
|
+
<button onClick={() => selectTool(Brush)}>Кисть</button>
|
|
26
|
+
<button onClick={() => selectTool(Rectangle)}>Прямоугольник</button>
|
|
27
|
+
<button onClick={() => selectTool(Circle)}>Круг</button>
|
|
28
|
+
<button onClick={() => selectTool(TextTool)}>Текст</button>
|
|
29
|
+
<button onClick={() => selectTool(ImageTool)}>Изображение</button>
|
|
30
|
+
|
|
24
31
|
</div>
|
|
25
32
|
);
|
|
26
33
|
};
|
package/src/store/ToolState.ts
CHANGED
package/src/tools/Text.ts
CHANGED
|
@@ -7,7 +7,18 @@ export class TextTool extends Tool {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
listen() {
|
|
10
|
-
|
|
10
|
+
const handler = (e: MouseEvent) => {
|
|
11
|
+
const target = e.target as HTMLCanvasElement;
|
|
12
|
+
const x = e.pageX - target.offsetLeft;
|
|
13
|
+
const y = e.pageY - target.offsetTop;
|
|
14
|
+
const text = prompt("Введите текст");
|
|
15
|
+
if (text) {
|
|
16
|
+
this.ctx.fillText(text, x, y);
|
|
17
|
+
}
|
|
18
|
+
// убираем событие после первого использования
|
|
19
|
+
target.removeEventListener("mousedown", handler);
|
|
20
|
+
};
|
|
21
|
+
this.canvas.addEventListener("mousedown", handler);
|
|
11
22
|
}
|
|
12
23
|
|
|
13
24
|
onClickHandler(e: MouseEvent) {
|
package/src/tools/Tool.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
export default class Tool {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.destroyEvents();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
destroyEvents() {
|
|
14
|
-
this.canvas.onmousemove = null;
|
|
2
|
+
constructor(public canvas: HTMLCanvasElement) {
|
|
3
|
+
this.ctx = canvas.getContext("2d")!;
|
|
4
|
+
this.clearEvents();
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
ctx: CanvasRenderingContext2D;
|
|
8
|
+
|
|
9
|
+
clearEvents() {
|
|
15
10
|
this.canvas.onmousedown = null;
|
|
16
11
|
this.canvas.onmouseup = null;
|
|
17
|
-
|
|
12
|
+
this.canvas.onmousemove = null;
|
|
18
13
|
}
|
|
19
|
-
|
|
14
|
+
}
|