react-screenshots 0.5.21 → 0.6.0

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.
Files changed (139) hide show
  1. package/README.md +145 -145
  2. package/dist/electron.html +1 -0
  3. package/dist/index.html +1 -0
  4. package/dist/static/css/electron.7eee95c8.css +1 -0
  5. package/dist/static/css/index.7eee95c8.css +1 -0
  6. package/dist/static/image/image.1ca17a04.jpg +0 -0
  7. package/dist/static/js/589.5602a0fa.js +12 -0
  8. package/dist/static/js/electron.1c6ab61b.js +1 -0
  9. package/dist/static/js/index.fbe72af7.js +1 -0
  10. package/dist/static/js/lib-react.6d1aa3cf.js +2 -0
  11. package/dist/static/js/lib-react.6d1aa3cf.js.LICENSE.txt +39 -0
  12. package/lib/{types → Screenshots}/ScreenshotsBackground/getBoundsByPoints.d.ts +1 -1
  13. package/lib/Screenshots/ScreenshotsBackground/getBoundsByPoints.js +21 -0
  14. package/lib/Screenshots/ScreenshotsBackground/index.d.ts +3 -0
  15. package/lib/Screenshots/ScreenshotsBackground/index.js +100 -0
  16. package/lib/{types → Screenshots}/ScreenshotsButton/index.d.ts +2 -2
  17. package/lib/Screenshots/ScreenshotsButton/index.js +31 -0
  18. package/lib/{types → Screenshots}/ScreenshotsCanvas/getBoundsByPoints.d.ts +1 -1
  19. package/lib/Screenshots/ScreenshotsCanvas/getBoundsByPoints.js +33 -0
  20. package/lib/{types → Screenshots}/ScreenshotsCanvas/getPoints.d.ts +1 -1
  21. package/lib/Screenshots/ScreenshotsCanvas/getPoints.js +57 -0
  22. package/lib/{types → Screenshots}/ScreenshotsCanvas/index.d.ts +1 -2
  23. package/lib/Screenshots/ScreenshotsCanvas/index.js +199 -0
  24. package/lib/{types → Screenshots}/ScreenshotsCanvas/isPointInDraw.d.ts +1 -1
  25. package/lib/Screenshots/ScreenshotsCanvas/isPointInDraw.js +24 -0
  26. package/lib/{types → Screenshots}/ScreenshotsColor/index.d.ts +1 -2
  27. package/lib/Screenshots/ScreenshotsColor/index.js +30 -0
  28. package/lib/{types → Screenshots}/ScreenshotsContext.d.ts +4 -3
  29. package/lib/Screenshots/ScreenshotsContext.js +32 -0
  30. package/lib/{types → Screenshots}/ScreenshotsMagnifier/index.d.ts +1 -2
  31. package/lib/Screenshots/ScreenshotsMagnifier/index.js +99 -0
  32. package/lib/{types → Screenshots}/ScreenshotsOperations/index.d.ts +1 -1
  33. package/lib/Screenshots/ScreenshotsOperations/index.js +64 -0
  34. package/lib/{types → Screenshots}/ScreenshotsOption/index.d.ts +3 -3
  35. package/lib/Screenshots/ScreenshotsOption/index.js +94 -0
  36. package/lib/{types → Screenshots}/ScreenshotsSize/index.d.ts +1 -2
  37. package/lib/Screenshots/ScreenshotsSize/index.js +31 -0
  38. package/lib/{types → Screenshots}/ScreenshotsSizeColor/index.d.ts +2 -3
  39. package/lib/Screenshots/ScreenshotsSizeColor/index.js +21 -0
  40. package/lib/Screenshots/ScreenshotsTextarea/calculateNodeSize.js +69 -0
  41. package/lib/{types → Screenshots}/ScreenshotsTextarea/index.d.ts +2 -2
  42. package/lib/Screenshots/ScreenshotsTextarea/index.js +54 -0
  43. package/lib/{types → Screenshots}/composeImage.d.ts +1 -1
  44. package/lib/Screenshots/composeImage.js +27 -0
  45. package/lib/Screenshots/exports.d.ts +4 -0
  46. package/lib/Screenshots/exports.js +2 -0
  47. package/lib/{types → Screenshots}/hooks/useBounds.d.ts +1 -1
  48. package/lib/Screenshots/hooks/useBounds.js +25 -0
  49. package/lib/Screenshots/hooks/useCall.js +12 -0
  50. package/lib/{types → Screenshots}/hooks/useCanvasContextRef.d.ts +1 -1
  51. package/lib/Screenshots/hooks/useCanvasContextRef.js +6 -0
  52. package/lib/Screenshots/hooks/useCanvasMousedown.js +15 -0
  53. package/lib/Screenshots/hooks/useCanvasMousemove.js +15 -0
  54. package/lib/Screenshots/hooks/useCanvasMouseup.js +15 -0
  55. package/lib/Screenshots/hooks/useCursor.js +25 -0
  56. package/lib/Screenshots/hooks/useDispatcher.d.ts +2 -0
  57. package/lib/Screenshots/hooks/useDispatcher.js +7 -0
  58. package/lib/{types → Screenshots}/hooks/useDrawSelect.d.ts +1 -1
  59. package/lib/Screenshots/hooks/useDrawSelect.js +15 -0
  60. package/lib/{types → Screenshots}/hooks/useEmiter.d.ts +1 -1
  61. package/lib/Screenshots/hooks/useEmiter.js +41 -0
  62. package/lib/{types → Screenshots}/hooks/useHistory.d.ts +1 -1
  63. package/lib/Screenshots/hooks/useHistory.js +122 -0
  64. package/lib/{types → Screenshots}/hooks/useLang.d.ts +1 -1
  65. package/lib/Screenshots/hooks/useLang.js +6 -0
  66. package/lib/Screenshots/hooks/useOperation.js +25 -0
  67. package/lib/Screenshots/hooks/useReset.js +28 -0
  68. package/lib/Screenshots/hooks/useStore.d.ts +2 -0
  69. package/lib/Screenshots/hooks/useStore.js +7 -0
  70. package/lib/{types → Screenshots}/index.d.ts +2 -2
  71. package/lib/Screenshots/index.js +140 -0
  72. package/lib/{types → Screenshots}/operations/Arrow/draw.d.ts +2 -2
  73. package/lib/Screenshots/operations/Arrow/draw.js +51 -0
  74. package/lib/{types → Screenshots}/operations/Arrow/index.d.ts +1 -1
  75. package/lib/Screenshots/operations/Arrow/index.js +153 -0
  76. package/lib/{types → Screenshots}/operations/Brush/draw.d.ts +2 -2
  77. package/lib/Screenshots/operations/Brush/draw.js +31 -0
  78. package/lib/{types → Screenshots}/operations/Brush/index.d.ts +2 -2
  79. package/lib/Screenshots/operations/Brush/index.js +138 -0
  80. package/lib/{types → Screenshots}/operations/Cancel/index.d.ts +1 -1
  81. package/lib/Screenshots/operations/Cancel/index.js +24 -0
  82. package/lib/{types → Screenshots}/operations/Ellipse/draw.d.ts +2 -2
  83. package/lib/Screenshots/operations/Ellipse/draw.js +81 -0
  84. package/lib/{types → Screenshots}/operations/Ellipse/index.d.ts +1 -1
  85. package/lib/Screenshots/operations/Ellipse/index.js +185 -0
  86. package/lib/{types → Screenshots}/operations/Mosaic/index.d.ts +1 -1
  87. package/lib/Screenshots/operations/Mosaic/index.js +174 -0
  88. package/lib/{types → Screenshots}/operations/Ok/index.d.ts +1 -1
  89. package/lib/Screenshots/operations/Ok/index.js +48 -0
  90. package/lib/{types → Screenshots}/operations/Rectangle/draw.d.ts +2 -2
  91. package/lib/Screenshots/operations/Rectangle/draw.js +66 -0
  92. package/lib/{types → Screenshots}/operations/Rectangle/index.d.ts +1 -1
  93. package/lib/Screenshots/operations/Rectangle/index.js +186 -0
  94. package/lib/{types → Screenshots}/operations/Redo/index.d.ts +1 -1
  95. package/lib/Screenshots/operations/Redo/index.js +21 -0
  96. package/lib/{types → Screenshots}/operations/Save/index.d.ts +1 -1
  97. package/lib/Screenshots/operations/Save/index.js +48 -0
  98. package/lib/{types → Screenshots}/operations/Text/index.d.ts +1 -1
  99. package/lib/Screenshots/operations/Text/index.js +220 -0
  100. package/lib/{types → Screenshots}/operations/Undo/index.d.ts +1 -1
  101. package/lib/Screenshots/operations/Undo/index.js +21 -0
  102. package/lib/Screenshots/operations/index.js +27 -0
  103. package/lib/{types → Screenshots}/operations/utils.d.ts +1 -1
  104. package/lib/Screenshots/operations/utils.js +23 -0
  105. package/lib/{types → Screenshots}/types.d.ts +1 -1
  106. package/lib/Screenshots/types.js +6 -0
  107. package/lib/Screenshots/useGetLoadedImage.js +22 -0
  108. package/lib/Screenshots/zh_CN.js +16 -0
  109. package/lib/electron/app.d.ts +10 -0
  110. package/lib/electron/app.js +80 -0
  111. package/lib/electron/index.d.ts +1 -0
  112. package/lib/electron/index.js +7 -0
  113. package/lib/web/app.d.ts +3 -0
  114. package/lib/web/app.js +41 -0
  115. package/lib/web/index.d.ts +1 -0
  116. package/lib/web/index.js +7 -0
  117. package/package.json +35 -41
  118. package/LICENSE +0 -21
  119. package/electron/assets/electron-ed141e06.css +0 -1
  120. package/electron/assets/index-73f470f6.js +0 -53
  121. package/electron/electron.html +0 -14
  122. package/lib/react-screenshots.cjs.js +0 -14
  123. package/lib/react-screenshots.es.js +0 -1716
  124. package/lib/style.css +0 -1
  125. package/lib/types/ScreenshotsBackground/index.d.ts +0 -4
  126. package/lib/types/exports.d.ts +0 -3
  127. package/lib/types/hooks/useDispatcher.d.ts +0 -2
  128. package/lib/types/hooks/useStore.d.ts +0 -2
  129. /package/lib/{types → Screenshots}/ScreenshotsTextarea/calculateNodeSize.d.ts +0 -0
  130. /package/lib/{types → Screenshots}/hooks/useCall.d.ts +0 -0
  131. /package/lib/{types → Screenshots}/hooks/useCanvasMousedown.d.ts +0 -0
  132. /package/lib/{types → Screenshots}/hooks/useCanvasMousemove.d.ts +0 -0
  133. /package/lib/{types → Screenshots}/hooks/useCanvasMouseup.d.ts +0 -0
  134. /package/lib/{types → Screenshots}/hooks/useCursor.d.ts +0 -0
  135. /package/lib/{types → Screenshots}/hooks/useOperation.d.ts +0 -0
  136. /package/lib/{types → Screenshots}/hooks/useReset.d.ts +0 -0
  137. /package/lib/{types → Screenshots}/operations/index.d.ts +0 -0
  138. /package/lib/{types → Screenshots}/useGetLoadedImage.d.ts +0 -0
  139. /package/lib/{types → Screenshots}/zh_CN.d.ts +0 -0
