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.
@@ -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
- return (_jsx("div", { children: _jsx("button", { onClick: () => {
7
- if (CanvasState.canvas) {
8
- toolState.setTool(new Brush(CanvasState.canvas));
9
- }
10
- }, children: "\u041A\u0438\u0441\u0442\u044C" }) }));
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
+ }
@@ -1,15 +1,12 @@
1
1
  export default class Tool {
2
2
  constructor(canvas) {
3
3
  this.canvas = canvas;
4
- const context = canvas.getContext("2d");
5
- if (!context)
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
- destroyEvents() {
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,4 @@
1
- declare const Border: React.MemoExoticComponent<React.ForwardRefExoticComponent<any>>;
1
+ declare const Border: (() => import("react/jsx-runtime").JSX.Element) & {
2
+ displayName: string;
3
+ };
2
4
  export default Border;
@@ -1,2 +1,2 @@
1
- declare const Canvas: () => any;
1
+ declare const Canvas: () => import("react/jsx-runtime").JSX.Element;
2
2
  export default Canvas;
@@ -1,2 +1,2 @@
1
- declare const Tools: () => any;
1
+ declare const Tools: () => import("react/jsx-runtime").JSX.Element;
2
2
  export default Tools;
@@ -1,3 +1,4 @@
1
+ import Tool from "../tools/Tool";
1
2
  declare class ToolState {
2
3
  tool: Tool | null;
3
4
  constructor();
@@ -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,6 @@
1
+ import Tool from "./Tool";
2
+ export declare class ImageTool extends Tool {
3
+ constructor(canvas: HTMLCanvasElement);
4
+ listen(): void;
5
+ onClickHandler(e: MouseEvent): Promise<void>;
6
+ }
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ import Tool from "./Tool";
2
+ export declare class TextTool extends Tool {
3
+ constructor(canvas: HTMLCanvasElement);
4
+ listen(): void;
5
+ onClickHandler(e: MouseEvent): void;
6
+ }
@@ -1,6 +1,6 @@
1
1
  export default class Tool {
2
2
  canvas: HTMLCanvasElement;
3
- ctx: CanvasRenderingContext2D;
4
3
  constructor(canvas: HTMLCanvasElement);
5
- destroyEvents(): void;
4
+ ctx: CanvasRenderingContext2D;
5
+ clearEvents(): void;
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvas-react-easy",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/types/index.d.ts",
6
6
  "license": "MIT",
@@ -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={selectBrush}>Кисть</button>
20
- <button onClick={selectRectangle}>Прямоугольник</button>
21
- <button onClick={selectCircle}>Круг</button>
22
- <button onClick={selectText}>Текст</button>
23
- <button onClick={selectImage}>Изображение</button>
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
  };
@@ -1,5 +1,6 @@
1
1
  // ToolState.ts
2
2
  import { makeAutoObservable } from "mobx";
3
+ import Tool from "../tools/Tool"; // путь к Tool.ts
3
4
 
4
5
  class ToolState {
5
6
  tool: Tool | null = null;
package/src/tools/Text.ts CHANGED
@@ -7,7 +7,18 @@ export class TextTool extends Tool {
7
7
  }
8
8
 
9
9
  listen() {
10
- this.canvas.onclick = this.onClickHandler.bind(this);
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
- canvas: HTMLCanvasElement;
3
- ctx: CanvasRenderingContext2D;
4
-
5
- constructor(canvas: HTMLCanvasElement) {
6
- this.canvas = canvas;
7
- const context = canvas.getContext("2d");
8
- if (!context) throw new Error("Canvas context is null");
9
- this.ctx = context;
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
+ }