react-screenshots 0.5.10 → 0.5.16

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 (64) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +145 -145
  3. package/package.json +2 -2
  4. package/electron/assets/index.95e77ee2.css +0 -1
  5. package/electron/assets/index.c68b977f.js +0 -14
  6. package/electron/assets/vendor.e3c417b2.js +0 -209
  7. package/electron/electron.html +0 -15
  8. package/lib/react-screenshots.cjs.js +0 -14
  9. package/lib/react-screenshots.es.js +0 -3168
  10. package/lib/style.css +0 -1
  11. package/lib/types/ScreenshotsBackground/getBoundsByPoints.d.ts +0 -2
  12. package/lib/types/ScreenshotsBackground/index.d.ts +0 -4
  13. package/lib/types/ScreenshotsButton/index.d.ts +0 -12
  14. package/lib/types/ScreenshotsCanvas/getBoundsByPoints.d.ts +0 -2
  15. package/lib/types/ScreenshotsCanvas/getPoints.d.ts +0 -2
  16. package/lib/types/ScreenshotsCanvas/index.d.ts +0 -15
  17. package/lib/types/ScreenshotsCanvas/isPointInDraw.d.ts +0 -2
  18. package/lib/types/ScreenshotsColor/index.d.ts +0 -8
  19. package/lib/types/ScreenshotsContext.d.ts +0 -29
  20. package/lib/types/ScreenshotsMagnifier/index.d.ts +0 -8
  21. package/lib/types/ScreenshotsOperations/index.d.ts +0 -6
  22. package/lib/types/ScreenshotsOption/index.d.ts +0 -15
  23. package/lib/types/ScreenshotsSize/index.d.ts +0 -8
  24. package/lib/types/ScreenshotsSizeColor/index.d.ts +0 -10
  25. package/lib/types/ScreenshotsTextarea/calculateNodeSize.d.ts +0 -17
  26. package/lib/types/ScreenshotsTextarea/index.d.ts +0 -15
  27. package/lib/types/composeImage.d.ts +0 -10
  28. package/lib/types/exports.d.ts +0 -3
  29. package/lib/types/hooks/useBounds.d.ts +0 -7
  30. package/lib/types/hooks/useCall.d.ts +0 -2
  31. package/lib/types/hooks/useCanvasContextRef.d.ts +0 -2
  32. package/lib/types/hooks/useCanvasMousedown.d.ts +0 -1
  33. package/lib/types/hooks/useCanvasMousemove.d.ts +0 -1
  34. package/lib/types/hooks/useCanvasMouseup.d.ts +0 -1
  35. package/lib/types/hooks/useCursor.d.ts +0 -6
  36. package/lib/types/hooks/useDispatcher.d.ts +0 -2
  37. package/lib/types/hooks/useDrawSelect.d.ts +0 -2
  38. package/lib/types/hooks/useEmiter.d.ts +0 -8
  39. package/lib/types/hooks/useHistory.d.ts +0 -16
  40. package/lib/types/hooks/useLang.d.ts +0 -2
  41. package/lib/types/hooks/useOperation.d.ts +0 -6
  42. package/lib/types/hooks/useReset.d.ts +0 -2
  43. package/lib/types/hooks/useStore.d.ts +0 -2
  44. package/lib/types/index.d.ts +0 -13
  45. package/lib/types/operations/Arrow/draw.d.ts +0 -11
  46. package/lib/types/operations/Arrow/index.d.ts +0 -22
  47. package/lib/types/operations/Brush/draw.d.ts +0 -3
  48. package/lib/types/operations/Brush/index.d.ts +0 -14
  49. package/lib/types/operations/Cancel/index.d.ts +0 -2
  50. package/lib/types/operations/Ellipse/draw.d.ts +0 -11
  51. package/lib/types/operations/Ellipse/index.d.ts +0 -28
  52. package/lib/types/operations/Mosaic/index.d.ts +0 -11
  53. package/lib/types/operations/Ok/index.d.ts +0 -2
  54. package/lib/types/operations/Rectangle/draw.d.ts +0 -11
  55. package/lib/types/operations/Rectangle/index.d.ts +0 -28
  56. package/lib/types/operations/Redo/index.d.ts +0 -2
  57. package/lib/types/operations/Save/index.d.ts +0 -2
  58. package/lib/types/operations/Text/index.d.ts +0 -22
  59. package/lib/types/operations/Undo/index.d.ts +0 -2
  60. package/lib/types/operations/index.d.ts +0 -3
  61. package/lib/types/operations/utils.d.ts +0 -4
  62. package/lib/types/types.d.ts +0 -39
  63. package/lib/types/useGetLoadedImage.d.ts +0 -1
  64. package/lib/types/zh_CN.d.ts +0 -16