@@ -1,5 +1,5 @@
1
- import { RectangleData, RectangleEditData } from '.';
2
- import { HistoryItemSource } from '../../types';
1
+ import type { RectangleData, RectangleEditData } from '.';
2
+ import type { HistoryItemSource } from '../../types';
3
3
  export declare function getEditedRectangleData(action: HistoryItemSource<RectangleData, RectangleEditData>): {
4
4
  x1: number;
5
5
  x2: number;
@@ -0,0 +1,66 @@
1
+ import { RectangleEditType } from "./index.js";
2
+ import { drawDragCircle } from "../utils.js";
3
+ function getEditedRectangleData(action) {
4
+ let { x1, y1, x2, y2 } = action.data;
5
+ action.editHistory.forEach(({ data })=>{
6
+ const x = data.x2 - data.x1;
7
+ const y = data.y2 - data.y1;
8
+ if (data.type === RectangleEditType.Move) {
9
+ x1 += x;
10
+ y1 += y;
11
+ x2 += x;
12
+ y2 += y;
13
+ } else if (data.type === RectangleEditType.ResizeTop) y1 += y;
14
+ else if (data.type === RectangleEditType.ResizeRightTop) {
15
+ x2 += x;
16
+ y1 += y;
17
+ } else if (data.type === RectangleEditType.ResizeRight) x2 += x;
18
+ else if (data.type === RectangleEditType.ResizeRightBottom) {
19
+ x2 += x;
20
+ y2 += y;
21
+ } else if (data.type === RectangleEditType.ResizeBottom) y2 += y;
22
+ else if (data.type === RectangleEditType.ResizeLeftBottom) {
23
+ x1 += x;
24
+ y2 += y;
25
+ } else if (data.type === RectangleEditType.ResizeLeft) x1 += x;
26
+ else if (data.type === RectangleEditType.ResizeLeftTop) {
27
+ x1 += x;
28
+ y1 += y;
29
+ }
30
+ });
31
+ return {
32
+ ...action.data,
33
+ x1,
34
+ x2,
35
+ y1,
36
+ y2
37
+ };
38
+ }
39
+ function draw(ctx, action) {
40
+ const { size, color, x1, y1, x2, y2 } = getEditedRectangleData(action);
41
+ ctx.lineCap = 'butt';
42
+ ctx.lineJoin = 'miter';
43
+ ctx.lineWidth = size;
44
+ ctx.strokeStyle = color;
45
+ ctx.beginPath();
46
+ ctx.moveTo(x1, y1);
47
+ ctx.lineTo(x2, y1);
48
+ ctx.lineTo(x2, y2);
49
+ ctx.lineTo(x1, y2);
50
+ ctx.closePath();
51
+ ctx.stroke();
52
+ if (action.isSelected) {
53
+ ctx.lineWidth = 1;
54
+ ctx.strokeStyle = '#000000';
55
+ ctx.fillStyle = '#ffffff';
56
+ drawDragCircle(ctx, (x1 + x2) / 2, y1);
57
+ drawDragCircle(ctx, x2, y1);
58
+ drawDragCircle(ctx, x2, (y1 + y2) / 2);
59
+ drawDragCircle(ctx, x2, y2);
60
+ drawDragCircle(ctx, (x1 + x2) / 2, y2);
61
+ drawDragCircle(ctx, x1, y2);
62
+ drawDragCircle(ctx, x1, (y1 + y2) / 2);
63
+ drawDragCircle(ctx, x1, y1);
64
+ }
65
+ }
66
+ export { draw as default, getEditedRectangleData };
@@ -1,4 +1,4 @@
1
- import { ReactElement } from 'react';
1
+ import type { ReactElement } from 'react';
2
2
  export interface RectangleData {
3
3
  size: number;
4
4
  color: string;
@@ -0,0 +1,186 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback, useRef, useState } from "react";
3
+ import useCanvasContextRef from "../../hooks/useCanvasContextRef.js";
4
+ import useCanvasMousedown from "../../hooks/useCanvasMousedown.js";
5
+ import useCanvasMousemove from "../../hooks/useCanvasMousemove.js";
6
+ import useCanvasMouseup from "../../hooks/useCanvasMouseup.js";
7
+ import useCursor from "../../hooks/useCursor.js";
8
+ import useDrawSelect from "../../hooks/useDrawSelect.js";
9
+ import useHistory from "../../hooks/useHistory.js";
10
+ import useLang from "../../hooks/useLang.js";
11
+ import useOperation from "../../hooks/useOperation.js";
12
+ import ScreenshotsButton from "../../ScreenshotsButton/index.js";
13
+ import ScreenshotsSizeColor from "../../ScreenshotsSizeColor/index.js";
14
+ import { HistoryItemType } from "../../types.js";
15
+ import { isHit, isHitCircle } from "../utils.js";
16
+ import draw, { getEditedRectangleData } from "./draw.js";
17
+ var Rectangle_RectangleEditType = /*#__PURE__*/ function(RectangleEditType) {
18
+ RectangleEditType[RectangleEditType["Move"] = 0] = "Move";
19
+ RectangleEditType[RectangleEditType["ResizeTop"] = 1] = "ResizeTop";
20
+ RectangleEditType[RectangleEditType["ResizeRightTop"] = 2] = "ResizeRightTop";
21
+ RectangleEditType[RectangleEditType["ResizeRight"] = 3] = "ResizeRight";
22
+ RectangleEditType[RectangleEditType["ResizeRightBottom"] = 4] = "ResizeRightBottom";
23
+ RectangleEditType[RectangleEditType["ResizeBottom"] = 5] = "ResizeBottom";
24
+ RectangleEditType[RectangleEditType["ResizeLeftBottom"] = 6] = "ResizeLeftBottom";
25
+ RectangleEditType[RectangleEditType["ResizeLeft"] = 7] = "ResizeLeft";
26
+ RectangleEditType[RectangleEditType["ResizeLeftTop"] = 8] = "ResizeLeftTop";
27
+ return RectangleEditType;
28
+ }({});
29
+ function Rectangle() {
30
+ const lang = useLang();
31
+ const [history, historyDispatcher] = useHistory();
32
+ const [operation, operationDispatcher] = useOperation();
33
+ const [, cursorDispatcher] = useCursor();
34
+ const canvasContextRef = useCanvasContextRef();
35
+ const [size, setSize] = useState(3);
36
+ const [color, setColor] = useState('#ee5126');
37
+ const rectangleRef = useRef(null);
38
+ const rectangleEditRef = useRef(null);
39
+ const checked = 'Rectangle' === operation;
40
+ const selectRectangle = useCallback(()=>{
41
+ operationDispatcher.set('Rectangle');
42
+ cursorDispatcher.set('crosshair');
43
+ }, [
44
+ operationDispatcher,
45
+ cursorDispatcher
46
+ ]);
47
+ const onSelectRectangle = useCallback(()=>{
48
+ if (checked) return;
49
+ selectRectangle();
50
+ historyDispatcher.clearSelect();
51
+ }, [
52
+ checked,
53
+ selectRectangle,
54
+ historyDispatcher
55
+ ]);
56
+ const onDrawSelect = useCallback((action, e)=>{
57
+ if ('Rectangle' !== action.name || !canvasContextRef.current) return;
58
+ const source = action;
59
+ selectRectangle();
60
+ const { x1, y1, x2, y2 } = getEditedRectangleData(source);
61
+ let type = 0;
62
+ if (isHitCircle(canvasContextRef.current.canvas, e, {
63
+ x: (x1 + x2) / 2,
64
+ y: y1
65
+ })) type = 1;
66
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
67
+ x: x2,
68
+ y: y1
69
+ })) type = 2;
70
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
71
+ x: x2,
72
+ y: (y1 + y2) / 2
73
+ })) type = 3;
74
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
75
+ x: x2,
76
+ y: y2
77
+ })) type = 4;
78
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
79
+ x: (x1 + x2) / 2,
80
+ y: y2
81
+ })) type = 5;
82
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
83
+ x: x1,
84
+ y: y2
85
+ })) type = 6;
86
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
87
+ x: x1,
88
+ y: (y1 + y2) / 2
89
+ })) type = 7;
90
+ else if (isHitCircle(canvasContextRef.current.canvas, e, {
91
+ x: x1,
92
+ y: y1
93
+ })) type = 8;
94
+ rectangleEditRef.current = {
95
+ type: HistoryItemType.Edit,
96
+ data: {
97
+ type,
98
+ x1: e.clientX,
99
+ y1: e.clientY,
100
+ x2: e.clientX,
101
+ y2: e.clientY
102
+ },
103
+ source: action
104
+ };
105
+ historyDispatcher.select(action);
106
+ }, [
107
+ canvasContextRef,
108
+ selectRectangle,
109
+ historyDispatcher
110
+ ]);
111
+ const onMousedown = useCallback((e)=>{
112
+ if (!checked || !canvasContextRef.current || rectangleRef.current) return;
113
+ const { left, top } = canvasContextRef.current.canvas.getBoundingClientRect();
114
+ const x = e.clientX - left;
115
+ const y = e.clientY - top;
116
+ rectangleRef.current = {
117
+ name: 'Rectangle',
118
+ type: HistoryItemType.Source,
119
+ data: {
120
+ size,
121
+ color,
122
+ x1: x,
123
+ y1: y,
124
+ x2: x,
125
+ y2: y
126
+ },
127
+ editHistory: [],
128
+ draw: draw,
129
+ isHit: isHit
130
+ };
131
+ }, [
132
+ checked,
133
+ size,
134
+ color,
135
+ canvasContextRef
136
+ ]);
137
+ const onMousemove = useCallback((e)=>{
138
+ if (!checked || !canvasContextRef.current) return;
139
+ if (rectangleEditRef.current) {
140
+ rectangleEditRef.current.data.x2 = e.clientX;
141
+ rectangleEditRef.current.data.y2 = e.clientY;
142
+ if (history.top !== rectangleEditRef.current) {
143
+ rectangleEditRef.current.source.editHistory.push(rectangleEditRef.current);
144
+ historyDispatcher.push(rectangleEditRef.current);
145
+ } else historyDispatcher.set(history);
146
+ } else if (rectangleRef.current) {
147
+ const { left, top } = canvasContextRef.current.canvas.getBoundingClientRect();
148
+ const rectangleData = rectangleRef.current.data;
149
+ rectangleData.x2 = e.clientX - left;
150
+ rectangleData.y2 = e.clientY - top;
151
+ if (history.top !== rectangleRef.current) historyDispatcher.push(rectangleRef.current);
152
+ else historyDispatcher.set(history);
153
+ }
154
+ }, [
155
+ checked,
156
+ canvasContextRef,
157
+ history,
158
+ historyDispatcher
159
+ ]);
160
+ const onMouseup = useCallback(()=>{
161
+ if (!checked) return;
162
+ if (rectangleRef.current) historyDispatcher.clearSelect();
163
+ rectangleRef.current = null;
164
+ rectangleEditRef.current = null;
165
+ }, [
166
+ checked,
167
+ historyDispatcher
168
+ ]);
169
+ useDrawSelect(onDrawSelect);
170
+ useCanvasMousedown(onMousedown);
171
+ useCanvasMousemove(onMousemove);
172
+ useCanvasMouseup(onMouseup);
173
+ return /*#__PURE__*/ jsx(ScreenshotsButton, {
174
+ title: lang.operation_rectangle_title,
175
+ icon: "icon-rectangle",
176
+ checked: checked,
177
+ onClick: onSelectRectangle,
178
+ option: /*#__PURE__*/ jsx(ScreenshotsSizeColor, {
179
+ size: size,
180
+ color: color,
181
+ onSizeChange: setSize,
182
+ onColorChange: setColor
183
+ })
184
+ });
185
+ }
186
+ export { Rectangle_RectangleEditType as RectangleEditType, Rectangle as default };
@@ -1,2 +1,2 @@
1
- import { ReactElement } from 'react';
1
+ import type { ReactElement } from 'react';
2
2
  export default function Redo(): ReactElement;
