pixel-data-js 0.20.0 → 0.22.2

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 (65) hide show
  1. package/dist/index.dev.cjs +722 -357
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +709 -356
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +722 -357
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +283 -128
  8. package/dist/index.prod.js +709 -356
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/Algorithm/floodFillSelection.ts +12 -14
  12. package/src/BlendModes/toBlendModeIndexAndName.ts +0 -7
  13. package/src/Clipboard/writeImgBlobToClipboard.ts +1 -1
  14. package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +3 -0
  15. package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +3 -0
  16. package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +25 -6
  17. package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +89 -46
  18. package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +7 -7
  19. package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +81 -41
  20. package/src/History/PixelMutator/mutatorApplyRectBrush.ts +3 -0
  21. package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +18 -5
  22. package/src/History/PixelMutator/mutatorApplyRectPencil.ts +3 -0
  23. package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +19 -4
  24. package/src/History/PixelMutator/mutatorBlendColor.ts +4 -0
  25. package/src/History/PixelMutator/mutatorBlendPixelData.ts +4 -0
  26. package/src/History/PixelMutator/mutatorClear.ts +11 -8
  27. package/src/History/PixelMutator/mutatorFill.ts +4 -0
  28. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +28 -0
  29. package/src/History/PixelMutator/mutatorInvert.ts +3 -0
  30. package/src/ImageData/extractImageDataBuffer.ts +3 -3
  31. package/src/ImageData/{imageDataToAlphaMask.ts → imageDataToAlphaMaskBuffer.ts} +3 -4
  32. package/src/ImageData/resizeImageData.ts +3 -5
  33. package/src/ImageData/writeImageDataBuffer.ts +7 -7
  34. package/src/Mask/AlphaMask.ts +16 -0
  35. package/src/Mask/BinaryMask.ts +16 -0
  36. package/src/Mask/CircleBrushAlphaMask.ts +32 -0
  37. package/src/Mask/CircleBrushBinaryMask.ts +30 -0
  38. package/src/Mask/applyBinaryMaskToAlphaMask.ts +12 -9
  39. package/src/Mask/copyMask.ts +9 -3
  40. package/src/Mask/extractMask.ts +33 -31
  41. package/src/Mask/extractMaskBuffer.ts +87 -0
  42. package/src/Mask/invertMask.ts +6 -4
  43. package/src/Mask/mergeAlphaMasks.ts +11 -10
  44. package/src/Mask/mergeBinaryMasks.ts +10 -9
  45. package/src/Mask/setMaskData.ts +7 -0
  46. package/src/MaskRect/merge2BinaryMaskRects.ts +81 -0
  47. package/src/MaskRect/mergeBinaryMaskRects.ts +39 -0
  48. package/src/MaskRect/subtractBinaryMaskRects.ts +80 -0
  49. package/src/PixelData/applyAlphaMaskToPixelData.ts +8 -5
  50. package/src/PixelData/applyBinaryMaskToPixelData.ts +8 -9
  51. package/src/PixelData/applyCircleBrushToPixelData.ts +54 -62
  52. package/src/PixelData/blendColorPixelDataAlphaMask.ts +35 -25
  53. package/src/PixelData/blendColorPixelDataBinaryMask.ts +26 -19
  54. package/src/PixelData/blendPixelDataAlphaMask.ts +3 -3
  55. package/src/PixelData/blendPixelDataBinaryMask.ts +3 -3
  56. package/src/PixelData/clearPixelData.ts +2 -2
  57. package/src/PixelData/fillPixelData.ts +15 -42
  58. package/src/PixelData/fillPixelDataBinaryMask.ts +79 -0
  59. package/src/PixelData/invertPixelData.ts +3 -3
  60. package/src/PixelData/pixelDataToAlphaMask.ts +4 -2
  61. package/src/PixelData/writePixelDataBuffer.ts +2 -3
  62. package/src/Rect/getRectsBounds.ts +22 -0
  63. package/src/Rect/trimRectBounds.ts +20 -17
  64. package/src/_types.ts +55 -29
  65. package/src/index.ts +16 -1