@@ -1,3168 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __objRest = (source, exclude) => {
21
- var target = {};
22
- for (var prop in source)
23
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
- target[prop] = source[prop];
25
- if (source != null && __getOwnPropSymbols)
26
- for (var prop of __getOwnPropSymbols(source)) {
27
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
- target[prop] = source[prop];
29
- }
30
- return target;
31
- };
32
- import React, { useContext, useCallback, memo, useState, useRef, useLayoutEffect, useEffect, forwardRef, useImperativeHandle, cloneElement } from "react";
33
- import { createPortal } from "react-dom";
34
- var HistoryItemType;
35
- (function(HistoryItemType2) {
36
- HistoryItemType2[HistoryItemType2["Edit"] = 0] = "Edit";
37
- HistoryItemType2[HistoryItemType2["Source"] = 1] = "Source";
38
- })(HistoryItemType || (HistoryItemType = {}));
39
- function composeImage({ image, width, height, history, bounds }) {
40
- return new Promise((resolve, reject) => {
41
- const $canvas = document.createElement("canvas");
42
- const targetWidth = bounds.width * window.devicePixelRatio;
43
- const targetHeight = bounds.height * window.devicePixelRatio;
44
- $canvas.width = targetWidth;
45
- $canvas.height = targetHeight;
46
- const ctx = $canvas.getContext("2d");
47
- if (!ctx) {
48
- return reject(new Error("convert image to blob fail"));
49
- }
50
- const rx = image.naturalWidth / width;
51
- const ry = image.naturalHeight / height;
52
- ctx.imageSmoothingEnabled = true;
53
- ctx.imageSmoothingQuality = "low";
54
- ctx.setTransform(window.devicePixelRatio, 0, 0, window.devicePixelRatio, 0, 0);
55
- ctx.clearRect(0, 0, bounds.width, bounds.height);
56
- ctx.drawImage(image, bounds.x * rx, bounds.y * ry, bounds.width * rx, bounds.height * ry, 0, 0, bounds.width, bounds.height);
57
- history.stack.slice(0, history.index + 1).forEach((item) => {
58
- if (item.type === HistoryItemType.Source) {
59
- item.draw(ctx, item);
60
- }
61
- });
62
- $canvas.toBlob((blob) => {
63
- if (!blob) {
64
- return reject(new Error("canvas toBlob fail"));
65
- }
66
- resolve(blob);
67
- }, "image/png");
68
- });
69
- }
70
- var iconfont = "";
71
- var screenshots = "";
72
- const zhCN = {
73
- magnifier_position_label: "\u5750\u6807",
74
- operation_ok_title: "\u786E\u5B9A",
75
- operation_cancel_title: "\u53D6\u6D88",
76
- operation_save_title: "\u4FDD\u5B58",
77
- operation_redo_title: "\u91CD\u505A",
78
- operation_undo_title: "\u64A4\u9500",
79
- operation_mosaic_title: "\u9A6C\u8D5B\u514B",
80
- operation_text_title: "\u6587\u672C",
81
- operation_brush_title: "\u753B\u7B14",
82
- operation_arrow_title: "\u7BAD\u5934",
83
- operation_ellipse_title: "\u692D\u5706",
84
- operation_rectangle_title: "\u77E9\u5F62"
85
- };
86
- var ScreenshotsContext = React.createContext({
87
- store: {
88
- url: void 0,
89
- image: null,
90
- width: 0,
91
- height: 0,
92
- lang: zhCN,
93
- emiterRef: { current: {} },
94
- canvasContextRef: { current: null },
95
- history: {
96
- index: -1,
97
- stack: []
98
- },
99
- bounds: null,
100
- cursor: "move",
101
- operation: void 0
102
- },
103
- dispatcher: {
104
- call: void 0,
105
- setHistory: void 0,
106
- setBounds: void 0,
107
- setCursor: void 0,
108
- setOperation: void 0
109
- }
110
- });
111
- function useDispatcher() {
112
- const { dispatcher } = useContext(ScreenshotsContext);
113
- return dispatcher;
114
- }
115
- function useStore() {
116
- const { store } = useContext(ScreenshotsContext);
117
- return store;
118
- }
119
- function useBounds() {
120
- const { bounds } = useStore();
121
- const { setBounds } = useDispatcher();
122
- const set = useCallback((bounds2) => {
123
- setBounds == null ? void 0 : setBounds(bounds2);
124
- }, [setBounds]);
125
- const reset = useCallback(() => {
126
- setBounds == null ? void 0 : setBounds(null);
127
- }, [setBounds]);
128
- return [
129
- bounds,
130
- {
131
- set,
132
- reset
133
- }
134
- ];
135
- }
136
- function useLang() {
137
- const { lang } = useStore();
138
- return lang;
139
- }
140
- var index$9 = "";
141
- var _jsxFileName$l = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsMagnifier/index.tsx";
142
- const magnifierWidth = 100;
143
- const magnifierHeight = 80;
144
- var ScreenshotsMagnifier = memo(function ScreenshotsMagnifier2({
145
- x,
146
- y
147
- }) {
148
- const {
149
- width,
150
- height,
151
- image
152
- } = useStore();
153
- const lang = useLang();
154
- const [position, setPosition] = useState(null);
155
- const elRef = useRef(null);
156
- const canvasRef = useRef(null);
157
- const ctxRef = useRef(null);
158
- const [rgb, setRgb] = useState("000000");
159
- useLayoutEffect(() => {
160
- if (!elRef.current) {
161
- return;
162
- }
163
- const elRect = elRef.current.getBoundingClientRect();
164
- let tx = x + 20;
165
- let ty = y + 20;
166
- if (tx + elRect.width > width) {
167
- tx = x - elRect.width - 20;
168
- }
169
- if (ty + elRect.height > height) {
170
- ty = y - elRect.height - 20;
171
- }
172
- if (tx < 0) {
173
- tx = 0;
174
- }
175
- if (ty < 0) {
176
- ty = 0;
177
- }
178
- setPosition({
179
- x: tx,
180
- y: ty
181
- });
182
- }, [width, height, x, y]);
183
- useEffect(() => {
184
- if (!image || !canvasRef.current) {
185
- ctxRef.current = null;
186
- return;
187
- }
188
- if (!ctxRef.current) {
189
- ctxRef.current = canvasRef.current.getContext("2d");
190
- }
191
- if (!ctxRef.current) {
192
- return;
193
- }
194
- const ctx = ctxRef.current;
195
- ctx.clearRect(0, 0, magnifierWidth, magnifierHeight);
196
- const rx = image.naturalWidth / width;
197
- const ry = image.naturalHeight / height;
198
- ctx.drawImage(image, x * rx - magnifierWidth / 2, y * ry - magnifierHeight / 2, magnifierWidth, magnifierHeight, 0, 0, magnifierWidth, magnifierHeight);
199
- const {
200
- data
201
- } = ctx.getImageData(Math.floor(magnifierWidth / 2), Math.floor(magnifierHeight / 2), 1, 1);
202
- const hex = Array.from(data.slice(0, 3)).map((val) => val >= 16 ? val.toString(16) : `0${val.toString(16)}`).join("").toUpperCase();
203
- setRgb(hex);
204
- }, [width, height, image, x, y]);
205
- return /* @__PURE__ */ React.createElement("div", {
206
- ref: elRef,
207
- className: "screenshots-magnifier",
208
- style: {
209
- transform: `translate(${position == null ? void 0 : position.x}px, ${position == null ? void 0 : position.y}px)`
210
- },
211
- __self: this,
212
- __source: {
213
- fileName: _jsxFileName$l,
214
- lineNumber: 89,
215
- columnNumber: 5
216
- }
217
- }, /* @__PURE__ */ React.createElement("div", {
218
- className: "screenshots-magnifier-body",
219
- __self: this,
220
- __source: {
221
- fileName: _jsxFileName$l,
222
- lineNumber: 96,
223
- columnNumber: 7
224
- }
225
- }, /* @__PURE__ */ React.createElement("canvas", {
226
- ref: canvasRef,
227
- className: "screenshots-magnifier-body-canvas",
228
- width: magnifierWidth,
229
- height: magnifierHeight,
230
- __self: this,
231
- __source: {
232
- fileName: _jsxFileName$l,
233
- lineNumber: 97,
234
- columnNumber: 9
235
- }
236
- })), /* @__PURE__ */ React.createElement("div", {
237
- className: "screenshots-magnifier-footer",
238
- __self: this,
239
- __source: {
240
- fileName: _jsxFileName$l,
241
- lineNumber: 104,
242
- columnNumber: 7
243
- }
244
- }, /* @__PURE__ */ React.createElement("div", {
245
- className: "screenshots-magnifier-footer-item",
246
- __self: this,
247
- __source: {
248
- fileName: _jsxFileName$l,
249
- lineNumber: 105,
250
- columnNumber: 9
251
- }
252
- }, lang.magnifier_position_label, ": (", x, ",", y, ")"), /* @__PURE__ */ React.createElement("div", {
253
- className: "screenshots-magnifier-footer-item",
254
- __self: this,
255
- __source: {
256
- fileName: _jsxFileName$l,
257
- lineNumber: 108,
258
- columnNumber: 9
259
- }
260
- }, "RGB: #", rgb)));
261
- });
262
- function getBoundsByPoints$2({ x: x1, y: y1 }, { x: x2, y: y2 }, width, height) {
263
- if (x1 > x2) {
264
- [x1, x2] = [x2, x1];
265
- }
266
- if (y1 > y2) {
267
- [y1, y2] = [y2, y1];
268
- }
269
- if (x1 < 0) {
270
- x1 = 0;
271
- }
272
- if (x2 > width) {
273
- x2 = width;
274
- }
275
- if (y1 < 0) {
276
- y1 = 0;
277
- }
278
- if (y2 > height) {
279
- y2 = height;
280
- }
281
- return {
282
- x: x1,
283
- y: y1,
284
- width: x2 - x1,
285
- height: y2 - y1
286
- };
287
- }
288
- var index$8 = "";
289
- var _jsxFileName$k = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsBackground/index.tsx";
290
- var ScreenshotsBackground = memo(function ScreenshotsBackground2() {
291
- const {
292
- url,
293
- image,
294
- width,
295
- height
296
- } = useStore();
297
- const [bounds, boundsDispatcher] = useBounds();
298
- const elRef = useRef(null);
299
- const pointRef = useRef(null);
300
- const isMoveRef = useRef(false);
301
- const [position, setPosition] = useState(null);
302
- const updateBounds = useCallback((p1, p2) => {
303
- if (!elRef.current) {
304
- return;
305
- }
306
- const {
307
- x,
308
- y
309
- } = elRef.current.getBoundingClientRect();
310
- boundsDispatcher.set(getBoundsByPoints$2({
311
- x: p1.x - x,
312
- y: p1.y - y
313
- }, {
314
- x: p2.x - x,
315
- y: p2.y - y
316
- }, width, height));
317
- }, [width, height, boundsDispatcher]);
318
- const onMouseDown = useCallback((e) => {
319
- if (pointRef.current || bounds || e.button !== 0) {
320
- return;
321
- }
322
- pointRef.current = {
323
- x: e.clientX,
324
- y: e.clientY
325
- };
326
- isMoveRef.current = false;
327
- }, [bounds]);
328
- useEffect(() => {
329
- const onMouseMove = (e) => {
330
- if (elRef.current) {
331
- const rect = elRef.current.getBoundingClientRect();
332
- if (e.clientX < rect.left || e.clientY < rect.top || e.clientX > rect.right || e.clientY > rect.bottom) {
333
- setPosition(null);
334
- } else {
335
- setPosition({
336
- x: e.clientX - rect.x,
337
- y: e.clientY - rect.y
338
- });
339
- }
340
- }
341
- if (!pointRef.current) {
342
- return;
343
- }
344
- updateBounds(pointRef.current, {
345
- x: e.clientX,
346
- y: e.clientY
347
- });
348
- isMoveRef.current = true;
349
- };
350
- const onMouseUp = (e) => {
351
- if (!pointRef.current) {
352
- return;
353
- }
354
- if (isMoveRef.current) {
355
- updateBounds(pointRef.current, {
356
- x: e.clientX,
357
- y: e.clientY
358
- });
359
- }
360
- pointRef.current = null;
361
- isMoveRef.current = false;
362
- };
363
- window.addEventListener("mousemove", onMouseMove);
364
- window.addEventListener("mouseup", onMouseUp);
365
- return () => {
366
- window.removeEventListener("mousemove", onMouseMove);
367
- window.removeEventListener("mouseup", onMouseUp);
368
- };
369
- }, [updateBounds]);
370
- useLayoutEffect(() => {
371
- if (!image || bounds) {
372
- setPosition(null);
373
- }
374
- }, [image, bounds]);
375
- if (!url || !image) {
376
- return null;
377
- }
378
- return /* @__PURE__ */ React.createElement("div", {
379
- ref: elRef,
380
- className: "screenshots-background",
381
- onMouseDown,
382
- __self: this,
383
- __source: {
384
- fileName: _jsxFileName$k,
385
- lineNumber: 120,
386
- columnNumber: 5
387
- }
388
- }, /* @__PURE__ */ React.createElement("img", {
389
- className: "screenshots-background-image",
390
- src: url,
391
- __self: this,
392
- __source: {
393
- fileName: _jsxFileName$k,
394
- lineNumber: 121,
395
- columnNumber: 7
396
- }
397
- }), /* @__PURE__ */ React.createElement("div", {
398
- className: "screenshots-background-mask",
399
- __self: this,
400
- __source: {
401
- fileName: _jsxFileName$k,
402
- lineNumber: 122,
403
- columnNumber: 7
404
- }
405
- }), position && !bounds && /* @__PURE__ */ React.createElement(ScreenshotsMagnifier, {
406
- x: position == null ? void 0 : position.x,
407
- y: position == null ? void 0 : position.y,
408
- __self: this,
409
- __source: {
410
- fileName: _jsxFileName$k,
411
- lineNumber: 123,
412
- columnNumber: 31
413
- }
414
- }));
415
- });
416
- function useCursor() {
417
- const { cursor } = useStore();
418
- const { setCursor } = useDispatcher();
419
- const set = useCallback((cursor2) => {
420
- setCursor == null ? void 0 : setCursor(cursor2);
421
- }, [setCursor]);
422
- const reset = useCallback(() => {
423
- setCursor == null ? void 0 : setCursor("move");
424
- }, [setCursor]);
425
- return [
426
- cursor,
427
- {
428
- set,
429
- reset
430
- }
431
- ];
432
- }
433
- function useEmiter() {
434
- const { emiterRef } = useStore();
435
- const on = useCallback((event, listener) => {
436
- const emiter = emiterRef.current;
437
- if (Array.isArray(emiter[event])) {
438
- emiter[event].push(listener);
439
- } else {
440
- emiter[event] = [listener];
441
- }
442
- }, [emiterRef]);
443
- const off = useCallback((event, listener) => {
444
- const emiter = emiterRef.current;
445
- if (Array.isArray(emiter[event])) {
446
- const index2 = emiter[event].findIndex((item) => item === listener);
447
- if (index2 !== -1) {
448
- emiter[event].splice(index2, 1);
449
- }
450
- }
451
- }, [emiterRef]);
452
- const emit = useCallback((event, ...args) => {
453
- const emiter = emiterRef.current;
454
- if (Array.isArray(emiter[event])) {
455
- emiter[event].forEach((listener) => listener(...args));
456
- }
457
- }, [emiterRef]);
458
- const reset = useCallback(() => {
459
- emiterRef.current = {};
460
- }, [emiterRef]);
461
- return {
462
- on,
463
- off,
464
- emit,
465
- reset
466
- };
467
- }
468
- function useHistory() {
469
- const { history } = useStore();
470
- const { setHistory } = useDispatcher();
471
- const push = useCallback((action) => {
472
- const { index: index2, stack } = history;
473
- stack.forEach((item) => {
474
- if (item.type === HistoryItemType.Source) {
475
- item.isSelected = false;
476
- }
477
- });
478
- if (action.type === HistoryItemType.Source) {
479
- action.isSelected = true;
480
- } else if (action.type === HistoryItemType.Edit) {
481
- action.source.isSelected = true;
482
- }
483
- stack.splice(index2 + 1);
484
- stack.push(action);
485
- setHistory == null ? void 0 : setHistory({
486
- index: stack.length - 1,
487
- stack
488
- });
489
- }, [history, setHistory]);
490
- const pop = useCallback(() => {
491
- const { stack } = history;
492
- stack.pop();
493
- setHistory == null ? void 0 : setHistory({
494
- index: stack.length - 1,
495
- stack
496
- });
497
- }, [history, setHistory]);
498
- const undo = useCallback(() => {
499
- const { index: index2, stack } = history;
500
- const item = stack[index2];
501
- if (item) {
502
- if (item.type === HistoryItemType.Source) {
503
- item.isSelected = false;
504
- } else if (item.type === HistoryItemType.Edit) {
505
- item.source.editHistory.pop();
506
- }
507
- }
508
- setHistory == null ? void 0 : setHistory({
509
- index: index2 <= 0 ? -1 : index2 - 1,
510
- stack
511
- });
512
- }, [history, setHistory]);
513
- const redo = useCallback(() => {
514
- const { index: index2, stack } = history;
515
- const item = stack[index2 + 1];
516
- if (item) {
517
- if (item.type === HistoryItemType.Source) {
518
- item.isSelected = false;
519
- } else if (item.type === HistoryItemType.Edit) {
520
- item.source.editHistory.push(item);
521
- }
522
- }
523
- setHistory == null ? void 0 : setHistory({
524
- index: index2 >= stack.length - 1 ? stack.length - 1 : index2 + 1,
525
- stack
526
- });
527
- }, [history, setHistory]);
528
- const set = useCallback((history2) => {
529
- setHistory == null ? void 0 : setHistory(__spreadValues({}, history2));
530
- }, [setHistory]);
531
- const select = useCallback((action) => {
532
- history.stack.forEach((item) => {
533
- if (item.type === HistoryItemType.Source) {
534
- if (item === action) {
535
- item.isSelected = true;
536
- } else {
537
- item.isSelected = false;
538
- }
539
- }
540
- });
541
- setHistory == null ? void 0 : setHistory(__spreadValues({}, history));
542
- }, [history, setHistory]);
543
- const clearSelect = useCallback(() => {
544
- history.stack.forEach((item) => {
545
- if (item.type === HistoryItemType.Source) {
546
- item.isSelected = false;
547
- }
548
- });
549
- setHistory == null ? void 0 : setHistory(__spreadValues({}, history));
550
- }, [history, setHistory]);
551
- const reset = useCallback(() => {
552
- setHistory == null ? void 0 : setHistory({
553
- index: -1,
554
- stack: []
555
- });
556
- }, [setHistory]);
557
- return [
558
- {
559
- index: history.index,
560
- stack: history.stack,
561
- top: history.stack.slice(history.index, history.index + 1)[0]
562
- },
563
- {
564
- push,
565
- pop,
566
- undo,
567
- redo,
568
- set,
569
- select,
570
- clearSelect,
571
- reset
572
- }
573
- ];
574
- }
575
- function useOperation() {
576
- const { operation } = useStore();
577
- const { setOperation } = useDispatcher();
578
- const set = useCallback((operation2) => {
579
- setOperation == null ? void 0 : setOperation(operation2);
580
- }, [setOperation]);
581
- const reset = useCallback(() => {
582
- setOperation == null ? void 0 : setOperation(void 0);
583
- }, [setOperation]);
584
- return [
585
- operation,
586
- {
587
- set,
588
- reset
589
- }
590
- ];
591
- }
592
- function getBoundsByPoints$1({ x: x1, y: y1 }, { x: x2, y: y2 }, bounds, width, height, resizeOrMove) {
593
- if (x1 > x2) {
594
- [x1, x2] = [x2, x1];
595
- }
596
- if (y1 > y2) {
597
- [y1, y2] = [y2, y1];
598
- }
599
- if (x1 < 0) {
600
- x1 = 0;
601
- if (resizeOrMove === "move") {
602
- x2 = bounds.width;
603
- }
604
- }
605
- if (x2 > width) {
606
- x2 = width;
607
- if (resizeOrMove === "move") {
608
- x1 = x2 - bounds.width;
609
- }
610
- }
611
- if (y1 < 0) {
612
- y1 = 0;
613
- if (resizeOrMove === "move") {
614
- y2 = bounds.height;
615
- }
616
- }
617
- if (y2 > height) {
618
- y2 = height;
619
- if (resizeOrMove === "move") {
620
- y1 = y2 - bounds.height;
621
- }
622
- }
623
- return {
624
- x: x1,
625
- y: y1,
626
- width: Math.max(x2 - x1, 1),
627
- height: Math.max(y2 - y1, 1)
628
- };
629
- }
630
- function getBoundsByPoints(e, resizeOrMove, point, bounds) {
631
- const x = e.clientX - point.x;
632
- const y = e.clientY - point.y;
633
- let x1 = bounds.x;
634
- let y1 = bounds.y;
635
- let x2 = bounds.x + bounds.width;
636
- let y2 = bounds.y + bounds.height;
637
- switch (resizeOrMove) {
638
- case "top":
639
- y1 += y;
640
- break;
641
- case "top-right":
642
- x2 += x;
643
- y1 += y;
644
- break;
645
- case "right":
646
- x2 += x;
647
- break;
648
- case "right-bottom":
649
- x2 += x;
650
- y2 += y;
651
- break;
652
- case "bottom":
653
- y2 += y;
654
- break;
655
- case "bottom-left":
656
- x1 += x;
657
- y2 += y;
658
- break;
659
- case "left":
660
- x1 += x;
661
- break;
662
- case "left-top":
663
- x1 += x;
664
- y1 += y;
665
- break;
666
- case "move":
667
- x1 += x;
668
- y1 += y;
669
- x2 += x;
670
- y2 += y;
671
- break;
672
- }
673
- return [
674
- {
675
- x: x1,
676
- y: y1
677
- },
678
- {
679
- x: x2,
680
- y: y2
681
- }
682
- ];
683
- }
684
- var index$7 = "";
685
- function isPointInDraw(bounds, canvas, history, e) {
686
- if (!canvas) {
687
- return false;
688
- }
689
- const $canvas = document.createElement("canvas");
690
- $canvas.width = bounds.width;
691
- $canvas.height = bounds.height;
692
- const ctx = $canvas.getContext("2d");
693
- if (!ctx) {
694
- return false;
695
- }
696
- const { left, top } = canvas.getBoundingClientRect();
697
- const x = e.clientX - left;
698
- const y = e.clientY - top;
699
- const stack = [...history.stack.slice(0, history.index + 1)];
700
- return stack.reverse().find((item) => {
701
- var _a;
702
- if (item.type !== HistoryItemType.Source) {
703
- return false;
704
- }
705
- ctx.clearRect(0, 0, bounds.width, bounds.height);
706
- return (_a = item.isHit) == null ? void 0 : _a.call(item, ctx, item, { x, y });
707
- });
708
- }
709
- var _jsxFileName$j = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsCanvas/index.tsx";
710
- const borders = ["top", "right", "bottom", "left"];
711
- var ResizePoints;
712
- (function(ResizePoints2) {
713
- ResizePoints2["ResizeTop"] = "top";
714
- ResizePoints2["ResizetopRight"] = "top-right";
715
- ResizePoints2["ResizeRight"] = "right";
716
- ResizePoints2["ResizeRightBottom"] = "right-bottom";
717
- ResizePoints2["ResizeBottom"] = "bottom";
718
- ResizePoints2["ResizeBottomLeft"] = "bottom-left";
719
- ResizePoints2["ResizeLeft"] = "left";
720
- ResizePoints2["ResizeLeftTop"] = "left-top";
721
- ResizePoints2["Move"] = "move";
722
- })(ResizePoints || (ResizePoints = {}));
723
- const resizePoints = [ResizePoints.ResizeTop, ResizePoints.ResizetopRight, ResizePoints.ResizeRight, ResizePoints.ResizeRightBottom, ResizePoints.ResizeBottom, ResizePoints.ResizeBottomLeft, ResizePoints.ResizeLeft, ResizePoints.ResizeLeftTop];
724
- var ScreenshotsCanvas = memo(forwardRef(function ScreenshotsCanvas2(props, ref) {
725
- const {
726
- url,
727
- image,
728
- width,
729
- height
730
- } = useStore();
731
- const emiter = useEmiter();
732
- const [history] = useHistory();
733
- const [cursor] = useCursor();
734
- const [bounds, boundsDispatcher] = useBounds();
735
- const [operation] = useOperation();
736
- const resizeOrMoveRef = useRef();
737
- const pointRef = useRef(null);
738
- const boundsRef = useRef(null);
739
- const canvasRef = useRef(null);
740
- const ctxRef = useRef(null);
741
- const draw2 = useCallback(() => {
742
- if (!bounds || !ctxRef.current) {
743
- return;
744
- }
745
- const ctx = ctxRef.current;
746
- ctx.imageSmoothingEnabled = true;
747
- ctx.imageSmoothingQuality = "low";
748
- ctx.clearRect(0, 0, bounds.width, bounds.height);
749
- history.stack.slice(0, history.index + 1).forEach((item) => {
750
- if (item.type === HistoryItemType.Source) {
751
- item.draw(ctx, item);
752
- }
753
- });
754
- }, [bounds, ctxRef, history]);
755
- const onMouseDown = useCallback((e, resizeOrMove) => {
756
- if (e.button !== 0 || !bounds) {
757
- return;
758
- }
759
- if (!operation) {
760
- resizeOrMoveRef.current = resizeOrMove;
761
- pointRef.current = {
762
- x: e.clientX,
763
- y: e.clientY
764
- };
765
- boundsRef.current = {
766
- x: bounds.x,
767
- y: bounds.y,
768
- width: bounds.width,
769
- height: bounds.height
770
- };
771
- } else {
772
- const draw22 = isPointInDraw(bounds, canvasRef.current, history, e.nativeEvent);
773
- if (draw22) {
774
- emiter.emit("drawselect", draw22, e.nativeEvent);
775
- } else {
776
- emiter.emit("mousedown", e.nativeEvent);
777
- }
778
- }
779
- }, [bounds, operation, emiter, history]);
780
- const updateBounds = useCallback((e) => {
781
- if (!resizeOrMoveRef.current || !pointRef.current || !boundsRef.current || !bounds) {
782
- return;
783
- }
784
- const points = getBoundsByPoints(e, resizeOrMoveRef.current, pointRef.current, boundsRef.current);
785
- boundsDispatcher.set(getBoundsByPoints$1(points[0], points[1], bounds, width, height, resizeOrMoveRef.current));
786
- }, [width, height, bounds, boundsDispatcher]);
787
- useLayoutEffect(() => {
788
- if (!image || !bounds || !canvasRef.current) {
789
- ctxRef.current = null;
790
- return;
791
- }
792
- if (!ctxRef.current) {
793
- ctxRef.current = canvasRef.current.getContext("2d");
794
- }
795
- draw2();
796
- }, [image, bounds, draw2]);
797
- useEffect(() => {
798
- const onMouseMove = (e) => {
799
- if (!operation) {
800
- if (!resizeOrMoveRef.current || !pointRef.current || !boundsRef.current) {
801
- return;
802
- }
803
- updateBounds(e);
804
- } else {
805
- emiter.emit("mousemove", e);
806
- }
807
- };
808
- const onMouseUp = (e) => {
809
- if (!operation) {
810
- if (!resizeOrMoveRef.current || !pointRef.current || !boundsRef.current) {
811
- return;
812
- }
813
- updateBounds(e);
814
- resizeOrMoveRef.current = void 0;
815
- pointRef.current = null;
816
- boundsRef.current = null;
817
- } else {
818
- emiter.emit("mouseup", e);
819
- }
820
- };
821
- window.addEventListener("mousemove", onMouseMove);
822
- window.addEventListener("mouseup", onMouseUp);
823
- return () => {
824
- window.removeEventListener("mousemove", onMouseMove);
825
- window.removeEventListener("mouseup", onMouseUp);
826
- };
827
- }, [updateBounds, operation, emiter]);
828
- useImperativeHandle(ref, () => ctxRef.current);
829
- return /* @__PURE__ */ React.createElement("div", {
830
- className: "screenshots-canvas",
831
- style: {
832
- width: (bounds == null ? void 0 : bounds.width) || 0,
833
- height: (bounds == null ? void 0 : bounds.height) || 0,
834
- transform: bounds ? `translate(${bounds.x}px, ${bounds.y}px)` : "none"
835
- },
836
- __self: this,
837
- __source: {
838
- fileName: _jsxFileName$j,
839
- lineNumber: 173,
840
- columnNumber: 7
841
- }
842
- }, /* @__PURE__ */ React.createElement("div", {
843
- className: "screenshots-canvas-body",
844
- __self: this,
845
- __source: {
846
- fileName: _jsxFileName$j,
847
- lineNumber: 181,
848
- columnNumber: 9
849
- }
850
- }, /* @__PURE__ */ React.createElement("img", {
851
- className: "screenshots-canvas-image",
852
- src: url,
853
- style: {
854
- width,
855
- height,
856
- transform: bounds ? `translate(${-bounds.x}px, ${-bounds.y}px)` : "none"
857
- },
858
- __self: this,
859
- __source: {
860
- fileName: _jsxFileName$j,
861
- lineNumber: 183,
862
- columnNumber: 11
863
- }
864
- }), /* @__PURE__ */ React.createElement("canvas", {
865
- ref: canvasRef,
866
- className: "screenshots-canvas-panel",
867
- width: (bounds == null ? void 0 : bounds.width) || 0,
868
- height: (bounds == null ? void 0 : bounds.height) || 0,
869
- __self: this,
870
- __source: {
871
- fileName: _jsxFileName$j,
872
- lineNumber: 192,
873
- columnNumber: 11
874
- }
875
- })), /* @__PURE__ */ React.createElement("div", {
876
- className: "screenshots-canvas-mask",
877
- style: {
878
- cursor
879
- },
880
- onMouseDown: (e) => onMouseDown(e, "move"),
881
- __self: this,
882
- __source: {
883
- fileName: _jsxFileName$j,
884
- lineNumber: 199,
885
- columnNumber: 9
886
- }
887
- }), borders.map((border) => {
888
- return /* @__PURE__ */ React.createElement("div", {
889
- key: border,
890
- className: `screenshots-canvas-border-${border}`,
891
- __self: this,
892
- __source: {
893
- fileName: _jsxFileName$j,
894
- lineNumber: 207,
895
- columnNumber: 18
896
- }
897
- });
898
- }), resizePoints.map((resizePoint) => {
899
- return /* @__PURE__ */ React.createElement("div", {
900
- key: resizePoint,
901
- className: `screenshots-canvas-point-${resizePoint}`,
902
- onMouseDown: (e) => onMouseDown(e, resizePoint),
903
- __self: this,
904
- __source: {
905
- fileName: _jsxFileName$j,
906
- lineNumber: 211,
907
- columnNumber: 13
908
- }
909
- });
910
- }));
911
- }));
912
- function useCall() {
913
- const dispatcher = useDispatcher();
914
- const call = useCallback((funcName, ...args) => {
915
- var _a;
916
- (_a = dispatcher.call) == null ? void 0 : _a.call(dispatcher, funcName, ...args);
917
- }, [dispatcher]);
918
- return call;
919
- }
920
- function useCanvasContextRef() {
921
- const { canvasContextRef } = useStore();
922
- return canvasContextRef;
923
- }
924
- function useReset() {
925
- const emiter = useEmiter();
926
- const [, boundsDispatcher] = useBounds();
927
- const [, cursorDispatcher] = useCursor();
928
- const [, historyDispatcher] = useHistory();
929
- const [, operatioDispatcher] = useOperation();
930
- const reset = useCallback(() => {
931
- emiter.reset();
932
- historyDispatcher.reset();
933
- boundsDispatcher.reset();
934
- cursorDispatcher.reset();
935
- operatioDispatcher.reset();
936
- }, [emiter, historyDispatcher, boundsDispatcher, cursorDispatcher, operatioDispatcher]);
937
- return reset;
938
- }
939
- var index$6 = "";
940
- var _jsxFileName$i = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsOption/index.tsx";
941
- var Placement;
942
- (function(Placement2) {
943
- Placement2["Bottom"] = "bottom";
944
- Placement2["Top"] = "top";
945
- })(Placement || (Placement = {}));
946
- var ScreenshotsOption = memo(function ScreenshotsOption2({
947
- open,
948
- content,
949
- children
950
- }) {
951
- var _a, _b;
952
- const childrenRef = useRef(null);
953
- const popoverRef = useRef(null);
954
- const contentRef = useRef(null);
955
- const operationsRect = useContext(ScreenshotsOperationsCtx);
956
- const [placement, setPlacement] = useState(Placement.Bottom);
957
- const [position, setPosition] = useState(null);
958
- const [offsetX, setOffsetX] = useState(0);
959
- const getPopoverEl = () => {
960
- if (!popoverRef.current) {
961
- popoverRef.current = document.createElement("div");
962
- }
963
- return popoverRef.current;
964
- };
965
- useEffect(() => {
966
- const $el = getPopoverEl();
967
- if (open) {
968
- document.body.appendChild($el);
969
- }
970
- return () => {
971
- $el.remove();
972
- };
973
- }, [open]);
974
- useEffect(() => {
975
- if (!open || !operationsRect || !childrenRef.current || !contentRef.current) {
976
- return;
977
- }
978
- const childrenRect = childrenRef.current.getBoundingClientRect();
979
- const contentRect = contentRef.current.getBoundingClientRect();
980
- let currentPlacement = placement;
981
- let x = childrenRect.left + childrenRect.width / 2;
982
- let y = childrenRect.top + childrenRect.height;
983
- let currentOffsetX = offsetX;
984
- if (x + contentRect.width / 2 > operationsRect.x + operationsRect.width) {
985
- const ox = x;
986
- x = operationsRect.x + operationsRect.width - contentRect.width / 2;
987
- currentOffsetX = ox - x;
988
- }
989
- if (x < operationsRect.x + contentRect.width / 2) {
990
- const ox = x;
991
- x = operationsRect.x + contentRect.width / 2;
992
- currentOffsetX = ox - x;
993
- }
994
- if (y > window.innerHeight - contentRect.height) {
995
- if (currentPlacement === Placement.Bottom) {
996
- currentPlacement = Placement.Top;
997
- }
998
- y = childrenRect.top - contentRect.height;
999
- }
1000
- if (y < 0) {
1001
- if (currentPlacement === Placement.Top) {
1002
- currentPlacement = Placement.Bottom;
1003
- }
1004
- y = childrenRect.top + childrenRect.height;
1005
- }
1006
- if (currentPlacement !== placement) {
1007
- setPlacement(currentPlacement);
1008
- }
1009
- if ((position == null ? void 0 : position.x) !== x || position.y !== y) {
1010
- setPosition({
1011
- x,
1012
- y
1013
- });
1014
- }
1015
- if (currentOffsetX !== offsetX) {
1016
- setOffsetX(currentOffsetX);
1017
- }
1018
- });
1019
- return /* @__PURE__ */ React.createElement(React.Fragment, null, cloneElement(children, {
1020
- ref: childrenRef
1021
- }), open && content && createPortal(/* @__PURE__ */ React.createElement("div", {
1022
- ref: contentRef,
1023
- className: "screenshots-option",
1024
- style: {
1025
- visibility: position ? "visible" : "hidden",
1026
- transform: `translate(${(_a = position == null ? void 0 : position.x) != null ? _a : 0}px, ${(_b = position == null ? void 0 : position.y) != null ? _b : 0}px)`
1027
- },
1028
- "data-placement": placement,
1029
- __self: this,
1030
- __source: {
1031
- fileName: _jsxFileName$i,
1032
- lineNumber: 111,
1033
- columnNumber: 11
1034
- }
1035
- }, /* @__PURE__ */ React.createElement("div", {
1036
- className: "screenshots-option-container",
1037
- __self: this,
1038
- __source: {
1039
- fileName: _jsxFileName$i,
1040
- lineNumber: 120,
1041
- columnNumber: 13
1042
- }
1043
- }, content), /* @__PURE__ */ React.createElement("div", {
1044
- className: "screenshots-option-arrow",
1045
- style: {
1046
- marginLeft: offsetX
1047
- },
1048
- __self: this,
1049
- __source: {
1050
- fileName: _jsxFileName$i,
1051
- lineNumber: 121,
1052
- columnNumber: 13
1053
- }
1054
- })), getPopoverEl()));
1055
- });
1056
- var index$5 = "";
1057
- var _jsxFileName$h = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsButton/index.tsx";
1058
- var ScreenshotsButton = memo(function ScreenshotsButton2({
1059
- title,
1060
- icon,
1061
- checked,
1062
- disabled,
1063
- option,
1064
- onClick
1065
- }) {
1066
- const classNames = ["screenshots-button"];
1067
- const onButtonClick = useCallback((e) => {
1068
- if (disabled || !onClick) {
1069
- return;
1070
- }
1071
- onClick(e);
1072
- }, [disabled, onClick]);
1073
- if (checked) {
1074
- classNames.push("screenshots-button-checked");
1075
- }
1076
- if (disabled) {
1077
- classNames.push("screenshots-button-disabled");
1078
- }
1079
- return /* @__PURE__ */ React.createElement(ScreenshotsOption, {
1080
- open: checked,
1081
- content: option,
1082
- __self: this,
1083
- __source: {
1084
- fileName: _jsxFileName$h,
1085
- lineNumber: 42,
1086
- columnNumber: 5
1087
- }
1088
- }, /* @__PURE__ */ React.createElement("div", {
1089
- className: classNames.join(" "),
1090
- title,
1091
- onClick: onButtonClick,
1092
- __self: this,
1093
- __source: {
1094
- fileName: _jsxFileName$h,
1095
- lineNumber: 43,
1096
- columnNumber: 7
1097
- }
1098
- }, /* @__PURE__ */ React.createElement("span", {
1099
- className: icon,
1100
- __self: this,
1101
- __source: {
1102
- fileName: _jsxFileName$h,
1103
- lineNumber: 44,
1104
- columnNumber: 9
1105
- }
1106
- })));
1107
- });
1108
- var _jsxFileName$g = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Ok/index.tsx";
1109
- function Ok() {
1110
- const {
1111
- image,
1112
- width,
1113
- height,
1114
- history,
1115
- bounds,
1116
- lang
1117
- } = useStore();
1118
- const canvasContextRef = useCanvasContextRef();
1119
- const [, historyDispatcher] = useHistory();
1120
- const call = useCall();
1121
- const reset = useReset();
1122
- const onClick = useCallback(() => {
1123
- historyDispatcher.clearSelect();
1124
- setTimeout(() => {
1125
- if (!canvasContextRef.current || !image || !bounds) {
1126
- return;
1127
- }
1128
- composeImage({
1129
- image,
1130
- width,
1131
- height,
1132
- history,
1133
- bounds
1134
- }).then((blob) => {
1135
- call("onOk", blob, bounds);
1136
- reset();
1137
- });
1138
- });
1139
- }, [canvasContextRef, historyDispatcher, image, width, height, history, bounds, call, reset]);
1140
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1141
- title: lang.operation_ok_title,
1142
- icon: "icon-ok",
1143
- onClick,
1144
- __self: this,
1145
- __source: {
1146
- fileName: _jsxFileName$g,
1147
- lineNumber: 36,
1148
- columnNumber: 10
1149
- }
1150
- });
1151
- }
1152
- var _jsxFileName$f = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Cancel/index.tsx";
1153
- function Cancel() {
1154
- const call = useCall();
1155
- const reset = useReset();
1156
- const lang = useLang();
1157
- const onClick = useCallback(() => {
1158
- call("onCancel");
1159
- reset();
1160
- }, [call, reset]);
1161
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1162
- title: lang.operation_cancel_title,
1163
- icon: "icon-cancel",
1164
- onClick,
1165
- __self: this,
1166
- __source: {
1167
- fileName: _jsxFileName$f,
1168
- lineNumber: 17,
1169
- columnNumber: 10
1170
- }
1171
- });
1172
- }
1173
- var _jsxFileName$e = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Save/index.tsx";
1174
- function Save() {
1175
- const {
1176
- image,
1177
- width,
1178
- height,
1179
- history,
1180
- bounds,
1181
- lang
1182
- } = useStore();
1183
- const canvasContextRef = useCanvasContextRef();
1184
- const [, historyDispatcher] = useHistory();
1185
- const call = useCall();
1186
- const reset = useReset();
1187
- const onClick = useCallback(() => {
1188
- historyDispatcher.clearSelect();
1189
- setTimeout(() => {
1190
- if (!canvasContextRef.current || !image || !bounds) {
1191
- return;
1192
- }
1193
- composeImage({
1194
- image,
1195
- width,
1196
- height,
1197
- history,
1198
- bounds
1199
- }).then((blob) => {
1200
- call("onSave", blob, bounds);
1201
- reset();
1202
- });
1203
- });
1204
- }, [canvasContextRef, historyDispatcher, image, width, height, history, bounds, call, reset]);
1205
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1206
- title: lang.operation_save_title,
1207
- icon: "icon-save",
1208
- onClick,
1209
- __self: this,
1210
- __source: {
1211
- fileName: _jsxFileName$e,
1212
- lineNumber: 36,
1213
- columnNumber: 10
1214
- }
1215
- });
1216
- }
1217
- var _jsxFileName$d = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Redo/index.tsx";
1218
- function Redo() {
1219
- const lang = useLang();
1220
- const [history, historyDispatcher] = useHistory();
1221
- const onClick = useCallback(() => {
1222
- historyDispatcher.redo();
1223
- }, [historyDispatcher]);
1224
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1225
- title: lang.operation_redo_title,
1226
- icon: "icon-redo",
1227
- disabled: !history.stack.length || history.stack.length - 1 === history.index,
1228
- onClick,
1229
- __self: this,
1230
- __source: {
1231
- fileName: _jsxFileName$d,
1232
- lineNumber: 15,
1233
- columnNumber: 5
1234
- }
1235
- });
1236
- }
1237
- var _jsxFileName$c = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Undo/index.tsx";
1238
- function Undo() {
1239
- const lang = useLang();
1240
- const [history, historyDispatcher] = useHistory();
1241
- const onClick = useCallback(() => {
1242
- historyDispatcher.undo();
1243
- }, [historyDispatcher]);
1244
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1245
- title: lang.operation_undo_title,
1246
- icon: "icon-undo",
1247
- disabled: history.index === -1,
1248
- onClick,
1249
- __self: this,
1250
- __source: {
1251
- fileName: _jsxFileName$c,
1252
- lineNumber: 15,
1253
- columnNumber: 5
1254
- }
1255
- });
1256
- }
1257
- var index$4 = "";
1258
- var _jsxFileName$b = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsSize/index.tsx";
1259
- var ScreenshotsSize = memo(function ScreenshotsSize2({
1260
- value,
1261
- onChange
1262
- }) {
1263
- const sizes2 = [3, 6, 9];
1264
- return /* @__PURE__ */ React.createElement("div", {
1265
- className: "screenshots-size",
1266
- __self: this,
1267
- __source: {
1268
- fileName: _jsxFileName$b,
1269
- lineNumber: 12,
1270
- columnNumber: 5
1271
- }
1272
- }, sizes2.map((size) => {
1273
- const classNames = ["screenshots-size-item"];
1274
- if (size === value) {
1275
- classNames.push("screenshots-size-active");
1276
- }
1277
- return /* @__PURE__ */ React.createElement("div", {
1278
- key: size,
1279
- className: classNames.join(" "),
1280
- onClick: () => onChange && onChange(size),
1281
- __self: this,
1282
- __source: {
1283
- fileName: _jsxFileName$b,
1284
- lineNumber: 21,
1285
- columnNumber: 11
1286
- }
1287
- }, /* @__PURE__ */ React.createElement("div", {
1288
- className: "screenshots-size-pointer",
1289
- style: {
1290
- width: size * 1.8,
1291
- height: size * 1.8
1292
- },
1293
- __self: this,
1294
- __source: {
1295
- fileName: _jsxFileName$b,
1296
- lineNumber: 22,
1297
- columnNumber: 13
1298
- }
1299
- }));
1300
- }));
1301
- });
1302
- function useCanvasMousedown(onMousedown) {
1303
- const emiter = useEmiter();
1304
- useEffect(() => {
1305
- emiter.on("mousedown", onMousedown);
1306
- return () => {
1307
- emiter.off("mousedown", onMousedown);
1308
- };
1309
- }, [onMousedown, emiter]);
1310
- }
1311
- function useCanvasMousemove(onMousemove) {
1312
- const emiter = useEmiter();
1313
- useEffect(() => {
1314
- emiter.on("mousemove", onMousemove);
1315
- return () => {
1316
- emiter.off("mousemove", onMousemove);
1317
- };
1318
- }, [onMousemove, emiter]);
1319
- }
1320
- function useCanvasMouseup(onMouseup) {
1321
- const emiter = useEmiter();
1322
- useEffect(() => {
1323
- emiter.on("mouseup", onMouseup);
1324
- return () => {
1325
- emiter.off("mouseup", onMouseup);
1326
- };
1327
- }, [onMouseup, emiter]);
1328
- }
1329
- var _jsxFileName$a = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Mosaic/index.tsx";
1330
- function getColor(x, y, imageData) {
1331
- if (!imageData) {
1332
- return [0, 0, 0, 0];
1333
- }
1334
- const {
1335
- data,
1336
- width
1337
- } = imageData;
1338
- const index2 = y * width * 4 + x * 4;
1339
- return Array.from(data.slice(index2, index2 + 4));
1340
- }
1341
- function draw$5(ctx, action) {
1342
- const {
1343
- tiles,
1344
- size
1345
- } = action.data;
1346
- tiles.forEach((tile) => {
1347
- const r = Math.round(tile.color[0]);
1348
- const g = Math.round(tile.color[1]);
1349
- const b = Math.round(tile.color[2]);
1350
- const a = tile.color[3] / 255;
1351
- ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
1352
- ctx.fillRect(tile.x - size / 2, tile.y - size / 2, size, size);
1353
- });
1354
- }
1355
- function Mosaic() {
1356
- const lang = useLang();
1357
- const {
1358
- image,
1359
- width,
1360
- height
1361
- } = useStore();
1362
- const [operation, operationDispatcher] = useOperation();
1363
- const canvasContextRef = useCanvasContextRef();
1364
- const [history, historyDispatcher] = useHistory();
1365
- const [bounds] = useBounds();
1366
- const [, cursorDispatcher] = useCursor();
1367
- const [size, setSize] = useState(3);
1368
- const imageDataRef = useRef(null);
1369
- const mosaicRef = useRef(null);
1370
- const checked = operation === "Mosaic";
1371
- const selectMosaic = useCallback(() => {
1372
- operationDispatcher.set("Mosaic");
1373
- cursorDispatcher.set("crosshair");
1374
- }, [operationDispatcher, cursorDispatcher]);
1375
- const onSelectMosaic = useCallback(() => {
1376
- if (checked) {
1377
- return;
1378
- }
1379
- selectMosaic();
1380
- historyDispatcher.clearSelect();
1381
- }, [checked, selectMosaic, historyDispatcher]);
1382
- const onMousedown = useCallback((e) => {
1383
- if (!checked || mosaicRef.current || !imageDataRef.current || !canvasContextRef.current) {
1384
- return;
1385
- }
1386
- const rect = canvasContextRef.current.canvas.getBoundingClientRect();
1387
- const x = e.clientX - rect.x;
1388
- const y = e.clientY - rect.y;
1389
- const mosaicSize = size * 2;
1390
- mosaicRef.current = {
1391
- name: "Mosaic",
1392
- type: HistoryItemType.Source,
1393
- data: {
1394
- size: mosaicSize,
1395
- tiles: [{
1396
- x,
1397
- y,
1398
- color: getColor(x, y, imageDataRef.current)
1399
- }]
1400
- },
1401
- editHistory: [],
1402
- draw: draw$5
1403
- };
1404
- }, [checked, size, canvasContextRef]);
1405
- const onMousemove = useCallback((e) => {
1406
- if (!checked || !mosaicRef.current || !canvasContextRef.current || !imageDataRef.current) {
1407
- return;
1408
- }
1409
- const rect = canvasContextRef.current.canvas.getBoundingClientRect();
1410
- const x = e.clientX - rect.x;
1411
- const y = e.clientY - rect.y;
1412
- const mosaicSize = mosaicRef.current.data.size;
1413
- const mosaicTiles = mosaicRef.current.data.tiles;
1414
- let lastTile = mosaicTiles[mosaicTiles.length - 1];
1415
- if (!lastTile) {
1416
- mosaicTiles.push({
1417
- x,
1418
- y,
1419
- color: getColor(x, y, imageDataRef.current)
1420
- });
1421
- } else {
1422
- const dx = lastTile.x - x;
1423
- const dy = lastTile.y - y;
1424
- let length = Math.sqrt(dx ** 2 + dy ** 2);
1425
- const sin = -dy / length;
1426
- const cos = -dx / length;
1427
- while (length > mosaicSize) {
1428
- const cx = Math.floor(lastTile.x + mosaicSize * cos);
1429
- const cy = Math.floor(lastTile.y + mosaicSize * sin);
1430
- lastTile = {
1431
- x: cx,
1432
- y: cy,
1433
- color: getColor(cx, cy, imageDataRef.current)
1434
- };
1435
- mosaicTiles.push(lastTile);
1436
- length -= mosaicSize;
1437
- }
1438
- if (length > mosaicSize / 2) {
1439
- mosaicTiles.push({
1440
- x,
1441
- y,
1442
- color: getColor(x, y, imageDataRef.current)
1443
- });
1444
- }
1445
- }
1446
- if (history.top !== mosaicRef.current) {
1447
- historyDispatcher.push(mosaicRef.current);
1448
- } else {
1449
- historyDispatcher.set(history);
1450
- }
1451
- }, [checked, canvasContextRef, history, historyDispatcher]);
1452
- const onMouseup = useCallback(() => {
1453
- if (!checked) {
1454
- return;
1455
- }
1456
- mosaicRef.current = null;
1457
- }, [checked]);
1458
- useCanvasMousedown(onMousedown);
1459
- useCanvasMousemove(onMousemove);
1460
- useCanvasMouseup(onMouseup);
1461
- useEffect(() => {
1462
- if (!bounds || !image || !checked) {
1463
- return;
1464
- }
1465
- const $canvas = document.createElement("canvas");
1466
- const canvasContext = $canvas.getContext("2d");
1467
- if (!canvasContext) {
1468
- return;
1469
- }
1470
- $canvas.width = bounds.width;
1471
- $canvas.height = bounds.height;
1472
- const rx = image.naturalWidth / width;
1473
- const ry = image.naturalHeight / height;
1474
- canvasContext.drawImage(image, bounds.x * rx, bounds.y * ry, bounds.width * rx, bounds.height * ry, 0, 0, bounds.width, bounds.height);
1475
- imageDataRef.current = canvasContext.getImageData(0, 0, bounds.width, bounds.height);
1476
- }, [width, height, bounds, image, checked]);
1477
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1478
- title: lang.operation_mosaic_title,
1479
- icon: "icon-mosaic",
1480
- checked,
1481
- onClick: onSelectMosaic,
1482
- option: /* @__PURE__ */ React.createElement(ScreenshotsSize, {
1483
- value: size,
1484
- onChange: setSize,
1485
- __self: this,
1486
- __source: {
1487
- fileName: _jsxFileName$a,
1488
- lineNumber: 220,
1489
- columnNumber: 15
1490
- }
1491
- }),
1492
- __self: this,
1493
- __source: {
1494
- fileName: _jsxFileName$a,
1495
- lineNumber: 215,
1496
- columnNumber: 5
1497
- }
1498
- });
1499
- }
1500
- var index$3 = "";
1501
- var _jsxFileName$9 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsColor/index.tsx";
1502
- var ScreenshotsColor = memo(function ScreenshotsColor2({
1503
- value,
1504
- onChange
1505
- }) {
1506
- const colors = ["#ee5126", "#fceb4d", "#90e746", "#51c0fa", "#7a7a7a", "#ffffff"];
1507
- return /* @__PURE__ */ React.createElement("div", {
1508
- className: "screenshots-color",
1509
- __self: this,
1510
- __source: {
1511
- fileName: _jsxFileName$9,
1512
- lineNumber: 12,
1513
- columnNumber: 5
1514
- }
1515
- }, colors.map((color) => {
1516
- const classNames = ["screenshots-color-item"];
1517
- if (color === value) {
1518
- classNames.push("screenshots-color-active");
1519
- }
1520
- return /* @__PURE__ */ React.createElement("div", {
1521
- key: color,
1522
- className: classNames.join(" "),
1523
- style: {
1524
- backgroundColor: color
1525
- },
1526
- onClick: () => onChange && onChange(color),
1527
- __self: this,
1528
- __source: {
1529
- fileName: _jsxFileName$9,
1530
- lineNumber: 19,
1531
- columnNumber: 11
1532
- }
1533
- });
1534
- }));
1535
- });
1536
- var index$2 = "";
1537
- var _jsxFileName$8 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsSizeColor/index.tsx";
1538
- var ScreenshotsSizeColor = memo(function ScreenshotsSizeColor2({
1539
- size,
1540
- color,
1541
- onSizeChange,
1542
- onColorChange
1543
- }) {
1544
- return /* @__PURE__ */ React.createElement("div", {
1545
- className: "screenshots-sizecolor",
1546
- __self: this,
1547
- __source: {
1548
- fileName: _jsxFileName$8,
1549
- lineNumber: 20,
1550
- columnNumber: 5
1551
- }
1552
- }, /* @__PURE__ */ React.createElement(ScreenshotsSize, {
1553
- value: size,
1554
- onChange: onSizeChange,
1555
- __self: this,
1556
- __source: {
1557
- fileName: _jsxFileName$8,
1558
- lineNumber: 21,
1559
- columnNumber: 7
1560
- }
1561
- }), /* @__PURE__ */ React.createElement(ScreenshotsColor, {
1562
- value: color,
1563
- onChange: onColorChange,
1564
- __self: this,
1565
- __source: {
1566
- fileName: _jsxFileName$8,
1567
- lineNumber: 22,
1568
- columnNumber: 7
1569
- }
1570
- }));
1571
- });
1572
- const hiddenTextareaStyle = `
1573
- min-width: 0 !important;
1574
- width: 0 !important;
1575
- min-height: 0 !important;
1576
- height:0 !important;
1577
- visibility: hidden !important;
1578
- overflow: hidden !important;
1579
- position: absolute !important;
1580
- z-index: -1000 !important;
1581
- top:0 !important;
1582
- right:0 !important;
1583
- `;
1584
- const sizeStyle = [
1585
- "letter-spacing",
1586
- "line-height",
1587
- "padding-top",
1588
- "padding-bottom",
1589
- "font-family",
1590
- "font-weight",
1591
- "font-size",
1592
- "font-variant",
1593
- "text-rendering",
1594
- "text-transform",
1595
- "text-indent",
1596
- "padding-left",
1597
- "padding-right",
1598
- "border-width",
1599
- "box-sizing",
1600
- "white-space",
1601
- "word-break"
1602
- ];
1603
- let hiddenTextarea;
1604
- function getComputedSizeInfo(node) {
1605
- const style = window.getComputedStyle(node);
1606
- const boxSizing = style.getPropertyValue("box-sizing") || style.getPropertyValue("-moz-box-sizing") || style.getPropertyValue("-webkit-box-sizing");
1607
- const paddingSize = parseFloat(style.getPropertyValue("padding-bottom")) + parseFloat(style.getPropertyValue("padding-top"));
1608
- const borderSize = parseFloat(style.getPropertyValue("border-bottom-width")) + parseFloat(style.getPropertyValue("border-top-width"));
1609
- const sizingStyle = sizeStyle.map((name) => `${name}:${style.getPropertyValue(name)}`).join(";");
1610
- return {
1611
- sizingStyle,
1612
- paddingSize,
1613
- borderSize,
1614
- boxSizing
1615
- };
1616
- }
1617
- function calculateNodeSize(textarea, value, maxWidth, maxHeight) {
1618
- if (!hiddenTextarea) {
1619
- hiddenTextarea = document.createElement("textarea");
1620
- hiddenTextarea.setAttribute("tab-index", "-1");
1621
- document.body.appendChild(hiddenTextarea);
1622
- }
1623
- const { paddingSize, borderSize, boxSizing, sizingStyle } = getComputedSizeInfo(textarea);
1624
- hiddenTextarea.setAttribute("style", `${sizingStyle};${hiddenTextareaStyle};max-width:${maxWidth}px;max-height:${maxHeight}px`);
1625
- hiddenTextarea.value = value || " ";
1626
- let width = hiddenTextarea.scrollWidth;
1627
- let height = hiddenTextarea.scrollHeight;
1628
- if (boxSizing === "border-box") {
1629
- width += borderSize;
1630
- height += borderSize;
1631
- } else if (boxSizing === "content-box") {
1632
- width -= paddingSize;
1633
- height -= paddingSize;
1634
- }
1635
- return {
1636
- width: Math.min(width, maxWidth),
1637
- height: Math.min(height, maxHeight)
1638
- };
1639
- }
1640
- var index$1 = "";
1641
- var _jsxFileName$7 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsTextarea/index.tsx";
1642
- var ScreenshotsTextarea = memo(function ScreenshotsTextarea2({
1643
- x,
1644
- y,
1645
- maxWidth,
1646
- maxHeight,
1647
- size,
1648
- color,
1649
- value,
1650
- onChange,
1651
- onBlur
1652
- }) {
1653
- const popoverRef = useRef(null);
1654
- const textareaRef = useRef(null);
1655
- const [width, setWidth] = useState(0);
1656
- const [height, setHeight] = useState(0);
1657
- const getPopoverEl = () => {
1658
- if (!popoverRef.current) {
1659
- popoverRef.current = document.createElement("div");
1660
- }
1661
- return popoverRef.current;
1662
- };
1663
- useLayoutEffect(() => {
1664
- if (popoverRef.current) {
1665
- document.body.appendChild(popoverRef.current);
1666
- requestAnimationFrame(() => {
1667
- var _a;
1668
- (_a = textareaRef.current) == null ? void 0 : _a.focus();
1669
- });
1670
- }
1671
- return () => {
1672
- var _a;
1673
- (_a = popoverRef.current) == null ? void 0 : _a.remove();
1674
- };
1675
- }, []);
1676
- useLayoutEffect(() => {
1677
- if (!textareaRef.current) {
1678
- return;
1679
- }
1680
- const {
1681
- width: width2,
1682
- height: height2
1683
- } = calculateNodeSize(textareaRef.current, value, maxWidth, maxHeight);
1684
- setWidth(width2);
1685
- setHeight(height2);
1686
- }, [value, maxWidth, maxHeight]);
1687
- return createPortal(/* @__PURE__ */ React.createElement("textarea", {
1688
- ref: textareaRef,
1689
- className: "screenshots-textarea",
1690
- style: {
1691
- color,
1692
- width,
1693
- height,
1694
- maxWidth,
1695
- maxHeight,
1696
- fontSize: size,
1697
- lineHeight: `${size}px`,
1698
- transform: `translate(${x}px, ${y}px)`
1699
- },
1700
- value,
1701
- onChange: (e) => onChange && onChange(e.target.value),
1702
- onBlur: (e) => onBlur && onBlur(e),
1703
- __self: this,
1704
- __source: {
1705
- fileName: _jsxFileName$7,
1706
- lineNumber: 65,
1707
- columnNumber: 5
1708
- }
1709
- }), getPopoverEl());
1710
- });
1711
- function useDrawSelect(onDrawSelect) {
1712
- const emiter = useEmiter();
1713
- useEffect(() => {
1714
- emiter.on("drawselect", onDrawSelect);
1715
- return () => {
1716
- emiter.off("drawselect", onDrawSelect);
1717
- };
1718
- }, [onDrawSelect, emiter]);
1719
- }
1720
- var _jsxFileName$6 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Text/index.tsx";
1721
- const sizes = {
1722
- 3: 18,
1723
- 6: 32,
1724
- 9: 46
1725
- };
1726
- function draw$4(ctx, action) {
1727
- const {
1728
- size,
1729
- color,
1730
- fontFamily,
1731
- x,
1732
- y,
1733
- text
1734
- } = action.data;
1735
- ctx.fillStyle = color;
1736
- ctx.textAlign = "left";
1737
- ctx.textBaseline = "top";
1738
- ctx.font = `${size}px ${fontFamily}`;
1739
- const distance = action.editHistory.reduce((distance2, {
1740
- data
1741
- }) => ({
1742
- x: distance2.x + data.x2 - data.x1,
1743
- y: distance2.y + data.y2 - data.y1
1744
- }), {
1745
- x: 0,
1746
- y: 0
1747
- });
1748
- text.split("\n").forEach((item, index2) => {
1749
- ctx.fillText(item, x + distance.x, y + distance.y + index2 * size);
1750
- });
1751
- }
1752
- function isHit$1(ctx, action, point) {
1753
- ctx.textAlign = "left";
1754
- ctx.textBaseline = "top";
1755
- ctx.font = `${action.data.size}px ${action.data.fontFamily}`;
1756
- let width = 0;
1757
- let height = 0;
1758
- action.data.text.split("\n").forEach((item) => {
1759
- const measured = ctx.measureText(item);
1760
- if (width < measured.width) {
1761
- width = measured.width;
1762
- }
1763
- height += action.data.size;
1764
- });
1765
- const {
1766
- x,
1767
- y
1768
- } = action.editHistory.reduce((distance, {
1769
- data
1770
- }) => ({
1771
- x: distance.x + data.x2 - data.x1,
1772
- y: distance.y + data.y2 - data.y1
1773
- }), {
1774
- x: 0,
1775
- y: 0
1776
- });
1777
- const left = action.data.x + x;
1778
- const top = action.data.y + y;
1779
- const right = left + width;
1780
- const bottom = top + height;
1781
- return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
1782
- }
1783
- function Text() {
1784
- const lang = useLang();
1785
- const [history, historyDispatcher] = useHistory();
1786
- const [bounds] = useBounds();
1787
- const [operation, operationDispatcher] = useOperation();
1788
- const [, cursorDispatcher] = useCursor();
1789
- const canvasContextRef = useCanvasContextRef();
1790
- const [size, setSize] = useState(3);
1791
- const [color, setColor] = useState("#ee5126");
1792
- const textRef = useRef(null);
1793
- const textEditRef = useRef(null);
1794
- const [textareaBounds, setTextareaBounds] = useState(null);
1795
- const [text, setText] = useState("");
1796
- const checked = operation === "Text";
1797
- const selectText = useCallback(() => {
1798
- operationDispatcher.set("Text");
1799
- cursorDispatcher.set("default");
1800
- }, [operationDispatcher, cursorDispatcher]);
1801
- const onSelectText = useCallback(() => {
1802
- if (checked) {
1803
- return;
1804
- }
1805
- selectText();
1806
- historyDispatcher.clearSelect();
1807
- }, [checked, selectText, historyDispatcher]);
1808
- const onSizeChange = useCallback((size2) => {
1809
- if (textRef.current) {
1810
- textRef.current.data.size = sizes[size2];
1811
- }
1812
- setSize(size2);
1813
- }, []);
1814
- const onColorChange = useCallback((color2) => {
1815
- if (textRef.current) {
1816
- textRef.current.data.color = color2;
1817
- }
1818
- setColor(color2);
1819
- }, []);
1820
- const onTextareaChange = useCallback((value) => {
1821
- setText(value);
1822
- if (checked && textRef.current) {
1823
- textRef.current.data.text = value;
1824
- }
1825
- }, [checked]);
1826
- const onTextareaBlur = useCallback(() => {
1827
- if (textRef.current && textRef.current.data.text) {
1828
- historyDispatcher.push(textRef.current);
1829
- }
1830
- textRef.current = null;
1831
- setText("");
1832
- setTextareaBounds(null);
1833
- }, [historyDispatcher]);
1834
- const onDrawSelect = useCallback((action, e) => {
1835
- if (action.name !== "Text") {
1836
- return;
1837
- }
1838
- selectText();
1839
- textEditRef.current = {
1840
- type: HistoryItemType.Edit,
1841
- data: {
1842
- x1: e.clientX,
1843
- y1: e.clientY,
1844
- x2: e.clientX,
1845
- y2: e.clientY
1846
- },
1847
- source: action
1848
- };
1849
- historyDispatcher.select(action);
1850
- }, [selectText, historyDispatcher]);
1851
- const onMousedown = useCallback((e) => {
1852
- if (!checked || !canvasContextRef.current || textRef.current || !bounds) {
1853
- return;
1854
- }
1855
- const {
1856
- left,
1857
- top
1858
- } = canvasContextRef.current.canvas.getBoundingClientRect();
1859
- const fontFamily = window.getComputedStyle(canvasContextRef.current.canvas).fontFamily;
1860
- const x = e.clientX - left;
1861
- const y = e.clientY - top;
1862
- textRef.current = {
1863
- name: "Text",
1864
- type: HistoryItemType.Source,
1865
- data: {
1866
- size: sizes[size],
1867
- color,
1868
- fontFamily,
1869
- x,
1870
- y,
1871
- text: ""
1872
- },
1873
- editHistory: [],
1874
- draw: draw$4,
1875
- isHit: isHit$1
1876
- };
1877
- setTextareaBounds({
1878
- x: e.clientX,
1879
- y: e.clientY,
1880
- maxWidth: bounds.width - x,
1881
- maxHeight: bounds.height - y
1882
- });
1883
- }, [checked, size, color, bounds, canvasContextRef]);
1884
- const onMousemove = useCallback((e) => {
1885
- if (!checked) {
1886
- return;
1887
- }
1888
- if (textEditRef.current) {
1889
- textEditRef.current.data.x2 = e.clientX;
1890
- textEditRef.current.data.y2 = e.clientY;
1891
- if (history.top !== textEditRef.current) {
1892
- textEditRef.current.source.editHistory.push(textEditRef.current);
1893
- historyDispatcher.push(textEditRef.current);
1894
- } else {
1895
- historyDispatcher.set(history);
1896
- }
1897
- }
1898
- }, [checked, history, historyDispatcher]);
1899
- const onMouseup = useCallback(() => {
1900
- if (!checked) {
1901
- return;
1902
- }
1903
- textEditRef.current = null;
1904
- }, [checked]);
1905
- useDrawSelect(onDrawSelect);
1906
- useCanvasMousedown(onMousedown);
1907
- useCanvasMousemove(onMousemove);
1908
- useCanvasMouseup(onMouseup);
1909
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ScreenshotsButton, {
1910
- title: lang.operation_text_title,
1911
- icon: "icon-text",
1912
- checked,
1913
- onClick: onSelectText,
1914
- option: /* @__PURE__ */ React.createElement(ScreenshotsSizeColor, {
1915
- size,
1916
- color,
1917
- onSizeChange,
1918
- onColorChange,
1919
- __self: this,
1920
- __source: {
1921
- fileName: _jsxFileName$6,
1922
- lineNumber: 261,
1923
- columnNumber: 11
1924
- }
1925
- }),
1926
- __self: this,
1927
- __source: {
1928
- fileName: _jsxFileName$6,
1929
- lineNumber: 255,
1930
- columnNumber: 7
1931
- }
1932
- }), checked && textareaBounds && /* @__PURE__ */ React.createElement(ScreenshotsTextarea, {
1933
- x: textareaBounds.x,
1934
- y: textareaBounds.y,
1935
- maxWidth: textareaBounds.maxWidth,
1936
- maxHeight: textareaBounds.maxHeight,
1937
- size: sizes[size],
1938
- color,
1939
- value: text,
1940
- onChange: onTextareaChange,
1941
- onBlur: onTextareaBlur,
1942
- __self: this,
1943
- __source: {
1944
- fileName: _jsxFileName$6,
1945
- lineNumber: 265,
1946
- columnNumber: 9
1947
- }
1948
- }));
1949
- }
1950
- const CircleRadius = 4;
1951
- function drawDragCircle(ctx, x, y) {
1952
- ctx.lineWidth = 1;
1953
- ctx.strokeStyle = "#000000";
1954
- ctx.fillStyle = "#ffffff";
1955
- ctx.beginPath();
1956
- ctx.arc(x, y, CircleRadius, 0, 2 * Math.PI);
1957
- ctx.fill();
1958
- ctx.stroke();
1959
- }
1960
- function isHit(ctx, action, point) {
1961
- action.draw(ctx, action);
1962
- const { data } = ctx.getImageData(point.x, point.y, 1, 1);
1963
- return data.some((val) => val !== 0);
1964
- }
1965
- function isHitCircle(canvas, e, point) {
1966
- if (!canvas) {
1967
- return false;
1968
- }
1969
- const { left, top } = canvas.getBoundingClientRect();
1970
- const x = e.clientX - left;
1971
- const y = e.clientY - top;
1972
- return (point.x - x) ** 2 + (point.y - y) ** 2 < CircleRadius ** 2;
1973
- }
1974
- function draw$3(ctx, action) {
1975
- const { size, color, points } = action.data;
1976
- ctx.lineCap = "round";
1977
- ctx.lineJoin = "round";
1978
- ctx.lineWidth = size;
1979
- ctx.strokeStyle = color;
1980
- const distance = action.editHistory.reduce((distance2, { data }) => ({
1981
- x: distance2.x + data.x2 - data.x1,
1982
- y: distance2.y + data.y2 - data.y1
1983
- }), { x: 0, y: 0 });
1984
- ctx.beginPath();
1985
- points.forEach((item, index2) => {
1986
- if (index2 === 0) {
1987
- ctx.moveTo(item.x + distance.x, item.y + distance.y);
1988
- } else {
1989
- ctx.lineTo(item.x + distance.x, item.y + distance.y);
1990
- }
1991
- });
1992
- ctx.stroke();
1993
- if (action.isSelected) {
1994
- ctx.lineWidth = 1;
1995
- ctx.strokeStyle = "#000000";
1996
- ctx.beginPath();
1997
- points.forEach((item, index2) => {
1998
- if (index2 === 0) {
1999
- ctx.moveTo(item.x + distance.x, item.y + distance.y);
2000
- } else {
2001
- ctx.lineTo(item.x + distance.x, item.y + distance.y);
2002
- }
2003
- });
2004
- ctx.stroke();
2005
- }
2006
- }
2007
- var _jsxFileName$5 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Brush/index.tsx";
2008
- function Brush() {
2009
- const lang = useLang();
2010
- const [, cursorDispatcher] = useCursor();
2011
- const [operation, operationDispatcher] = useOperation();
2012
- const canvasContextRef = useCanvasContextRef();
2013
- const [history, historyDispatcher] = useHistory();
2014
- const [size, setSize] = useState(3);
2015
- const [color, setColor] = useState("#ee5126");
2016
- const brushRef = useRef(null);
2017
- const brushEditRef = useRef(null);
2018
- const checked = operation === "Brush";
2019
- const selectBrush = useCallback(() => {
2020
- operationDispatcher.set("Brush");
2021
- cursorDispatcher.set("default");
2022
- }, [operationDispatcher, cursorDispatcher]);
2023
- const onSelectBrush = useCallback(() => {
2024
- if (checked) {
2025
- return;
2026
- }
2027
- selectBrush();
2028
- historyDispatcher.clearSelect();
2029
- }, [checked, selectBrush, historyDispatcher]);
2030
- const onDrawSelect = useCallback((action, e) => {
2031
- if (action.name !== "Brush") {
2032
- return;
2033
- }
2034
- selectBrush();
2035
- brushEditRef.current = {
2036
- type: HistoryItemType.Edit,
2037
- data: {
2038
- x1: e.clientX,
2039
- y1: e.clientY,
2040
- x2: e.clientX,
2041
- y2: e.clientY
2042
- },
2043
- source: action
2044
- };
2045
- historyDispatcher.select(action);
2046
- }, [selectBrush, historyDispatcher]);
2047
- const onMousedown = useCallback((e) => {
2048
- if (!checked || brushRef.current || !canvasContextRef.current) {
2049
- return;
2050
- }
2051
- const {
2052
- left,
2053
- top
2054
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2055
- brushRef.current = {
2056
- name: "Brush",
2057
- type: HistoryItemType.Source,
2058
- data: {
2059
- size,
2060
- color,
2061
- points: [{
2062
- x: e.clientX - left,
2063
- y: e.clientY - top
2064
- }]
2065
- },
2066
- editHistory: [],
2067
- draw: draw$3,
2068
- isHit
2069
- };
2070
- }, [checked, canvasContextRef, size, color]);
2071
- const onMousemove = useCallback((e) => {
2072
- if (!checked || !canvasContextRef.current) {
2073
- return;
2074
- }
2075
- if (brushEditRef.current) {
2076
- brushEditRef.current.data.x2 = e.clientX;
2077
- brushEditRef.current.data.y2 = e.clientY;
2078
- if (history.top !== brushEditRef.current) {
2079
- brushEditRef.current.source.editHistory.push(brushEditRef.current);
2080
- historyDispatcher.push(brushEditRef.current);
2081
- } else {
2082
- historyDispatcher.set(history);
2083
- }
2084
- } else if (brushRef.current) {
2085
- const {
2086
- left,
2087
- top
2088
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2089
- brushRef.current.data.points.push({
2090
- x: e.clientX - left,
2091
- y: e.clientY - top
2092
- });
2093
- if (history.top !== brushRef.current) {
2094
- historyDispatcher.push(brushRef.current);
2095
- } else {
2096
- historyDispatcher.set(history);
2097
- }
2098
- }
2099
- }, [checked, history, canvasContextRef, historyDispatcher]);
2100
- const onMouseup = useCallback(() => {
2101
- if (!checked) {
2102
- return;
2103
- }
2104
- if (brushRef.current) {
2105
- historyDispatcher.clearSelect();
2106
- }
2107
- brushRef.current = null;
2108
- brushEditRef.current = null;
2109
- }, [checked, historyDispatcher]);
2110
- useDrawSelect(onDrawSelect);
2111
- useCanvasMousedown(onMousedown);
2112
- useCanvasMousemove(onMousemove);
2113
- useCanvasMouseup(onMouseup);
2114
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
2115
- title: lang.operation_brush_title,
2116
- icon: "icon-brush",
2117
- checked,
2118
- onClick: onSelectBrush,
2119
- option: /* @__PURE__ */ React.createElement(ScreenshotsSizeColor, {
2120
- size,
2121
- color,
2122
- onSizeChange: setSize,
2123
- onColorChange: setColor,
2124
- __self: this,
2125
- __source: {
2126
- fileName: _jsxFileName$5,
2127
- lineNumber: 166,
2128
- columnNumber: 15
2129
- }
2130
- }),
2131
- __self: this,
2132
- __source: {
2133
- fileName: _jsxFileName$5,
2134
- lineNumber: 161,
2135
- columnNumber: 5
2136
- }
2137
- });
2138
- }
2139
- function getEditedArrowData(action) {
2140
- let { x1, y1, x2, y2 } = action.data;
2141
- action.editHistory.forEach(({ data }) => {
2142
- const x = data.x2 - data.x1;
2143
- const y = data.y2 - data.y1;
2144
- if (data.type === ArrowEditType.Move) {
2145
- x1 += x;
2146
- y1 += y;
2147
- x2 += x;
2148
- y2 += y;
2149
- } else if (data.type === ArrowEditType.MoveStart) {
2150
- x1 += x;
2151
- y1 += y;
2152
- } else if (data.type === ArrowEditType.MoveEnd) {
2153
- x2 += x;
2154
- y2 += y;
2155
- }
2156
- });
2157
- return __spreadProps(__spreadValues({}, action.data), {
2158
- x1,
2159
- x2,
2160
- y1,
2161
- y2
2162
- });
2163
- }
2164
- function draw$2(ctx, action) {
2165
- const { size, color, x1, x2, y1, y2 } = getEditedArrowData(action);
2166
- ctx.lineCap = "round";
2167
- ctx.lineJoin = "bevel";
2168
- ctx.lineWidth = size;
2169
- ctx.strokeStyle = color;
2170
- const dx = x2 - x1;
2171
- const dy = y2 - y1;
2172
- const length = size * 3;
2173
- const angle = Math.atan2(dy, dx);
2174
- ctx.beginPath();
2175
- ctx.moveTo(x1, y1);
2176
- ctx.lineTo(x2, y2);
2177
- ctx.lineTo(x2 - length * Math.cos(angle - Math.PI / 6), y2 - length * Math.sin(angle - Math.PI / 6));
2178
- ctx.moveTo(x2, y2);
2179
- ctx.lineTo(x2 - length * Math.cos(angle + Math.PI / 6), y2 - length * Math.sin(angle + Math.PI / 6));
2180
- ctx.stroke();
2181
- if (action.isSelected) {
2182
- drawDragCircle(ctx, x1, y1);
2183
- drawDragCircle(ctx, x2, y2);
2184
- }
2185
- }
2186
- var _jsxFileName$4 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Arrow/index.tsx";
2187
- var ArrowEditType;
2188
- (function(ArrowEditType2) {
2189
- ArrowEditType2[ArrowEditType2["Move"] = 0] = "Move";
2190
- ArrowEditType2[ArrowEditType2["MoveStart"] = 1] = "MoveStart";
2191
- ArrowEditType2[ArrowEditType2["MoveEnd"] = 2] = "MoveEnd";
2192
- })(ArrowEditType || (ArrowEditType = {}));
2193
- function Arrow() {
2194
- const lang = useLang();
2195
- const [, cursorDispatcher] = useCursor();
2196
- const [operation, operationDispatcher] = useOperation();
2197
- const [history, historyDispatcher] = useHistory();
2198
- const canvasContextRef = useCanvasContextRef();
2199
- const [size, setSize] = useState(3);
2200
- const [color, setColor] = useState("#ee5126");
2201
- const arrowRef = useRef(null);
2202
- const arrowEditRef = useRef(null);
2203
- const checked = operation === "Arrow";
2204
- const selectArrow = useCallback(() => {
2205
- operationDispatcher.set("Arrow");
2206
- cursorDispatcher.set("default");
2207
- }, [operationDispatcher, cursorDispatcher]);
2208
- const onSelectArrow = useCallback(() => {
2209
- if (checked) {
2210
- return;
2211
- }
2212
- selectArrow();
2213
- historyDispatcher.clearSelect();
2214
- }, [checked, selectArrow, historyDispatcher]);
2215
- const onDrawSelect = useCallback((action, e) => {
2216
- if (action.name !== "Arrow" || !canvasContextRef.current) {
2217
- return;
2218
- }
2219
- const source = action;
2220
- selectArrow();
2221
- const {
2222
- x1,
2223
- y1,
2224
- x2,
2225
- y2
2226
- } = getEditedArrowData(source);
2227
- let type = 0;
2228
- if (isHitCircle(canvasContextRef.current.canvas, e, {
2229
- x: x1,
2230
- y: y1
2231
- })) {
2232
- type = 1;
2233
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2234
- x: x2,
2235
- y: y2
2236
- })) {
2237
- type = 2;
2238
- }
2239
- arrowEditRef.current = {
2240
- type: HistoryItemType.Edit,
2241
- data: {
2242
- type,
2243
- x1: e.clientX,
2244
- y1: e.clientY,
2245
- x2: e.clientX,
2246
- y2: e.clientY
2247
- },
2248
- source
2249
- };
2250
- historyDispatcher.select(action);
2251
- }, [canvasContextRef, selectArrow, historyDispatcher]);
2252
- const onMousedown = useCallback((e) => {
2253
- if (!checked || arrowRef.current || !canvasContextRef.current) {
2254
- return;
2255
- }
2256
- const {
2257
- left,
2258
- top
2259
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2260
- arrowRef.current = {
2261
- name: "Arrow",
2262
- type: HistoryItemType.Source,
2263
- data: {
2264
- size,
2265
- color,
2266
- x1: e.clientX - left,
2267
- y1: e.clientY - top,
2268
- x2: e.clientX - left,
2269
- y2: e.clientY - top
2270
- },
2271
- editHistory: [],
2272
- draw: draw$2,
2273
- isHit
2274
- };
2275
- }, [checked, color, size, canvasContextRef]);
2276
- const onMousemove = useCallback((e) => {
2277
- if (!checked || !canvasContextRef.current) {
2278
- return;
2279
- }
2280
- if (arrowEditRef.current) {
2281
- arrowEditRef.current.data.x2 = e.clientX;
2282
- arrowEditRef.current.data.y2 = e.clientY;
2283
- if (history.top !== arrowEditRef.current) {
2284
- arrowEditRef.current.source.editHistory.push(arrowEditRef.current);
2285
- historyDispatcher.push(arrowEditRef.current);
2286
- } else {
2287
- historyDispatcher.set(history);
2288
- }
2289
- } else if (arrowRef.current) {
2290
- const {
2291
- left,
2292
- top
2293
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2294
- arrowRef.current.data.x2 = e.clientX - left;
2295
- arrowRef.current.data.y2 = e.clientY - top;
2296
- if (history.top !== arrowRef.current) {
2297
- historyDispatcher.push(arrowRef.current);
2298
- } else {
2299
- historyDispatcher.set(history);
2300
- }
2301
- }
2302
- }, [checked, history, canvasContextRef, historyDispatcher]);
2303
- const onMouseup = useCallback(() => {
2304
- if (!checked) {
2305
- return;
2306
- }
2307
- if (arrowRef.current) {
2308
- historyDispatcher.clearSelect();
2309
- }
2310
- arrowRef.current = null;
2311
- arrowEditRef.current = null;
2312
- }, [checked, historyDispatcher]);
2313
- useDrawSelect(onDrawSelect);
2314
- useCanvasMousedown(onMousedown);
2315
- useCanvasMousemove(onMousemove);
2316
- useCanvasMouseup(onMouseup);
2317
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
2318
- title: lang.operation_arrow_title,
2319
- icon: "icon-arrow",
2320
- checked,
2321
- onClick: onSelectArrow,
2322
- option: /* @__PURE__ */ React.createElement(ScreenshotsSizeColor, {
2323
- size,
2324
- color,
2325
- onSizeChange: setSize,
2326
- onColorChange: setColor,
2327
- __self: this,
2328
- __source: {
2329
- fileName: _jsxFileName$4,
2330
- lineNumber: 190,
2331
- columnNumber: 15
2332
- }
2333
- }),
2334
- __self: this,
2335
- __source: {
2336
- fileName: _jsxFileName$4,
2337
- lineNumber: 185,
2338
- columnNumber: 5
2339
- }
2340
- });
2341
- }
2342
- function getEditedEllipseData(action) {
2343
- let { x1, y1, x2, y2 } = action.data;
2344
- action.editHistory.forEach(({ data }) => {
2345
- const x = data.x2 - data.x1;
2346
- const y = data.y2 - data.y1;
2347
- if (data.type === EllipseEditType.Move) {
2348
- x1 += x;
2349
- y1 += y;
2350
- x2 += x;
2351
- y2 += y;
2352
- } else if (data.type === EllipseEditType.ResizeTop) {
2353
- y1 += y;
2354
- } else if (data.type === EllipseEditType.ResizeRightTop) {
2355
- x2 += x;
2356
- y1 += y;
2357
- } else if (data.type === EllipseEditType.ResizeRight) {
2358
- x2 += x;
2359
- } else if (data.type === EllipseEditType.ResizeRightBottom) {
2360
- x2 += x;
2361
- y2 += y;
2362
- } else if (data.type === EllipseEditType.ResizeBottom) {
2363
- y2 += y;
2364
- } else if (data.type === EllipseEditType.ResizeLeftBottom) {
2365
- x1 += x;
2366
- y2 += y;
2367
- } else if (data.type === EllipseEditType.ResizeLeft) {
2368
- x1 += x;
2369
- } else if (data.type === EllipseEditType.ResizeLeftTop) {
2370
- x1 += x;
2371
- y1 += y;
2372
- }
2373
- });
2374
- return __spreadProps(__spreadValues({}, action.data), {
2375
- x1,
2376
- x2,
2377
- y1,
2378
- y2
2379
- });
2380
- }
2381
- function draw$1(ctx, action) {
2382
- const { size, color, x1, y1, x2, y2 } = getEditedEllipseData(action);
2383
- ctx.lineCap = "butt";
2384
- ctx.lineJoin = "miter";
2385
- ctx.lineWidth = size;
2386
- ctx.strokeStyle = color;
2387
- const x = (x1 + x2) / 2;
2388
- const y = (y1 + y2) / 2;
2389
- const rx = Math.abs(x2 - x1) / 2;
2390
- const ry = Math.abs(y2 - y1) / 2;
2391
- const k = 0.5522848;
2392
- const ox = rx * k;
2393
- const oy = ry * k;
2394
- ctx.beginPath();
2395
- ctx.moveTo(x - rx, y);
2396
- ctx.bezierCurveTo(x - rx, y - oy, x - ox, y - ry, x, y - ry);
2397
- ctx.bezierCurveTo(x + ox, y - ry, x + rx, y - oy, x + rx, y);
2398
- ctx.bezierCurveTo(x + rx, y + oy, x + ox, y + ry, x, y + ry);
2399
- ctx.bezierCurveTo(x - ox, y + ry, x - rx, y + oy, x - rx, y);
2400
- ctx.closePath();
2401
- ctx.stroke();
2402
- if (action.isSelected) {
2403
- ctx.lineWidth = 1;
2404
- ctx.strokeStyle = "#000000";
2405
- ctx.fillStyle = "#ffffff";
2406
- ctx.beginPath();
2407
- ctx.moveTo(x1, y1);
2408
- ctx.lineTo(x2, y1);
2409
- ctx.lineTo(x2, y2);
2410
- ctx.lineTo(x1, y2);
2411
- ctx.closePath();
2412
- ctx.stroke();
2413
- drawDragCircle(ctx, (x1 + x2) / 2, y1);
2414
- drawDragCircle(ctx, x2, y1);
2415
- drawDragCircle(ctx, x2, (y1 + y2) / 2);
2416
- drawDragCircle(ctx, x2, y2);
2417
- drawDragCircle(ctx, (x1 + x2) / 2, y2);
2418
- drawDragCircle(ctx, x1, y2);
2419
- drawDragCircle(ctx, x1, (y1 + y2) / 2);
2420
- drawDragCircle(ctx, x1, y1);
2421
- }
2422
- }
2423
- var _jsxFileName$3 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Ellipse/index.tsx";
2424
- var EllipseEditType;
2425
- (function(EllipseEditType2) {
2426
- EllipseEditType2[EllipseEditType2["Move"] = 0] = "Move";
2427
- EllipseEditType2[EllipseEditType2["ResizeTop"] = 1] = "ResizeTop";
2428
- EllipseEditType2[EllipseEditType2["ResizeRightTop"] = 2] = "ResizeRightTop";
2429
- EllipseEditType2[EllipseEditType2["ResizeRight"] = 3] = "ResizeRight";
2430
- EllipseEditType2[EllipseEditType2["ResizeRightBottom"] = 4] = "ResizeRightBottom";
2431
- EllipseEditType2[EllipseEditType2["ResizeBottom"] = 5] = "ResizeBottom";
2432
- EllipseEditType2[EllipseEditType2["ResizeLeftBottom"] = 6] = "ResizeLeftBottom";
2433
- EllipseEditType2[EllipseEditType2["ResizeLeft"] = 7] = "ResizeLeft";
2434
- EllipseEditType2[EllipseEditType2["ResizeLeftTop"] = 8] = "ResizeLeftTop";
2435
- })(EllipseEditType || (EllipseEditType = {}));
2436
- function Ellipse() {
2437
- const lang = useLang();
2438
- const [history, historyDispatcher] = useHistory();
2439
- const [operation, operationDispatcher] = useOperation();
2440
- const [, cursorDispatcher] = useCursor();
2441
- const canvasContextRef = useCanvasContextRef();
2442
- const [size, setSize] = useState(3);
2443
- const [color, setColor] = useState("#ee5126");
2444
- const ellipseRef = useRef(null);
2445
- const ellipseEditRef = useRef(null);
2446
- const checked = operation === "Ellipse";
2447
- const selectEllipse = useCallback(() => {
2448
- operationDispatcher.set("Ellipse");
2449
- cursorDispatcher.set("crosshair");
2450
- }, [operationDispatcher, cursorDispatcher]);
2451
- const onSelectEllipse = useCallback(() => {
2452
- if (checked) {
2453
- return;
2454
- }
2455
- selectEllipse();
2456
- historyDispatcher.clearSelect();
2457
- }, [checked, selectEllipse, historyDispatcher]);
2458
- const onDrawSelect = useCallback((action, e) => {
2459
- if (action.name !== "Ellipse" || !canvasContextRef.current) {
2460
- return;
2461
- }
2462
- const source = action;
2463
- selectEllipse();
2464
- const {
2465
- x1,
2466
- y1,
2467
- x2,
2468
- y2
2469
- } = getEditedEllipseData(source);
2470
- let type = 0;
2471
- if (isHitCircle(canvasContextRef.current.canvas, e, {
2472
- x: (x1 + x2) / 2,
2473
- y: y1
2474
- })) {
2475
- type = 1;
2476
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2477
- x: x2,
2478
- y: y1
2479
- })) {
2480
- type = 2;
2481
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2482
- x: x2,
2483
- y: (y1 + y2) / 2
2484
- })) {
2485
- type = 3;
2486
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2487
- x: x2,
2488
- y: y2
2489
- })) {
2490
- type = 4;
2491
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2492
- x: (x1 + x2) / 2,
2493
- y: y2
2494
- })) {
2495
- type = 5;
2496
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2497
- x: x1,
2498
- y: y2
2499
- })) {
2500
- type = 6;
2501
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2502
- x: x1,
2503
- y: (y1 + y2) / 2
2504
- })) {
2505
- type = 7;
2506
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2507
- x: x1,
2508
- y: y1
2509
- })) {
2510
- type = 8;
2511
- }
2512
- ellipseEditRef.current = {
2513
- type: HistoryItemType.Edit,
2514
- data: {
2515
- type,
2516
- x1: e.clientX,
2517
- y1: e.clientY,
2518
- x2: e.clientX,
2519
- y2: e.clientY
2520
- },
2521
- source
2522
- };
2523
- historyDispatcher.select(action);
2524
- }, [canvasContextRef, selectEllipse, historyDispatcher]);
2525
- const onMousedown = useCallback((e) => {
2526
- if (!checked || !canvasContextRef.current || ellipseRef.current) {
2527
- return;
2528
- }
2529
- const {
2530
- left,
2531
- top
2532
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2533
- const x = e.clientX - left;
2534
- const y = e.clientY - top;
2535
- ellipseRef.current = {
2536
- name: "Ellipse",
2537
- type: HistoryItemType.Source,
2538
- data: {
2539
- size,
2540
- color,
2541
- x1: x,
2542
- y1: y,
2543
- x2: x,
2544
- y2: y
2545
- },
2546
- editHistory: [],
2547
- draw: draw$1,
2548
- isHit
2549
- };
2550
- }, [checked, size, color, canvasContextRef]);
2551
- const onMousemove = useCallback((e) => {
2552
- if (!checked || !canvasContextRef.current) {
2553
- return;
2554
- }
2555
- if (ellipseEditRef.current) {
2556
- ellipseEditRef.current.data.x2 = e.clientX;
2557
- ellipseEditRef.current.data.y2 = e.clientY;
2558
- if (history.top !== ellipseEditRef.current) {
2559
- ellipseEditRef.current.source.editHistory.push(ellipseEditRef.current);
2560
- historyDispatcher.push(ellipseEditRef.current);
2561
- } else {
2562
- historyDispatcher.set(history);
2563
- }
2564
- } else if (ellipseRef.current) {
2565
- const {
2566
- left,
2567
- top
2568
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2569
- ellipseRef.current.data.x2 = e.clientX - left;
2570
- ellipseRef.current.data.y2 = e.clientY - top;
2571
- if (history.top !== ellipseRef.current) {
2572
- historyDispatcher.push(ellipseRef.current);
2573
- } else {
2574
- historyDispatcher.set(history);
2575
- }
2576
- }
2577
- }, [checked, canvasContextRef, history, historyDispatcher]);
2578
- const onMouseup = useCallback(() => {
2579
- if (!checked) {
2580
- return;
2581
- }
2582
- if (ellipseRef.current) {
2583
- historyDispatcher.clearSelect();
2584
- }
2585
- ellipseRef.current = null;
2586
- ellipseEditRef.current = null;
2587
- }, [checked, historyDispatcher]);
2588
- useDrawSelect(onDrawSelect);
2589
- useCanvasMousedown(onMousedown);
2590
- useCanvasMousemove(onMousemove);
2591
- useCanvasMouseup(onMouseup);
2592
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
2593
- title: lang.operation_ellipse_title,
2594
- icon: "icon-ellipse",
2595
- checked,
2596
- onClick: onSelectEllipse,
2597
- option: /* @__PURE__ */ React.createElement(ScreenshotsSizeColor, {
2598
- size,
2599
- color,
2600
- onSizeChange: setSize,
2601
- onColorChange: setColor,
2602
- __self: this,
2603
- __source: {
2604
- fileName: _jsxFileName$3,
2605
- lineNumber: 242,
2606
- columnNumber: 15
2607
- }
2608
- }),
2609
- __self: this,
2610
- __source: {
2611
- fileName: _jsxFileName$3,
2612
- lineNumber: 237,
2613
- columnNumber: 5
2614
- }
2615
- });
2616
- }
2617
- function getEditedRectangleData(action) {
2618
- let { x1, y1, x2, y2 } = action.data;
2619
- action.editHistory.forEach(({ data }) => {
2620
- const x = data.x2 - data.x1;
2621
- const y = data.y2 - data.y1;
2622
- if (data.type === RectangleEditType.Move) {
2623
- x1 += x;
2624
- y1 += y;
2625
- x2 += x;
2626
- y2 += y;
2627
- } else if (data.type === RectangleEditType.ResizeTop) {
2628
- y1 += y;
2629
- } else if (data.type === RectangleEditType.ResizeRightTop) {
2630
- x2 += x;
2631
- y1 += y;
2632
- } else if (data.type === RectangleEditType.ResizeRight) {
2633
- x2 += x;
2634
- } else if (data.type === RectangleEditType.ResizeRightBottom) {
2635
- x2 += x;
2636
- y2 += y;
2637
- } else if (data.type === RectangleEditType.ResizeBottom) {
2638
- y2 += y;
2639
- } else if (data.type === RectangleEditType.ResizeLeftBottom) {
2640
- x1 += x;
2641
- y2 += y;
2642
- } else if (data.type === RectangleEditType.ResizeLeft) {
2643
- x1 += x;
2644
- } else if (data.type === RectangleEditType.ResizeLeftTop) {
2645
- x1 += x;
2646
- y1 += y;
2647
- }
2648
- });
2649
- return __spreadProps(__spreadValues({}, action.data), {
2650
- x1,
2651
- x2,
2652
- y1,
2653
- y2
2654
- });
2655
- }
2656
- function draw(ctx, action) {
2657
- const { size, color, x1, y1, x2, y2 } = getEditedRectangleData(action);
2658
- ctx.lineCap = "butt";
2659
- ctx.lineJoin = "miter";
2660
- ctx.lineWidth = size;
2661
- ctx.strokeStyle = color;
2662
- ctx.beginPath();
2663
- ctx.moveTo(x1, y1);
2664
- ctx.lineTo(x2, y1);
2665
- ctx.lineTo(x2, y2);
2666
- ctx.lineTo(x1, y2);
2667
- ctx.closePath();
2668
- ctx.stroke();
2669
- if (action.isSelected) {
2670
- ctx.lineWidth = 1;
2671
- ctx.strokeStyle = "#000000";
2672
- ctx.fillStyle = "#ffffff";
2673
- drawDragCircle(ctx, (x1 + x2) / 2, y1);
2674
- drawDragCircle(ctx, x2, y1);
2675
- drawDragCircle(ctx, x2, (y1 + y2) / 2);
2676
- drawDragCircle(ctx, x2, y2);
2677
- drawDragCircle(ctx, (x1 + x2) / 2, y2);
2678
- drawDragCircle(ctx, x1, y2);
2679
- drawDragCircle(ctx, x1, (y1 + y2) / 2);
2680
- drawDragCircle(ctx, x1, y1);
2681
- }
2682
- }
2683
- var _jsxFileName$2 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/operations/Rectangle/index.tsx";
2684
- var RectangleEditType;
2685
- (function(RectangleEditType2) {
2686
- RectangleEditType2[RectangleEditType2["Move"] = 0] = "Move";
2687
- RectangleEditType2[RectangleEditType2["ResizeTop"] = 1] = "ResizeTop";
2688
- RectangleEditType2[RectangleEditType2["ResizeRightTop"] = 2] = "ResizeRightTop";
2689
- RectangleEditType2[RectangleEditType2["ResizeRight"] = 3] = "ResizeRight";
2690
- RectangleEditType2[RectangleEditType2["ResizeRightBottom"] = 4] = "ResizeRightBottom";
2691
- RectangleEditType2[RectangleEditType2["ResizeBottom"] = 5] = "ResizeBottom";
2692
- RectangleEditType2[RectangleEditType2["ResizeLeftBottom"] = 6] = "ResizeLeftBottom";
2693
- RectangleEditType2[RectangleEditType2["ResizeLeft"] = 7] = "ResizeLeft";
2694
- RectangleEditType2[RectangleEditType2["ResizeLeftTop"] = 8] = "ResizeLeftTop";
2695
- })(RectangleEditType || (RectangleEditType = {}));
2696
- function Rectangle() {
2697
- const lang = useLang();
2698
- const [history, historyDispatcher] = useHistory();
2699
- const [operation, operationDispatcher] = useOperation();
2700
- const [, cursorDispatcher] = useCursor();
2701
- const canvasContextRef = useCanvasContextRef();
2702
- const [size, setSize] = useState(3);
2703
- const [color, setColor] = useState("#ee5126");
2704
- const rectangleRef = useRef(null);
2705
- const rectangleEditRef = useRef(null);
2706
- const checked = operation === "Rectangle";
2707
- const selectRectangle = useCallback(() => {
2708
- operationDispatcher.set("Rectangle");
2709
- cursorDispatcher.set("crosshair");
2710
- }, [operationDispatcher, cursorDispatcher]);
2711
- const onSelectRectangle = useCallback(() => {
2712
- if (checked) {
2713
- return;
2714
- }
2715
- selectRectangle();
2716
- historyDispatcher.clearSelect();
2717
- }, [checked, selectRectangle, historyDispatcher]);
2718
- const onDrawSelect = useCallback((action, e) => {
2719
- if (action.name !== "Rectangle" || !canvasContextRef.current) {
2720
- return;
2721
- }
2722
- const source = action;
2723
- selectRectangle();
2724
- const {
2725
- x1,
2726
- y1,
2727
- x2,
2728
- y2
2729
- } = getEditedRectangleData(source);
2730
- let type = 0;
2731
- if (isHitCircle(canvasContextRef.current.canvas, e, {
2732
- x: (x1 + x2) / 2,
2733
- y: y1
2734
- })) {
2735
- type = 1;
2736
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2737
- x: x2,
2738
- y: y1
2739
- })) {
2740
- type = 2;
2741
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2742
- x: x2,
2743
- y: (y1 + y2) / 2
2744
- })) {
2745
- type = 3;
2746
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2747
- x: x2,
2748
- y: y2
2749
- })) {
2750
- type = 4;
2751
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2752
- x: (x1 + x2) / 2,
2753
- y: y2
2754
- })) {
2755
- type = 5;
2756
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2757
- x: x1,
2758
- y: y2
2759
- })) {
2760
- type = 6;
2761
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2762
- x: x1,
2763
- y: (y1 + y2) / 2
2764
- })) {
2765
- type = 7;
2766
- } else if (isHitCircle(canvasContextRef.current.canvas, e, {
2767
- x: x1,
2768
- y: y1
2769
- })) {
2770
- type = 8;
2771
- }
2772
- rectangleEditRef.current = {
2773
- type: HistoryItemType.Edit,
2774
- data: {
2775
- type,
2776
- x1: e.clientX,
2777
- y1: e.clientY,
2778
- x2: e.clientX,
2779
- y2: e.clientY
2780
- },
2781
- source: action
2782
- };
2783
- historyDispatcher.select(action);
2784
- }, [canvasContextRef, selectRectangle, historyDispatcher]);
2785
- const onMousedown = useCallback((e) => {
2786
- if (!checked || !canvasContextRef.current || rectangleRef.current) {
2787
- return;
2788
- }
2789
- const {
2790
- left,
2791
- top
2792
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2793
- const x = e.clientX - left;
2794
- const y = e.clientY - top;
2795
- rectangleRef.current = {
2796
- name: "Rectangle",
2797
- type: HistoryItemType.Source,
2798
- data: {
2799
- size,
2800
- color,
2801
- x1: x,
2802
- y1: y,
2803
- x2: x,
2804
- y2: y
2805
- },
2806
- editHistory: [],
2807
- draw,
2808
- isHit
2809
- };
2810
- }, [checked, size, color, canvasContextRef]);
2811
- const onMousemove = useCallback((e) => {
2812
- if (!checked || !canvasContextRef.current) {
2813
- return;
2814
- }
2815
- if (rectangleEditRef.current) {
2816
- rectangleEditRef.current.data.x2 = e.clientX;
2817
- rectangleEditRef.current.data.y2 = e.clientY;
2818
- if (history.top !== rectangleEditRef.current) {
2819
- rectangleEditRef.current.source.editHistory.push(rectangleEditRef.current);
2820
- historyDispatcher.push(rectangleEditRef.current);
2821
- } else {
2822
- historyDispatcher.set(history);
2823
- }
2824
- } else if (rectangleRef.current) {
2825
- const {
2826
- left,
2827
- top
2828
- } = canvasContextRef.current.canvas.getBoundingClientRect();
2829
- const rectangleData = rectangleRef.current.data;
2830
- rectangleData.x2 = e.clientX - left;
2831
- rectangleData.y2 = e.clientY - top;
2832
- if (history.top !== rectangleRef.current) {
2833
- historyDispatcher.push(rectangleRef.current);
2834
- } else {
2835
- historyDispatcher.set(history);
2836
- }
2837
- }
2838
- }, [checked, canvasContextRef, history, historyDispatcher]);
2839
- const onMouseup = useCallback(() => {
2840
- if (!checked) {
2841
- return;
2842
- }
2843
- if (rectangleRef.current) {
2844
- historyDispatcher.clearSelect();
2845
- }
2846
- rectangleRef.current = null;
2847
- rectangleEditRef.current = null;
2848
- }, [checked, historyDispatcher]);
2849
- useDrawSelect(onDrawSelect);
2850
- useCanvasMousedown(onMousedown);
2851
- useCanvasMousemove(onMousemove);
2852
- useCanvasMouseup(onMouseup);
2853
- return /* @__PURE__ */ React.createElement(ScreenshotsButton, {
2854
- title: lang.operation_rectangle_title,
2855
- icon: "icon-rectangle",
2856
- checked,
2857
- onClick: onSelectRectangle,
2858
- option: /* @__PURE__ */ React.createElement(ScreenshotsSizeColor, {
2859
- size,
2860
- color,
2861
- onSizeChange: setSize,
2862
- onColorChange: setColor,
2863
- __self: this,
2864
- __source: {
2865
- fileName: _jsxFileName$2,
2866
- lineNumber: 242,
2867
- columnNumber: 15
2868
- }
2869
- }),
2870
- __self: this,
2871
- __source: {
2872
- fileName: _jsxFileName$2,
2873
- lineNumber: 237,
2874
- columnNumber: 5
2875
- }
2876
- });
2877
- }
2878
- var OperationButtons = [Rectangle, Ellipse, Arrow, Brush, Text, Mosaic, "|", Undo, Redo, "|", Save, Cancel, Ok];
2879
- var index = "";
2880
- var _jsxFileName$1 = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/ScreenshotsOperations/index.tsx";
2881
- const ScreenshotsOperationsCtx = React.createContext(null);
2882
- var ScreenshotsOperations = memo(function ScreenshotsOperations2() {
2883
- var _a, _b;
2884
- const {
2885
- width,
2886
- height
2887
- } = useStore();
2888
- const [bounds] = useBounds();
2889
- const [operationsRect, setOperationsRect] = useState(null);
2890
- const [position, setPosition] = useState(null);
2891
- const elRef = useRef(null);
2892
- const onDoubleClick = useCallback((e) => {
2893
- e.stopPropagation();
2894
- }, []);
2895
- const onContextMenu = useCallback((e) => {
2896
- e.preventDefault();
2897
- e.stopPropagation();
2898
- }, []);
2899
- useEffect(() => {
2900
- if (!bounds || !elRef.current) {
2901
- return;
2902
- }
2903
- const elRect = elRef.current.getBoundingClientRect();
2904
- let x = bounds.x + bounds.width - elRect.width;
2905
- let y = bounds.y + bounds.height + 10;
2906
- if (x < 0) {
2907
- x = 0;
2908
- }
2909
- if (x > width - elRect.width) {
2910
- x = width - elRect.width;
2911
- }
2912
- if (y > height - elRect.height) {
2913
- y = height - elRect.height - 10;
2914
- }
2915
- if ((position == null ? void 0 : position.x) !== x || position.y !== y) {
2916
- setPosition({
2917
- x,
2918
- y
2919
- });
2920
- }
2921
- if ((operationsRect == null ? void 0 : operationsRect.x) !== elRect.x || operationsRect.y !== elRect.y || operationsRect.width !== elRect.width || operationsRect.height !== elRect.height) {
2922
- setOperationsRect({
2923
- x: elRect.x,
2924
- y: elRect.y,
2925
- width: elRect.width,
2926
- height: elRect.height
2927
- });
2928
- }
2929
- });
2930
- if (!bounds) {
2931
- return null;
2932
- }
2933
- return /* @__PURE__ */ React.createElement(ScreenshotsOperationsCtx.Provider, {
2934
- value: operationsRect,
2935
- __self: this,
2936
- __source: {
2937
- fileName: _jsxFileName$1,
2938
- lineNumber: 76,
2939
- columnNumber: 5
2940
- }
2941
- }, /* @__PURE__ */ React.createElement("div", {
2942
- ref: elRef,
2943
- className: "screenshots-operations",
2944
- style: {
2945
- visibility: position ? "visible" : "hidden",
2946
- transform: `translate(${(_a = position == null ? void 0 : position.x) != null ? _a : 0}px, ${(_b = position == null ? void 0 : position.y) != null ? _b : 0}px)`
2947
- },
2948
- onDoubleClick,
2949
- onContextMenu,
2950
- __self: this,
2951
- __source: {
2952
- fileName: _jsxFileName$1,
2953
- lineNumber: 77,
2954
- columnNumber: 7
2955
- }
2956
- }, /* @__PURE__ */ React.createElement("div", {
2957
- className: "screenshots-operations-buttons",
2958
- __self: this,
2959
- __source: {
2960
- fileName: _jsxFileName$1,
2961
- lineNumber: 87,
2962
- columnNumber: 9
2963
- }
2964
- }, OperationButtons.map((OperationButton, index2) => {
2965
- if (OperationButton === "|") {
2966
- return /* @__PURE__ */ React.createElement("div", {
2967
- key: index2,
2968
- className: "screenshots-operations-divider",
2969
- __self: this,
2970
- __source: {
2971
- fileName: _jsxFileName$1,
2972
- lineNumber: 90,
2973
- columnNumber: 22
2974
- }
2975
- });
2976
- } else {
2977
- return /* @__PURE__ */ React.createElement(OperationButton, {
2978
- key: index2,
2979
- __self: this,
2980
- __source: {
2981
- fileName: _jsxFileName$1,
2982
- lineNumber: 92,
2983
- columnNumber: 22
2984
- }
2985
- });
2986
- }
2987
- }))));
2988
- });
2989
- function useGetLoadedImage(url) {
2990
- const [image, setImage] = useState(null);
2991
- useEffect(() => {
2992
- setImage(null);
2993
- if (url == null) {
2994
- return;
2995
- }
2996
- const $image = document.createElement("img");
2997
- const onLoad = () => setImage($image);
2998
- const onError = () => setImage(null);
2999
- $image.addEventListener("load", onLoad);
3000
- $image.addEventListener("error", onError);
3001
- $image.src = url;
3002
- return () => {
3003
- $image.removeEventListener("load", onLoad);
3004
- $image.removeEventListener("error", onError);
3005
- };
3006
- }, [url]);
3007
- return image;
3008
- }
3009
- var _jsxFileName = "/Users/nashaofu/Documents/GitHub/screenshots/packages/react-screenshots/src/Screenshots/index.tsx";
3010
- function Screenshots(_a) {
3011
- var _b = _a, {
3012
- url,
3013
- width,
3014
- height,
3015
- lang,
3016
- className
3017
- } = _b, props = __objRest(_b, [
3018
- "url",
3019
- "width",
3020
- "height",
3021
- "lang",
3022
- "className"
3023
- ]);
3024
- const image = useGetLoadedImage(url);
3025
- const canvasContextRef = useRef(null);
3026
- const emiterRef = useRef({});
3027
- const [history, setHistory] = useState({
3028
- index: -1,
3029
- stack: []
3030
- });
3031
- const [bounds, setBounds] = useState(null);
3032
- const [cursor, setCursor] = useState("move");
3033
- const [operation, setOperation] = useState(void 0);
3034
- const store = {
3035
- url,
3036
- width,
3037
- height,
3038
- image,
3039
- lang: __spreadValues(__spreadValues({}, zhCN), lang),
3040
- emiterRef,
3041
- canvasContextRef,
3042
- history,
3043
- bounds,
3044
- cursor,
3045
- operation
3046
- };
3047
- const call = useCallback((funcName, ...args) => {
3048
- const func = props[funcName];
3049
- if (typeof func === "function") {
3050
- func(...args);
3051
- }
3052
- }, [props]);
3053
- const dispatcher = {
3054
- call,
3055
- setHistory,
3056
- setBounds,
3057
- setCursor,
3058
- setOperation
3059
- };
3060
- const classNames = ["screenshots"];
3061
- if (className) {
3062
- classNames.push(className);
3063
- }
3064
- const reset = () => {
3065
- emiterRef.current = {};
3066
- setHistory({
3067
- index: -1,
3068
- stack: []
3069
- });
3070
- setBounds(null);
3071
- setCursor("move");
3072
- setOperation(void 0);
3073
- };
3074
- const onDoubleClick = useCallback(async (e) => {
3075
- if (e.button !== 0 || !image) {
3076
- return;
3077
- }
3078
- if (bounds && canvasContextRef.current) {
3079
- composeImage({
3080
- image,
3081
- width,
3082
- height,
3083
- history,
3084
- bounds
3085
- }).then((blob) => {
3086
- call("onOk", blob, bounds);
3087
- reset();
3088
- });
3089
- } else {
3090
- const targetBounds = {
3091
- x: 0,
3092
- y: 0,
3093
- width,
3094
- height
3095
- };
3096
- composeImage({
3097
- image,
3098
- width,
3099
- height,
3100
- history,
3101
- bounds: targetBounds
3102
- }).then((blob) => {
3103
- call("onOk", blob, targetBounds);
3104
- reset();
3105
- });
3106
- }
3107
- }, [image, history, bounds, width, height, call]);
3108
- const onContextMenu = useCallback((e) => {
3109
- if (e.button !== 2) {
3110
- return;
3111
- }
3112
- e.preventDefault();
3113
- call("onCancel");
3114
- reset();
3115
- }, [call]);
3116
- useLayoutEffect(() => {
3117
- reset();
3118
- }, [url]);
3119
- return /* @__PURE__ */ React.createElement(ScreenshotsContext.Provider, {
3120
- value: {
3121
- store,
3122
- dispatcher
3123
- },
3124
- __self: this,
3125
- __source: {
3126
- fileName: _jsxFileName,
3127
- lineNumber: 142,
3128
- columnNumber: 5
3129
- }
3130
- }, /* @__PURE__ */ React.createElement("div", {
3131
- className: classNames.join(" "),
3132
- style: {
3133
- width,
3134
- height
3135
- },
3136
- onDoubleClick,
3137
- onContextMenu,
3138
- __self: this,
3139
- __source: {
3140
- fileName: _jsxFileName,
3141
- lineNumber: 143,
3142
- columnNumber: 7
3143
- }
3144
- }, /* @__PURE__ */ React.createElement(ScreenshotsBackground, {
3145
- __self: this,
3146
- __source: {
3147
- fileName: _jsxFileName,
3148
- lineNumber: 149,
3149
- columnNumber: 9
3150
- }
3151
- }), /* @__PURE__ */ React.createElement(ScreenshotsCanvas, {
3152
- ref: canvasContextRef,
3153
- __self: this,
3154
- __source: {
3155
- fileName: _jsxFileName,
3156
- lineNumber: 150,
3157
- columnNumber: 9
3158
- }
3159
- }), /* @__PURE__ */ React.createElement(ScreenshotsOperations, {
3160
- __self: this,
3161
- __source: {
3162
- fileName: _jsxFileName,
3163
- lineNumber: 151,
3164
- columnNumber: 9
3165
- }
3166
- })));
3167
- }
3168
- export { Screenshots as default };