@@ -0,0 +1,21 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback } from "react";
3
+ import ScreenshotsButton from "../../ScreenshotsButton/index.js";
4
+ import useHistory from "../../hooks/useHistory.js";
5
+ import useLang from "../../hooks/useLang.js";
6
+ function Redo() {
7
+ const lang = useLang();
8
+ const [history, historyDispatcher] = useHistory();
9
+ const onClick = useCallback(()=>{
10
+ historyDispatcher.redo();
11
+ }, [
12
+ historyDispatcher
13
+ ]);
14
+ return /*#__PURE__*/ jsx(ScreenshotsButton, {
15
+ title: lang.operation_redo_title,
16
+ icon: "icon-redo",
17
+ disabled: !history.stack.length || history.stack.length - 1 === history.index,
18
+ onClick: onClick
19
+ });
20
+ }
21
+ export { Redo as default };
@@ -1,2 +1,2 @@
1
- import { ReactElement } from 'react';
1
+ import type { ReactElement } from 'react';
2
2
  export default function Save(): ReactElement;
@@ -0,0 +1,48 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback } from "react";
3
+ import composeImage from "../../composeImage.js";
4
+ import useStore from "../../hooks/useStore.js";
5
+ import useCall from "../../hooks/useCall.js";
6
+ import useCanvasContextRef from "../../hooks/useCanvasContextRef.js";
7
+ import useHistory from "../../hooks/useHistory.js";
8
+ import useReset from "../../hooks/useReset.js";
9
+ import ScreenshotsButton from "../../ScreenshotsButton/index.js";
10
+ function Save() {
11
+ const { image, width, height, history, bounds, lang } = useStore();
12
+ const canvasContextRef = useCanvasContextRef();
13
+ const [, historyDispatcher] = useHistory();
14
+ const call = useCall();
15
+ const reset = useReset();
16
+ const onClick = useCallback(()=>{
17
+ historyDispatcher.clearSelect();
18
+ setTimeout(()=>{
19
+ if (!canvasContextRef.current || !image || !bounds) return;
20
+ composeImage({
21
+ image,
22
+ width,
23
+ height,
24
+ history,
25
+ bounds
26
+ }).then((blob)=>{
27
+ call('onSave', blob, bounds);
28
+ reset();
29
+ });
30
+ });
31
+ }, [
32
+ canvasContextRef,
33
+ historyDispatcher,
34
+ image,
35
+ width,
36
+ height,
37
+ history,
38
+ bounds,
39
+ call,
40
+ reset
41
+ ]);
42
+ return /*#__PURE__*/ jsx(ScreenshotsButton, {
43
+ title: lang.operation_save_title,
44
+ icon: "icon-save",
45
+ onClick: onClick
46
+ });
47
+ }
48
+ export { Save as default };
@@ -1,4 +1,4 @@
1
- import { ReactElement } from 'react';
1
+ import type { ReactElement } from 'react';
2
2
  export interface TextData {
3
3
  size: number;
4
4
  color: string;
@@ -0,0 +1,220 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useRef, useState } from "react";
3
+ import useCanvasContextRef from "../../hooks/useCanvasContextRef.js";
4
+ import useCanvasMousedown from "../../hooks/useCanvasMousedown.js";
5
+ import useCursor from "../../hooks/useCursor.js";
6
+ import useHistory from "../../hooks/useHistory.js";
7
+ import useOperation from "../../hooks/useOperation.js";
8
+ import ScreenshotsButton from "../../ScreenshotsButton/index.js";
9
+ import ScreenshotsSizeColor from "../../ScreenshotsSizeColor/index.js";
10
+ import { HistoryItemType } from "../../types.js";
11
+ import ScreenshotsTextarea from "../../ScreenshotsTextarea/index.js";
12
+ import useBounds from "../../hooks/useBounds.js";
13
+ import useDrawSelect from "../../hooks/useDrawSelect.js";
14
+ import useCanvasMousemove from "../../hooks/useCanvasMousemove.js";
15
+ import useCanvasMouseup from "../../hooks/useCanvasMouseup.js";
16
+ import useLang from "../../hooks/useLang.js";
17
+ const sizes = {
18
+ 3: 18,
19
+ 6: 32,
20
+ 9: 46
21
+ };
22
+ function draw(ctx, action) {
23
+ const { size, color, fontFamily, x, y, text } = action.data;
24
+ ctx.fillStyle = color;
25
+ ctx.textAlign = 'left';
26
+ ctx.textBaseline = 'top';
27
+ ctx.font = `${size}px ${fontFamily}`;
28
+ const distance = action.editHistory.reduce((distance, { data })=>({
29
+ x: distance.x + data.x2 - data.x1,
30
+ y: distance.y + data.y2 - data.y1
31
+ }), {
32
+ x: 0,
33
+ y: 0
34
+ });
35
+ text.split('\n').forEach((item, index)=>{
36
+ ctx.fillText(item, x + distance.x, y + distance.y + index * size);
37
+ });
38
+ }
39
+ function isHit(ctx, action, point) {
40
+ ctx.textAlign = 'left';
41
+ ctx.textBaseline = 'top';
42
+ ctx.font = `${action.data.size}px ${action.data.fontFamily}`;
43
+ let width = 0;
44
+ let height = 0;
45
+ action.data.text.split('\n').forEach((item)=>{
46
+ const measured = ctx.measureText(item);
47
+ if (width < measured.width) width = measured.width;
48
+ height += action.data.size;
49
+ });
50
+ const { x, y } = action.editHistory.reduce((distance, { data })=>({
51
+ x: distance.x + data.x2 - data.x1,
52
+ y: distance.y + data.y2 - data.y1
53
+ }), {
54
+ x: 0,
55
+ y: 0
56
+ });
57
+ const left = action.data.x + x;
58
+ const top = action.data.y + y;
59
+ const right = left + width;
60
+ const bottom = top + height;
61
+ return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
62
+ }
63
+ function Text() {
64
+ const lang = useLang();
65
+ const [history, historyDispatcher] = useHistory();
66
+ const [bounds] = useBounds();
67
+ const [operation, operationDispatcher] = useOperation();
68
+ const [, cursorDispatcher] = useCursor();
69
+ const canvasContextRef = useCanvasContextRef();
70
+ const [size, setSize] = useState(3);
71
+ const [color, setColor] = useState('#ee5126');
72
+ const textRef = useRef(null);
73
+ const textEditRef = useRef(null);
74
+ const [textareaBounds, setTextareaBounds] = useState(null);
75
+ const [text, setText] = useState('');
76
+ const checked = 'Text' === operation;
77
+ const selectText = useCallback(()=>{
78
+ operationDispatcher.set('Text');
79
+ cursorDispatcher.set('default');
80
+ }, [
81
+ operationDispatcher,
82
+ cursorDispatcher
83
+ ]);
84
+ const onSelectText = useCallback(()=>{
85
+ if (checked) return;
86
+ selectText();
87
+ historyDispatcher.clearSelect();
88
+ }, [
89
+ checked,
90
+ selectText,
91
+ historyDispatcher
92
+ ]);
93
+ const onSizeChange = useCallback((size)=>{
94
+ if (textRef.current) textRef.current.data.size = sizes[size];
95
+ setSize(size);
96
+ }, []);
97
+ const onColorChange = useCallback((color)=>{
98
+ if (textRef.current) textRef.current.data.color = color;
99
+ setColor(color);
100
+ }, []);
101
+ const onTextareaChange = useCallback((value)=>{
102
+ setText(value);
103
+ if (checked && textRef.current) textRef.current.data.text = value;
104
+ }, [
105
+ checked
106
+ ]);
107
+ const onTextareaBlur = useCallback(()=>{
108
+ if (textRef.current && textRef.current.data.text) historyDispatcher.push(textRef.current);
109
+ textRef.current = null;
110
+ setText('');
111
+ setTextareaBounds(null);
112
+ }, [
113
+ historyDispatcher
114
+ ]);
115
+ const onDrawSelect = useCallback((action, e)=>{
116
+ if ('Text' !== action.name) return;
117
+ selectText();
118
+ textEditRef.current = {
119
+ type: HistoryItemType.Edit,
120
+ data: {
121
+ x1: e.clientX,
122
+ y1: e.clientY,
123
+ x2: e.clientX,
124
+ y2: e.clientY
125
+ },
126
+ source: action
127
+ };
128
+ historyDispatcher.select(action);
129
+ }, [
130
+ selectText,
131
+ historyDispatcher
132
+ ]);
133
+ const onMousedown = useCallback((e)=>{
134
+ if (!checked || !canvasContextRef.current || textRef.current || !bounds) return;
135
+ const { left, top } = canvasContextRef.current.canvas.getBoundingClientRect();
136
+ const fontFamily = window.getComputedStyle(canvasContextRef.current.canvas).fontFamily;
137
+ const x = e.clientX - left;
138
+ const y = e.clientY - top;
139
+ textRef.current = {
140
+ name: 'Text',
141
+ type: HistoryItemType.Source,
142
+ data: {
143
+ size: sizes[size],
144
+ color,
145
+ fontFamily,
146
+ x,
147
+ y,
148
+ text: ''
149
+ },
150
+ editHistory: [],
151
+ draw,
152
+ isHit
153
+ };
154
+ setTextareaBounds({
155
+ x: e.clientX,
156
+ y: e.clientY,
157
+ maxWidth: bounds.width - x,
158
+ maxHeight: bounds.height - y
159
+ });
160
+ }, [
161
+ checked,
162
+ size,
163
+ color,
164
+ bounds,
165
+ canvasContextRef
166
+ ]);
167
+ const onMousemove = useCallback((e)=>{
168
+ if (!checked) return;
169
+ if (textEditRef.current) {
170
+ textEditRef.current.data.x2 = e.clientX;
171
+ textEditRef.current.data.y2 = e.clientY;
172
+ if (history.top !== textEditRef.current) {
173
+ textEditRef.current.source.editHistory.push(textEditRef.current);
174
+ historyDispatcher.push(textEditRef.current);
175
+ } else historyDispatcher.set(history);
176
+ }
177
+ }, [
178
+ checked,
179
+ history,
180
+ historyDispatcher
181
+ ]);
182
+ const onMouseup = useCallback(()=>{
183
+ if (!checked) return;
184
+ textEditRef.current = null;
185
+ }, [
186
+ checked
187
+ ]);
188
+ useDrawSelect(onDrawSelect);
189
+ useCanvasMousedown(onMousedown);
190
+ useCanvasMousemove(onMousemove);
191
+ useCanvasMouseup(onMouseup);
192
+ return /*#__PURE__*/ jsxs(Fragment, {
193
+ children: [
194
+ /*#__PURE__*/ jsx(ScreenshotsButton, {
195
+ title: lang.operation_text_title,
196
+ icon: "icon-text",
197
+ checked: checked,
198
+ onClick: onSelectText,
199
+ option: /*#__PURE__*/ jsx(ScreenshotsSizeColor, {
200
+ size: size,
201
+ color: color,
202
+ onSizeChange: onSizeChange,
203
+ onColorChange: onColorChange
204
+ })
205
+ }),
206
+ checked && textareaBounds && /*#__PURE__*/ jsx(ScreenshotsTextarea, {
207
+ x: textareaBounds.x,
208
+ y: textareaBounds.y,
209
+ maxWidth: textareaBounds.maxWidth,
210
+ maxHeight: textareaBounds.maxHeight,
211
+ size: sizes[size],
212
+ color: color,
213
+ value: text,
214
+ onChange: onTextareaChange,
215
+ onBlur: onTextareaBlur
216
+ })
217
+ ]
218
+ });
219
+ }
220
+ export { Text as default };
@@ -1,2 +1,2 @@
1
- import { ReactElement } from 'react';
1
+ import type { ReactElement } from 'react';
2
2
  export default function Undo(): ReactElement;