@@ -0,0 +1,22 @@
1
+ import type { Rect } from '../_types'
2
+
3
+ export function getRectsBounds<T extends Rect>(rects: T[]): T {
4
+ if (rects.length === 1) return { ...rects[0] }
5
+ let minX = Infinity, minY = Infinity
6
+ let maxX = -Infinity, maxY = -Infinity
7
+
8
+ for (let i = 0; i < rects.length; i++) {
9
+ const r = rects[i]
10
+ const x1 = r.x
11
+ const y1 = r.y
12
+ const x2 = x1 + r.w
13
+ const y2 = y1 + r.h
14
+
15
+ if (x1 < minX) minX = x1
16
+ if (y1 < minY) minY = y1
17
+ if (x2 > maxX) maxX = x2
18
+ if (y2 > maxY) maxY = y2
19
+ }
20
+
21
+ return { x: minX, y: minY, w: maxX - minX, h: maxY - minY } as T
22
+ }
@@ -1,11 +1,11 @@
1
- import type { Rect, SelectionRect } from '../_types'
2
- import { extractMask } from '../Mask/extractMask'
1
+ import type { NullableMaskRect, Rect } from '../_types'
2
+ import { extractMaskBuffer } from '../Mask/extractMaskBuffer'
3
3
 
4
4
  /**
5
5
  * Intersects a target rectangle with a boundary, trimming dimensions and masks in-place.
6
6
  * This utility calculates the axis-aligned intersection between the `target` and `bounds`.
7
- * If the `target` includes a `mask` (as in a {@link SelectionRect}), the mask is physically
8
- * cropped and re-aligned using `extractMask` to match the new dimensions.
7
+ * If the `target` includes a `mask` (as in a {@link NullableMaskRect}), the mask is physically
8
+ * cropped and re-aligned using `extractMaskBuffer` to match the new dimensions.
9
9
  * @param target - The rectangle or selection object to be trimmed. **Note:** This object is mutated in-place.
10
10
  * @param bounds - The boundary rectangle defining the maximum allowable area (e.g., canvas dimensions).
11
11
  * @example
@@ -15,7 +15,7 @@ import { extractMask } from '../Mask/extractMask'
15
15
  * // The mask is cropped by 10 px on the top and left.
16
16
  * trimRectBounds(selection, canvas);
17
17
  */