@@ -0,0 +1,21 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback } from "react";
3
+ import ScreenshotsButton from "../../ScreenshotsButton/index.js";
4
+ import useHistory from "../../hooks/useHistory.js";
5
+ import useLang from "../../hooks/useLang.js";
6
+ function Undo() {
7
+ const lang = useLang();
8
+ const [history, historyDispatcher] = useHistory();
9
+ const onClick = useCallback(()=>{
10
+ historyDispatcher.undo();
11
+ }, [
12
+ historyDispatcher
13
+ ]);
14
+ return /*#__PURE__*/ jsx(ScreenshotsButton, {
15
+ title: lang.operation_undo_title,
16
+ icon: "icon-undo",
17
+ disabled: -1 === history.index,
18
+ onClick: onClick
19
+ });
20
+ }
21
+ export { Undo as default };
@@ -0,0 +1,27 @@
1
+ import Ok from "./Ok/index.js";
2
+ import Cancel from "./Cancel/index.js";
3
+ import Save from "./Save/index.js";
4
+ import Redo from "./Redo/index.js";
5
+ import Undo from "./Undo/index.js";
6
+ import Mosaic from "./Mosaic/index.js";
7
+ import Text from "./Text/index.js";
8
+ import Brush from "./Brush/index.js";
9
+ import Arrow from "./Arrow/index.js";
10
+ import Ellipse from "./Ellipse/index.js";
11
+ import Rectangle from "./Rectangle/index.js";
12
+ const operations = [
13
+ Rectangle,
14
+ Ellipse,
15
+ Arrow,
16
+ Brush,
17
+ Text,
18
+ Mosaic,
19
+ '|',
20
+ Undo,
21
+ Redo,
22
+ '|',
23
+ Save,
24
+ Cancel,
25
+ Ok
26
+ ];
27
+ export { operations as default };
@@ -1,4 +1,4 @@
1
- import { HistoryItemSource, Point } from '../types';
1
+ import type { HistoryItemSource, Point } from '../types';
2
2
  export declare function drawDragCircle(ctx: CanvasRenderingContext2D, x: number, y: number): void;