18
- export function trimRectBounds<T extends Rect | SelectionRect>(
18
+ export function trimRectBounds<T extends NullableMaskRect>(
19
19
  target: T,
20
20
  bounds: Rect,
21
21
  ): void {
@@ -40,9 +40,8 @@ export function trimRectBounds<T extends Rect | SelectionRect>(
40
40
  target.w = 0
41
41
  target.h = 0
42
42
 
43
- if ('mask' in target && target.mask) {
44
- // This line is now hit by the 'empty intersection' test below
45
- target.mask = new Uint8Array(0)
43
+ if ('data' in target && target.data) {
44
+ target.data = new Uint8Array(0)
46
45
  }
47
46
 
48
47
  return
@@ -58,9 +57,9 @@ export function trimRectBounds<T extends Rect | SelectionRect>(
58
57
  target.w = intersectedW
59
58
  target.h = intersectedH
60
59
 
61
- if ('mask' in target && target.mask) {
62
- const currentMask = extractMask(
63
- target.mask,
60
+ if ('data' in target && target.data) {
61
+ const currentMaskBuffer = extractMaskBuffer(
62
+ target.data,
64
63
  originalW,
65
64
  offsetX,
66
65
  offsetY,
@@ -76,7 +75,7 @@ export function trimRectBounds<T extends Rect | SelectionRect>(
76
75
  // Scan for content
77
76
  for (let y = 0; y < intersectedH; y++) {
78
77
  for (let x = 0; x < intersectedW; x++) {
79
- if (currentMask[y * intersectedW + x] !== 0) {
78
+ if (currentMaskBuffer[y * intersectedW + x] !== 0) {
80
79
  if (x < minX) minX = x
81
80
  if (x > maxX) maxX = x
82
81
  if (y < minY) minY = y
@@ -89,8 +88,8 @@ export function trimRectBounds<T extends Rect | SelectionRect>(
89
88
  if (maxX === -1) {
90
89
  target.w = 0
91
90
  target.h = 0
92
- // This covers the specific line you mentioned
93
- target.mask = new Uint8Array(0)
91
+ target.data = new Uint8Array(0)
92
+
94
93
  return
95
94
  }
96
95
 
@@ -99,20 +98,24 @@ export function trimRectBounds<T extends Rect | SelectionRect>(
99
98
 
100
99
  // Only shift and crop if the content is smaller than the intersection
101
100
  if (finalW !== intersectedW || finalH !== intersectedH) {
102
- target.mask = extractMask(
103
- currentMask,
101
+ const newMaskBuffer = extractMaskBuffer(
102
+ currentMaskBuffer,
104
103
  intersectedW,
105
104
  minX,
106
105
  minY,
107
106
  finalW,
108
107
  finalH,
109
108
  )
109
+
110
110
  target.x += minX
111
111
  target.y += minY
112
112
  target.w = finalW
113
113
  target.h = finalH
114
+ target.data = newMaskBuffer
114
115
  } else {
115
- target.mask = currentMask
116
+ target.w = finalW
117
+ target.h = finalH
118
+ target.data = currentMaskBuffer
116
119
  }
117
120
  }
118
121
  }
package/src/_types.ts CHANGED
@@ -47,14 +47,6 @@ export type Rect = {
47
47
  h: number
48
48
  }
49
49
 
50
- export type BinaryMaskRect = {
51
- x: number
52
- y: number
53
- w: number
54
- h: number
55
- mask: BinaryMask
56
- }
57
-
58
50
  /**
59
51
  * Defines how mask values should be interpreted during a draw operation.
60
52
  */
@@ -71,12 +63,36 @@ export enum MaskType {
71
63
  BINARY
72
64
  }
73
65
 
66
+ export interface Mask {
67
+ readonly type: MaskType
68
+ readonly data: Uint8Array
69
+ readonly w: number
70
+ readonly h: number
71
+ }
72
+
74
73
  /** Strictly 0 or 1 */
75
- export type BinaryMask = Uint8Array & { readonly __brand: 'Binary' }
74
+ export interface BinaryMask extends Mask {
75
+ readonly type: MaskType.BINARY
76
+ }
77
+
76
78
  /** Strictly 0-255 */
77
- export type AlphaMask = Uint8Array & { readonly __brand: 'Alpha' }
79
+ export interface AlphaMask extends Mask {
80
+ readonly type: MaskType.ALPHA
81
+ }
78
82
 
79
- export type AnyMask = BinaryMask | AlphaMask
83
+ interface CircleBrush {
84
+ readonly size: number
85
+ readonly radius: number
86
+ readonly minOffset: number
87
+ }
88
+
89
+ export interface CircleBrushAlphaMask extends CircleBrush, AlphaMask {
90
+ }
91
+
92
+ export interface CircleBrushBinaryMask extends CircleBrush, BinaryMask {
93
+ }
94
+
95
+ export type CircleBrushMask = CircleBrushAlphaMask | CircleBrushBinaryMask
80
96
 
81
97
  /**
82
98
  * Configuration for pixel manipulation operations.
@@ -122,14 +138,6 @@ export interface MaskOffset {
122
138
  my?: number
123
139
  }
124
140
 
125
- export interface MaskOffsetWidth {
126
- /**
127
- * Mask width.
128
- * @default value of `w`
129
- */
130
- mw?: number
131
- }
132
-
133
141
  export interface InvertMask {
134
142
 
135
143
  /**
@@ -139,7 +147,7 @@ export interface InvertMask {
139
147
  invertMask?: boolean
140
148
  }
141
149
 
142
- export interface Alpha {
150
+ interface Alpha {
143
151
  /**
144
152
  * Overall layer opacity 0-255.
145
153
  * @default 255
@@ -147,14 +155,14 @@ export interface Alpha {
147
155
  alpha?: number
148
156
  }
149
157
 
150
- export interface ApplyMaskToPixelDataOptions extends PixelRect, Alpha, MaskOffsetWidth, MaskOffset, InvertMask {
158
+ export interface ApplyMaskToPixelDataOptions extends PixelRect, Alpha, MaskOffset, InvertMask {
151
159
  }
152
160
 
153
161
  export interface MergeAlphaMasksOptions extends PixelRect, Alpha, MaskOffset, InvertMask {
154
162
 
155
163
  }
156
164
 
157
- export interface PixelMutateOptions extends PixelRect, MaskOffset, MaskOffsetWidth, InvertMask {
165
+ export interface PixelMutateOptions extends PixelRect, MaskOffset, InvertMask {
158
166
  /** An optional mask to restrict where pixels are mutated. */
159
167
  mask?: BinaryMask | null
160
168
  }
@@ -187,7 +195,7 @@ export interface PixelBlendOptions extends PixelRect, Alpha, BasePixelBlendOptio
187
195
 
188
196
  }
189
197
 
190
- export interface PixelBlendMaskOptions extends PixelRect, Alpha, MaskOffsetWidth, MaskOffset, InvertMask, BasePixelBlendOptions {
198
+ export interface PixelBlendMaskOptions extends PixelRect, Alpha, MaskOffset, InvertMask, BasePixelBlendOptions {
191
199
  }
192
200
 
193
201
  /**
@@ -201,17 +209,35 @@ export interface ColorBlendOptions extends PixelRect, Alpha {
201
209
  blendFn?: BlendColor32
202
210
  }
203
211
 
204
- export interface ColorBlendMaskOptions extends ColorBlendOptions, MaskOffset, MaskOffsetWidth, InvertMask {
212
+ export interface ColorBlendMaskOptions extends ColorBlendOptions, MaskOffset, InvertMask {
213
+ }
214
+
215
+ export type BinaryMaskRect = Rect & {
216
+ type: MaskType.BINARY
217
+ data: Uint8Array
205
218
  }
206
219
 
207
- export type SelectionRect = Rect & ({
208
- mask: Uint8Array,
209
- maskType: MaskType,
220
+ export type NullableBinaryMaskRect = Rect & ({
221
+ type: MaskType.BINARY
222
+ data: Uint8Array
210
223
  } | {
211
- mask?: null
212
- maskType?: null,
224
+ type?: null
225
+ data?: null
213
226
  })
214
227
 
228
+
229
+ export type NullableMaskRect = Rect & ({
230
+ type: MaskType
231
+ data: Uint8Array
232
+ } | {
233
+ type?: null
234
+ data?: null
235
+ })
236
+
237
+ export type AlphaMaskRect = Rect & {
238
+ mask: AlphaMask
239
+ }
240
+
215
241
  export type HistoryMutator<T extends {}, D extends {}> = (writer: PixelWriter<any>, deps?: Partial<D>) => T
216
242
 
217
243
  export interface IPixelData {
package/src/index.ts CHANGED
@@ -45,12 +45,13 @@ export * from './History/PixelMutator/mutatorBlendPixel'
45
45
  export * from './History/PixelMutator/mutatorBlendPixelData'
46
46
  export * from './History/PixelMutator/mutatorClear'
47
47
  export * from './History/PixelMutator/mutatorFill'
48
+ export * from './History/PixelMutator/mutatorFillBinaryMask'
48
49
  export * from './History/PixelMutator/mutatorInvert'
49
50
 
50
51
  export * from './ImageData/copyImageData'
51
52
  export * from './ImageData/extractImageDataBuffer'
52
53
  export * from './ImageData/ImageDataLike'
53
- export * from './ImageData/imageDataToAlphaMask'
54
+ export * from './ImageData/imageDataToAlphaMaskBuffer'
54
55
  export * from './ImageData/imageDataToDataUrl'
55
56
  export * from './ImageData/imageDataToImgBlob'
56
57
  export * from './ImageData/imageDataToUInt32Array'
@@ -74,12 +75,24 @@ export * from './Input/fileInputChangeToImageData'
74
75
  export * from './Input/fileToImageData'
75
76
  export * from './Input/getSupportedRasterFormats'
76
77
 
78
+ export * from './Mask/AlphaMask'
79
+ export * from './Mask/BinaryMask'
80
+
81
+ export * from './Mask/CircleBrushAlphaMask'
82
+ export * from './Mask/CircleBrushBinaryMask'
83
+
77
84
  export * from './Mask/applyBinaryMaskToAlphaMask'
78
85
  export * from './Mask/copyMask'
79
86
  export * from './Mask/extractMask'
87
+ export * from './Mask/extractMaskBuffer'
80
88
  export * from './Mask/invertMask'
81
89
  export * from './Mask/mergeAlphaMasks'
82
90
  export * from './Mask/mergeBinaryMasks'
91
+ export * from './Mask/setMaskData'
92
+
93
+ export { subtractBinaryMaskRects } from './MaskRect/subtractBinaryMaskRects'
94
+ export * from './MaskRect/merge2BinaryMaskRects'
95
+ export * from './MaskRect/mergeBinaryMaskRects'
83
96
 
84
97
  export * from './PixelData/applyAlphaMaskToPixelData'
85
98
  export * from './PixelData/applyBinaryMaskToPixelData'
@@ -98,6 +111,7 @@ export * from './PixelData/clearPixelData'
98
111
  export * from './PixelData/extractPixelData'
99
112
  export * from './PixelData/extractPixelDataBuffer'
100
113
  export * from './PixelData/fillPixelData'
114
+ export * from './PixelData/fillPixelDataBinaryMask'
101
115
  export * from './PixelData/invertPixelData'
102
116
  export * from './PixelData/PixelBuffer32'
103
117
  export * from './PixelData/pixelDataToAlphaMask'
@@ -110,6 +124,7 @@ export * from './Rect/getCircleBrushOrPencilBounds'
110
124
  export * from './Rect/getCircleBrushOrPencilStrokeBounds'
111
125
  export * from './Rect/getRectBrushOrPencilBounds'
112
126
  export * from './Rect/getRectBrushOrPencilStrokeBounds'
127
+ export * from './Rect/getRectsBounds'
113
128
  export * from './Rect/trimRectBounds'
114
129
 
115
130
  export * from './Algorithm/forEachLinePoint'