3
3
  export declare function isHit<S, E>(ctx: CanvasRenderingContext2D, action: HistoryItemSource<S, E>, point: Point): boolean;
4
4
  export declare function isHitCircle(canvas: HTMLCanvasElement | null, e: MouseEvent, point: Point): boolean;
@@ -0,0 +1,23 @@
1
+ const CircleRadius = 4;
2
+ function drawDragCircle(ctx, x, y) {
3
+ ctx.lineWidth = 1;
4
+ ctx.strokeStyle = '#000000';
5
+ ctx.fillStyle = '#ffffff';
6
+ ctx.beginPath();
7
+ ctx.arc(x, y, CircleRadius, 0, 2 * Math.PI);
8
+ ctx.fill();
9
+ ctx.stroke();
10
+ }
11
+ function isHit(ctx, action, point) {
12
+ action.draw(ctx, action);
13
+ const { data } = ctx.getImageData(point.x, point.y, 1, 1);
14
+ return data.some((val)=>0 !== val);
15
+ }
16
+ function isHitCircle(canvas, e, point) {
17
+ if (!canvas) return false;
18
+ const { left, top } = canvas.getBoundingClientRect();
19
+ const x = e.clientX - left;
20
+ const y = e.clientY - top;
21
+ return (point.x - x) ** 2 + (point.y - y) ** 2 < CircleRadius ** 2;
22
+ }
23
+ export { drawDragCircle, isHit, isHitCircle };
@@ -1,4 +1,4 @@
1
- import { MutableRefObject } from 'react';
1
+ import type { MutableRefObject } from 'react';
2
2
  export type CanvasContextRef = MutableRefObject<CanvasRenderingContext2D | null>;
3
3
  export type EmiterListener = (...args: any) => unknown;
4
4
  export type Emiter = Record<string, EmiterListener[]>;
@@ -0,0 +1,6 @@
1
+ var types_HistoryItemType = /*#__PURE__*/ function(HistoryItemType) {
2
+ HistoryItemType[HistoryItemType["Edit"] = 0] = "Edit";
3
+ HistoryItemType[HistoryItemType["Source"] = 1] = "Source";
4
+ return HistoryItemType;
5
+ }({});
6
+ export { types_HistoryItemType as HistoryItemType };