@lvl99dotcom/paintcanvas 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +131 -2
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +5 -0
  5. package/dist/lib/brushes/BrushTipCache/index.d.ts +32 -0
  6. package/dist/lib/brushes/BrushTipCache/index.js +60 -0
  7. package/dist/lib/brushes/StrokeEngine/index.d.ts +171 -0
  8. package/dist/lib/brushes/StrokeEngine/index.js +324 -0
  9. package/dist/lib/brushes/StrokePath/index.d.ts +53 -0
  10. package/dist/lib/brushes/StrokePath/index.js +161 -0
  11. package/dist/lib/brushes/StrokeSampler/index.d.ts +55 -0
  12. package/dist/lib/brushes/StrokeSampler/index.js +75 -0
  13. package/dist/lib/brushes/authors/index.d.ts +55 -0
  14. package/dist/lib/brushes/authors/index.js +60 -0
  15. package/dist/lib/brushes/configRanges/index.d.ts +52 -0
  16. package/dist/lib/brushes/configRanges/index.js +206 -0
  17. package/dist/lib/brushes/index.d.ts +5 -0
  18. package/dist/lib/brushes/index.js +19 -0
  19. package/dist/lib/brushes/params/index.d.ts +108 -0
  20. package/dist/lib/brushes/params/index.js +139 -0
  21. package/dist/lib/brushes/presetFile/index.d.ts +32 -0
  22. package/dist/lib/brushes/presetFile/index.js +55 -0
  23. package/dist/lib/brushes/presets/drawing/brush-pen.js +3 -0
  24. package/dist/lib/brushes/presets/drawing/felt-pen.js +3 -0
  25. package/dist/lib/brushes/presets/drawing/index.d.ts +13 -0
  26. package/dist/lib/brushes/presets/drawing/index.js +88 -0
  27. package/dist/lib/brushes/presets/drawing/pencil-2b.js +3 -0
  28. package/dist/lib/brushes/presets/drawing/pencil-hb.js +3 -0
  29. package/dist/lib/brushes/presets/painting/grass.js +3 -0
  30. package/dist/lib/brushes/presets/painting/hair.js +3 -0
  31. package/dist/lib/brushes/presets/painting/index.d.ts +18 -0
  32. package/dist/lib/brushes/presets/painting/index.js +118 -0
  33. package/dist/lib/brushes/presets/painting/splatter.js +3 -0
  34. package/dist/lib/brushes/presets/painting/textured-paint.js +3 -0
  35. package/dist/lib/brushes/presets/painting/watery-paint.js +3 -0
  36. package/dist/lib/brushes/presets/round/index.d.ts +9 -0
  37. package/dist/lib/brushes/presets/round/index.js +44 -0
  38. package/dist/lib/brushes/presets/round/round.js +3 -0
  39. package/dist/lib/brushes/presets/round/soft-round.js +3 -0
  40. package/dist/lib/brushes/presets/sized/index.d.ts +20 -0
  41. package/dist/lib/brushes/presets/sized/index.js +30 -0
  42. package/dist/lib/brushes/presets/sketching/index.d.ts +14 -0
  43. package/dist/lib/brushes/presets/sketching/index.js +107 -0
  44. package/dist/lib/brushes/presets/square/index.d.ts +7 -0
  45. package/dist/lib/brushes/presets/square/index.js +22 -0
  46. package/dist/lib/brushes/presets/square/square.js +3 -0
  47. package/dist/lib/brushes/shapeImage/index.d.ts +40 -0
  48. package/dist/lib/brushes/shapeImage/index.js +61 -0
  49. package/dist/lib/brushes/types/index.d.ts +243 -0
  50. package/dist/lib/brushes/types/index.js +20 -0
  51. package/dist/lib/classes/BackgroundWork/index.d.ts +55 -0
  52. package/dist/lib/classes/BackgroundWork/index.js +97 -0
  53. package/dist/lib/classes/BrushSettings/index.d.ts +91 -0
  54. package/dist/lib/classes/BrushSettings/index.js +152 -0
  55. package/dist/lib/classes/CustomPresets/index.d.ts +53 -0
  56. package/dist/lib/classes/CustomPresets/index.js +71 -0
  57. package/dist/lib/classes/ExternalSheets/index.d.ts +64 -0
  58. package/dist/lib/classes/ExternalSheets/index.js +112 -0
  59. package/dist/lib/classes/GestureTracker/index.d.ts +62 -0
  60. package/dist/lib/classes/GestureTracker/index.js +122 -0
  61. package/dist/lib/classes/History/index.d.ts +83 -0
  62. package/dist/lib/classes/History/index.js +126 -0
  63. package/dist/lib/classes/HistoryGuard/index.d.ts +58 -0
  64. package/dist/lib/classes/HistoryGuard/index.js +97 -0
  65. package/dist/lib/classes/InputSettings/index.d.ts +74 -0
  66. package/dist/lib/classes/InputSettings/index.js +101 -0
  67. package/dist/lib/classes/KeyboardShortcuts/index.d.ts +48 -0
  68. package/dist/lib/classes/KeyboardShortcuts/index.js +137 -0
  69. package/dist/lib/classes/Layer/index.d.ts +86 -0
  70. package/dist/lib/classes/Layer/index.js +111 -0
  71. package/dist/lib/classes/LayerAutosave/index.d.ts +180 -0
  72. package/dist/lib/classes/LayerAutosave/index.js +346 -0
  73. package/dist/lib/classes/LayerStack/index.d.ts +177 -0
  74. package/dist/lib/classes/LayerStack/index.js +394 -0
  75. package/dist/lib/classes/PaintCanvas/index.d.ts +537 -0
  76. package/dist/lib/classes/PaintCanvas/index.js +965 -0
  77. package/dist/lib/classes/StrokeLog/index.d.ts +149 -0
  78. package/dist/lib/classes/StrokeLog/index.js +257 -0
  79. package/dist/lib/classes/Viewport/index.d.ts +108 -0
  80. package/dist/lib/classes/Viewport/index.js +194 -0
  81. package/dist/lib/document/index.d.ts +17 -0
  82. package/dist/lib/document/index.js +25 -0
  83. package/dist/lib/document/schema.d.ts +132 -0
  84. package/dist/lib/document/schema.js +110 -0
  85. package/dist/lib/i18n/index.d.ts +131 -0
  86. package/dist/lib/i18n/index.js +277 -0
  87. package/dist/lib/image/index.d.ts +90 -0
  88. package/dist/lib/image/index.js +147 -0
  89. package/dist/lib/messages/PatchSender/index.d.ts +75 -0
  90. package/dist/lib/messages/PatchSender/index.js +125 -0
  91. package/dist/lib/messages/index.d.ts +26 -0
  92. package/dist/lib/messages/index.js +59 -0
  93. package/dist/lib/messages/schema.d.ts +1775 -0
  94. package/dist/lib/messages/schema.js +192 -0
  95. package/dist/lib/presets/index.d.ts +32 -0
  96. package/dist/lib/presets/index.js +35 -0
  97. package/dist/lib/presets/schema.d.ts +753 -0
  98. package/dist/lib/presets/schema.js +181 -0
  99. package/dist/lib/rendering/BrushTip/index.d.ts +63 -0
  100. package/dist/lib/rendering/BrushTip/index.js +112 -0
  101. package/dist/lib/rendering/checkerboard/index.d.ts +22 -0
  102. package/dist/lib/rendering/checkerboard/index.js +31 -0
  103. package/dist/lib/rendering/compositing/index.d.ts +64 -0
  104. package/dist/lib/rendering/compositing/index.js +124 -0
  105. package/dist/lib/rendering/cursor/index.d.ts +14 -0
  106. package/dist/lib/rendering/cursor/index.js +39 -0
  107. package/dist/lib/rendering/cursors/index.d.ts +18 -0
  108. package/dist/lib/rendering/cursors/index.js +23 -0
  109. package/dist/lib/rendering/maskOutline/index.d.ts +22 -0
  110. package/dist/lib/rendering/maskOutline/index.js +78 -0
  111. package/dist/lib/rendering/outline/index.d.ts +36 -0
  112. package/dist/lib/rendering/outline/index.js +120 -0
  113. package/dist/lib/rendering/sample/index.d.ts +55 -0
  114. package/dist/lib/rendering/sample/index.js +83 -0
  115. package/dist/lib/rendering/screenshot/index.d.ts +67 -0
  116. package/dist/lib/rendering/screenshot/index.js +96 -0
  117. package/dist/lib/rendering/transformBox/index.d.ts +10 -0
  118. package/dist/lib/rendering/transformBox/index.js +57 -0
  119. package/dist/lib/selection/Lasso/index.d.ts +70 -0
  120. package/dist/lib/selection/Lasso/index.js +156 -0
  121. package/dist/lib/selection/Selection/index.d.ts +86 -0
  122. package/dist/lib/selection/Selection/index.js +228 -0
  123. package/dist/lib/selection/geometry/index.d.ts +37 -0
  124. package/dist/lib/selection/geometry/index.js +57 -0
  125. package/dist/lib/storage/index.d.ts +63 -0
  126. package/dist/lib/storage/index.js +114 -0
  127. package/dist/lib/transform/Transformer/index.d.ts +124 -0
  128. package/dist/lib/transform/Transformer/index.js +286 -0
  129. package/dist/lib/transform/geometry/index.d.ts +95 -0
  130. package/dist/lib/transform/geometry/index.js +258 -0
  131. package/dist/lib/utils/array/index.d.ts +10 -0
  132. package/dist/lib/utils/array/index.js +21 -0
  133. package/dist/lib/utils/gestures/index.d.ts +35 -0
  134. package/dist/lib/utils/gestures/index.js +81 -0
  135. package/dist/lib/utils/navigation/index.d.ts +51 -0
  136. package/dist/lib/utils/navigation/index.js +59 -0
  137. package/dist/lib/utils/random/index.d.ts +18 -0
  138. package/dist/lib/utils/random/index.js +27 -0
  139. package/dist/lib/utils/shortcuts/index.d.ts +74 -0
  140. package/dist/lib/utils/shortcuts/index.js +189 -0
  141. package/dist/lib/validation/validators.generated.d.ts +27 -0
  142. package/dist/lib/validation/validators.generated.js +19826 -0
  143. package/dist/locales/en-GB.js +181 -0
  144. package/dist/locales/en-US.js +181 -0
  145. package/dist/locales/fr.js +181 -0
  146. package/dist/locales/ja.js +181 -0
  147. package/dist/locales/ko.js +181 -0
  148. package/dist/locales/zh-Hans.js +181 -0
  149. package/dist/locales/zh-Hant.js +181 -0
  150. package/dist/package.js +3 -0
  151. package/dist/testing/app.d.ts +7 -0
  152. package/dist/testing/app.js +16 -0
  153. package/dist/testing/elements.d.ts +42 -0
  154. package/dist/testing/elements.js +58 -0
  155. package/dist/testing/fakeCanvas.d.ts +21 -0
  156. package/dist/testing/fakeCanvas.js +26 -0
  157. package/dist/testing/layerStore.d.ts +26 -0
  158. package/dist/testing/layerStore.js +43 -0
  159. package/dist/testing/locks.d.ts +15 -0
  160. package/dist/testing/locks.js +41 -0
  161. package/dist/testing/recordingCanvas.d.ts +14 -0
  162. package/dist/testing/recordingCanvas.js +28 -0
  163. package/dist/testing/recordingContext.d.ts +10 -0
  164. package/dist/testing/recordingContext.js +19 -0
  165. package/dist/ui/ChangeController/index.d.ts +40 -0
  166. package/dist/ui/ChangeController/index.js +62 -0
  167. package/dist/ui/base/index.d.ts +69 -0
  168. package/dist/ui/base/index.js +94 -0
  169. package/dist/ui/elements/PaintCanvas/index.d.ts +249 -0
  170. package/dist/ui/elements/PaintCanvas/index.js +584 -0
  171. package/dist/ui/elements/PaintCanvas/style.js +3 -0
  172. package/dist/ui/elements/PcBrushConfig/index.d.ts +130 -0
  173. package/dist/ui/elements/PcBrushConfig/index.js +465 -0
  174. package/dist/ui/elements/PcBrushConfig/style.js +3 -0
  175. package/dist/ui/elements/PcBrushMenu/index.d.ts +121 -0
  176. package/dist/ui/elements/PcBrushMenu/index.js +362 -0
  177. package/dist/ui/elements/PcBrushMenu/style.js +3 -0
  178. package/dist/ui/elements/PcBrushTest/index.d.ts +71 -0
  179. package/dist/ui/elements/PcBrushTest/index.js +136 -0
  180. package/dist/ui/elements/PcBrushTest/style.js +3 -0
  181. package/dist/ui/elements/PcButton/index.d.ts +57 -0
  182. package/dist/ui/elements/PcButton/index.js +124 -0
  183. package/dist/ui/elements/PcButtonGroup/index.d.ts +44 -0
  184. package/dist/ui/elements/PcButtonGroup/index.js +93 -0
  185. package/dist/ui/elements/PcCanvas/index.d.ts +356 -0
  186. package/dist/ui/elements/PcCanvas/index.js +1004 -0
  187. package/dist/ui/elements/PcCanvas/style.js +3 -0
  188. package/dist/ui/elements/PcCanvasMap/index.d.ts +96 -0
  189. package/dist/ui/elements/PcCanvasMap/index.js +187 -0
  190. package/dist/ui/elements/PcCanvasMap/style.js +3 -0
  191. package/dist/ui/elements/PcContextMenu/index.d.ts +72 -0
  192. package/dist/ui/elements/PcContextMenu/index.js +148 -0
  193. package/dist/ui/elements/PcDialog/index.d.ts +63 -0
  194. package/dist/ui/elements/PcDialog/index.js +114 -0
  195. package/dist/ui/elements/PcIcon/index.d.ts +36 -0
  196. package/dist/ui/elements/PcIcon/index.js +43 -0
  197. package/dist/ui/elements/PcIconToggle/index.d.ts +46 -0
  198. package/dist/ui/elements/PcIconToggle/index.js +87 -0
  199. package/dist/ui/elements/PcInfoTip/index.d.ts +40 -0
  200. package/dist/ui/elements/PcInfoTip/index.js +95 -0
  201. package/dist/ui/elements/PcInputSettings/index.d.ts +69 -0
  202. package/dist/ui/elements/PcInputSettings/index.js +154 -0
  203. package/dist/ui/elements/PcLayerItem/index.d.ts +221 -0
  204. package/dist/ui/elements/PcLayerItem/index.js +561 -0
  205. package/dist/ui/elements/PcLayerItem/style.js +3 -0
  206. package/dist/ui/elements/PcLayersMenu/index.d.ts +108 -0
  207. package/dist/ui/elements/PcLayersMenu/index.js +208 -0
  208. package/dist/ui/elements/PcLayersMenu/style.js +3 -0
  209. package/dist/ui/elements/PcMatch/index.d.ts +31 -0
  210. package/dist/ui/elements/PcMatch/index.js +58 -0
  211. package/dist/ui/elements/PcPanel/index.d.ts +43 -0
  212. package/dist/ui/elements/PcPanel/index.js +51 -0
  213. package/dist/ui/elements/PcPopover/index.d.ts +48 -0
  214. package/dist/ui/elements/PcPopover/index.js +86 -0
  215. package/dist/ui/elements/PcSlider/index.d.ts +57 -0
  216. package/dist/ui/elements/PcSlider/index.js +88 -0
  217. package/dist/ui/elements/PcStats/index.d.ts +54 -0
  218. package/dist/ui/elements/PcStats/index.js +144 -0
  219. package/dist/ui/elements/PcThemePicker/index.d.ts +56 -0
  220. package/dist/ui/elements/PcThemePicker/index.js +134 -0
  221. package/dist/ui/elements/PcToast/index.d.ts +58 -0
  222. package/dist/ui/elements/PcToast/index.js +110 -0
  223. package/dist/ui/elements/PcToggleCheckbox/index.d.ts +37 -0
  224. package/dist/ui/elements/PcToggleCheckbox/index.js +105 -0
  225. package/dist/ui/elements/PcToolSettings/index.d.ts +128 -0
  226. package/dist/ui/elements/PcToolSettings/index.js +549 -0
  227. package/dist/ui/elements/PcToolSettings/style.js +3 -0
  228. package/dist/ui/elements/PcToolbar/index.d.ts +71 -0
  229. package/dist/ui/elements/PcToolbar/index.js +190 -0
  230. package/dist/ui/elements/PcToolbar/style.js +3 -0
  231. package/dist/ui/icons/images/brush.js +3 -0
  232. package/dist/ui/icons/images/circle-mask.js +3 -0
  233. package/dist/ui/icons/images/clipboard.js +3 -0
  234. package/dist/ui/icons/images/cursor.js +3 -0
  235. package/dist/ui/icons/images/eraser.js +3 -0
  236. package/dist/ui/icons/images/eyedropper.js +3 -0
  237. package/dist/ui/icons/images/flip-horizontal.js +3 -0
  238. package/dist/ui/icons/images/flip-vertical.js +3 -0
  239. package/dist/ui/icons/images/focus-pen.js +3 -0
  240. package/dist/ui/icons/images/freehand-mask.js +3 -0
  241. package/dist/ui/icons/images/hidden.js +3 -0
  242. package/dist/ui/icons/images/layers.js +3 -0
  243. package/dist/ui/icons/images/linked.js +3 -0
  244. package/dist/ui/icons/images/locked.js +3 -0
  245. package/dist/ui/icons/images/moon.js +3 -0
  246. package/dist/ui/icons/images/pan.js +3 -0
  247. package/dist/ui/icons/images/polygon-mask.js +3 -0
  248. package/dist/ui/icons/images/pressure.js +3 -0
  249. package/dist/ui/icons/images/randomise.js +3 -0
  250. package/dist/ui/icons/images/rectangle-mask.js +3 -0
  251. package/dist/ui/icons/images/redo.js +3 -0
  252. package/dist/ui/icons/images/rotate-90-left.js +3 -0
  253. package/dist/ui/icons/images/rotate-90-right.js +3 -0
  254. package/dist/ui/icons/images/smoothing-bezier-cubic.js +3 -0
  255. package/dist/ui/icons/images/smoothing-bezier-quad.js +3 -0
  256. package/dist/ui/icons/images/smoothing-linear.js +3 -0
  257. package/dist/ui/icons/images/star.js +3 -0
  258. package/dist/ui/icons/images/sun.js +3 -0
  259. package/dist/ui/icons/images/tilt.js +3 -0
  260. package/dist/ui/icons/images/undo.js +3 -0
  261. package/dist/ui/icons/images/unlinked.js +3 -0
  262. package/dist/ui/icons/images/unlocked.js +3 -0
  263. package/dist/ui/icons/images/visible.js +3 -0
  264. package/dist/ui/icons/images/zoom-in.js +3 -0
  265. package/dist/ui/icons/images/zoom-out.js +3 -0
  266. package/dist/ui/icons/images/zoom.js +3 -0
  267. package/dist/ui/icons/index.d.ts +42 -0
  268. package/dist/ui/icons/index.js +130 -0
  269. package/dist/ui/index.d.ts +21 -0
  270. package/dist/ui/index.js +22 -0
  271. package/dist/ui/layout/index.d.ts +88 -0
  272. package/dist/ui/layout/index.js +96 -0
  273. package/dist/ui/styles/index.d.ts +13 -0
  274. package/dist/ui/styles/index.js +195 -0
  275. package/dist/ui/tokens/index.d.ts +29 -0
  276. package/dist/ui/tokens/index.js +114 -0
  277. package/locales/en-GB.json +179 -0
  278. package/locales/en-US.json +179 -0
  279. package/locales/fr.json +179 -0
  280. package/locales/ja.json +179 -0
  281. package/locales/ko.json +179 -0
  282. package/locales/zh-Hans.json +179 -0
  283. package/locales/zh-Hant.json +179 -0
  284. package/package.json +97 -3
@@ -0,0 +1,107 @@
1
+ import { BUILT_IN_AUTHOR } from "../../authors/index.js";
2
+ import { SmoothingType } from "../../types/index.js";
3
+ // src/lib/brushes/presets/sketching/index.ts
4
+ /** Settings shared by the sketching presets */
5
+ var DEFAULT_CONFIG = {
6
+ version: "1.0.0",
7
+ author: BUILT_IN_AUTHOR,
8
+ group: "Sketching"
9
+ };
10
+ /** Thin pencil that gets wider and darker with pen pressure */
11
+ var pencil = {
12
+ ...DEFAULT_CONFIG,
13
+ id: "pencil",
14
+ name: "Pencil 4px (pressure)",
15
+ width: 4,
16
+ height: 4,
17
+ constrainProportions: true,
18
+ alpha: .9,
19
+ spacing: 1,
20
+ sampleRate: 10,
21
+ smoothingType: SmoothingType.BezierCubic,
22
+ widthConfig: {
23
+ usePressure: true,
24
+ minPressure: .3,
25
+ maxPressure: 1
26
+ }
27
+ };
28
+ /** Ink pen with strong pressure taper */
29
+ var inkPen = {
30
+ ...DEFAULT_CONFIG,
31
+ id: "inkPen",
32
+ name: "Ink pen 10px (pressure)",
33
+ width: 10,
34
+ height: 10,
35
+ constrainProportions: true,
36
+ spacing: 1,
37
+ sampleRate: 10,
38
+ smoothingType: SmoothingType.BezierCubic,
39
+ widthConfig: {
40
+ usePressure: true,
41
+ minPressure: .1,
42
+ maxPressure: 1
43
+ }
44
+ };
45
+ /** Scattered dots of varying size, for texture */
46
+ var stipple = {
47
+ ...DEFAULT_CONFIG,
48
+ id: "stipple",
49
+ name: "Stipple 8px",
50
+ width: 8,
51
+ height: 8,
52
+ constrainProportions: true,
53
+ spacing: 14,
54
+ sampleRate: 10,
55
+ smoothingType: SmoothingType.Linear,
56
+ widthConfig: {
57
+ useRandomise: true,
58
+ minRandomise: .3,
59
+ maxRandomise: 1
60
+ },
61
+ offsetXConfig: {
62
+ useRandomise: true,
63
+ minRandomise: 0,
64
+ maxRandomise: 1
65
+ },
66
+ offsetYConfig: {
67
+ useRandomise: true,
68
+ minRandomise: 0,
69
+ maxRandomise: 1
70
+ }
71
+ };
72
+ /** Flat angled nib; with a pen, the angle follows the pen's tilt */
73
+ var calligraphy = {
74
+ ...DEFAULT_CONFIG,
75
+ id: "calligraphy",
76
+ name: "Calligraphy 24px (tilt)",
77
+ width: 24,
78
+ height: 5,
79
+ constrainProportions: true,
80
+ rotation: 45,
81
+ spacing: 1,
82
+ sampleRate: 10,
83
+ smoothingType: SmoothingType.BezierCubic,
84
+ rotationConfig: { useTilt: true }
85
+ };
86
+ /** Semi-transparent marker: overlapping parts of one stroke stay even, separate strokes build up */
87
+ var marker = {
88
+ ...DEFAULT_CONFIG,
89
+ id: "marker",
90
+ name: "Marker 30px 40%",
91
+ width: 30,
92
+ height: 30,
93
+ constrainProportions: true,
94
+ alpha: .4,
95
+ spacing: 2,
96
+ sampleRate: 10,
97
+ smoothingType: SmoothingType.BezierQuad
98
+ };
99
+ /** Presets for sketching and for testing how drawing feels */
100
+ var sketching = {
101
+ pencil,
102
+ inkPen,
103
+ stipple,
104
+ calligraphy,
105
+ marker
106
+ };
107
+ export { calligraphy, sketching as default, sketching, inkPen, marker, pencil, stipple };
@@ -0,0 +1,7 @@
1
+ import type { BrushConfig, BrushesConfig } from "../../types";
2
+ /** Hard square brushes, snapped to the pixel grid */
3
+ export declare const square: BrushesConfig;
4
+ declare const _default: {
5
+ [x: string]: BrushConfig;
6
+ };
7
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import { BUILT_IN_AUTHOR } from "../../authors/index.js";
2
+ import { sizedPresets } from "../sized/index.js";
3
+ import square_default$1 from "./square.js";
4
+ /** Hard square brushes, snapped to the pixel grid */
5
+ var square = sizedPresets("square", "Square", [
6
+ 1,
7
+ 5,
8
+ 10,
9
+ 20,
10
+ 30,
11
+ 40,
12
+ 50
13
+ ], {
14
+ version: "1.0.0",
15
+ author: BUILT_IN_AUTHOR,
16
+ constrainProportions: true,
17
+ image: square_default$1,
18
+ sampleRate: 50,
19
+ snapToPixelGrid: true
20
+ }, (size) => ({ spacing: Math.max(1, Math.round(size / 10)) }));
21
+ var square_default = { ...square };
22
+ export { square_default as default, square };
@@ -0,0 +1,3 @@
1
+ // src/lib/brushes/presets/square/square.png?inline
2
+ var square_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAQAAADa613fAAAAa0lEQVR42u3PQREAAAjDsN38ewYVfLi0CtLMj5sngYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNy1qlZkZS7/ScAAAAAASUVORK5CYII=";
3
+ export { square_default as default };
@@ -0,0 +1,40 @@
1
+ import { type CanvasFactory } from "../../classes/Layer";
2
+ /** Largest brush shape file, in bytes */
3
+ export declare const MAX_SHAPE_FILE_BYTES: number;
4
+ /** Largest brush shape width or height, in pixels; larger images are shrunk */
5
+ export declare const MAX_SHAPE_SIZE = 512;
6
+ /** Messages shown when a brush shape can't be used */
7
+ export declare const SHAPE_ERRORS: {
8
+ readonly type: "Brush shapes must be PNG images";
9
+ readonly size: "Brush shape images can be up to 2 MB";
10
+ readonly decode: "Couldn't read the brush shape image";
11
+ readonly noImage: "There is no PNG image to paste";
12
+ };
13
+ /** A brush shape image can't be used, with a message for the user */
14
+ export declare class ShapeImageError extends Error {
15
+ }
16
+ /** A brush shape ready to use in a preset */
17
+ export interface ShapeImage {
18
+ /** PNG data URL */
19
+ image: string;
20
+ width: number;
21
+ height: number;
22
+ }
23
+ /** What reading a shape needs (replaceable for tests) */
24
+ export interface ShapeImageDependencies {
25
+ decode?: (blob: Blob) => Promise<ImageBitmap>;
26
+ createCanvas?: CanvasFactory;
27
+ }
28
+ /**
29
+ * Turn a PNG file into a brush shape: at most 2 MB, shrunk to at most 512 pixels on its longest side, as a PNG data
30
+ * URL. Its alpha is used as is. Throws a `ShapeImageError` if it can't be used.
31
+ *
32
+ * @example
33
+ * const shape = await readShapeImage(input.files[0]); // { image: "data:image/png;base64,…", width: 120, height: 80 }
34
+ */
35
+ export declare const readShapeImage: (blob: Blob, { decode, createCanvas, }?: ShapeImageDependencies) => Promise<ShapeImage>;
36
+ /**
37
+ * Read a brush shape from a PNG image on the clipboard. Throws a `ShapeImageError` if there is none or it can't be
38
+ * used.
39
+ */
40
+ export declare const readClipboardShape: (clipboard?: Pick<Clipboard, "read">, deps?: ShapeImageDependencies) => Promise<ShapeImage>;
@@ -0,0 +1,61 @@
1
+ import { bytesToBase64 } from "../../image/index.js";
2
+ import { createOffscreenCanvas } from "../../classes/Layer/index.js";
3
+ // src/lib/brushes/shapeImage/index.ts
4
+ /** Largest brush shape file, in bytes */
5
+ var MAX_SHAPE_FILE_BYTES = 2097152;
6
+ /** Largest brush shape width or height, in pixels; larger images are shrunk */
7
+ var MAX_SHAPE_SIZE = 512;
8
+ /** Messages shown when a brush shape can't be used */
9
+ var SHAPE_ERRORS = {
10
+ type: "Brush shapes must be PNG images",
11
+ size: "Brush shape images can be up to 2 MB",
12
+ decode: "Couldn't read the brush shape image",
13
+ noImage: "There is no PNG image to paste"
14
+ };
15
+ /** A brush shape image can't be used, with a message for the user */
16
+ var ShapeImageError = class extends Error {};
17
+ /**
18
+ * Turn a PNG file into a brush shape: at most 2 MB, shrunk to at most 512 pixels on its longest side, as a PNG data
19
+ * URL. Its alpha is used as is. Throws a `ShapeImageError` if it can't be used.
20
+ *
21
+ * @example
22
+ * const shape = await readShapeImage(input.files[0]); // { image: "data:image/png;base64,…", width: 120, height: 80 }
23
+ */
24
+ var readShapeImage = async (blob, { decode = (file) => createImageBitmap(file), createCanvas = createOffscreenCanvas } = {}) => {
25
+ if (blob.type !== "image/png") throw new ShapeImageError(SHAPE_ERRORS.type);
26
+ if (blob.size > 2097152) throw new ShapeImageError(SHAPE_ERRORS.size);
27
+ let bitmap;
28
+ try {
29
+ bitmap = await decode(blob);
30
+ } catch {
31
+ throw new ShapeImageError(SHAPE_ERRORS.decode);
32
+ }
33
+ const scale = Math.min(1, 512 / Math.max(bitmap.width, bitmap.height));
34
+ const width = Math.max(1, Math.round(bitmap.width * scale));
35
+ const height = Math.max(1, Math.round(bitmap.height * scale));
36
+ const canvas = createCanvas(width, height);
37
+ canvas.getContext("2d").drawImage(bitmap, 0, 0, width, height);
38
+ const png = await canvas.convertToBlob({ type: "image/png" });
39
+ const bytes = new Uint8Array(await png.arrayBuffer());
40
+ return {
41
+ image: `data:image/png;base64,${bytesToBase64(bytes)}`,
42
+ width,
43
+ height
44
+ };
45
+ };
46
+ /**
47
+ * Read a brush shape from a PNG image on the clipboard. Throws a `ShapeImageError` if there is none or it can't be
48
+ * used.
49
+ */
50
+ var readClipboardShape = async (clipboard = navigator.clipboard, deps = {}) => {
51
+ let items;
52
+ try {
53
+ items = await clipboard.read();
54
+ } catch {
55
+ throw new ShapeImageError(SHAPE_ERRORS.noImage);
56
+ }
57
+ const item = items.find((entry) => entry.types.includes("image/png"));
58
+ if (!item) throw new ShapeImageError(SHAPE_ERRORS.noImage);
59
+ return readShapeImage(await item.getType("image/png"), deps);
60
+ };
61
+ export { MAX_SHAPE_FILE_BYTES, MAX_SHAPE_SIZE, SHAPE_ERRORS, ShapeImageError, readClipboardShape, readShapeImage };
@@ -0,0 +1,243 @@
1
+ export interface AssetAuthorDetails {
2
+ /** Author's name */
3
+ name: string;
4
+ /** Author's handle or username, which tells their presets apart from others with the same name */
5
+ handle?: string;
6
+ /** Author's email */
7
+ email?: string;
8
+ /** Author's website */
9
+ website?: string;
10
+ }
11
+ export type AssetAuthor = string | AssetAuthorDetails;
12
+ /** Which colour settings a brush varies */
13
+ export declare enum ColourMode {
14
+ HSL = 0,
15
+ RGB = 1
16
+ }
17
+ /** How the line between a stroke's recorded points is drawn */
18
+ export declare enum SmoothingType {
19
+ /** Same as Linear (kept for older presets) */
20
+ None = 0,
21
+ /** Straight lines between points */
22
+ Linear = 1,
23
+ /** Quadratic curves through the midpoints between points (smooth, no lag) */
24
+ BezierQuad = 2,
25
+ /** Cubic curves whose handles follow the direction of movement before and after each point (smoothest; lags one point) */
26
+ BezierCubic = 3
27
+ }
28
+ /**
29
+ * Controls how a brush parameter varies for each stamp along a stroke. All ranges are fractions from 0 to 1.
30
+ *
31
+ * Each enabled source produces a factor:
32
+ *
33
+ * - Randomise: `minRandomise + (maxRandomise - minRandomise) * Math.random()`
34
+ * - Pressure: `minPressure + (maxPressure - minPressure) * pressure` (pressure 0–1 from the pen)
35
+ * - Tilt: `minTilt + (maxTilt - minTilt) * tilt` (tilt 0 = pen upright, 1 = pen flat)
36
+ *
37
+ * The factors are multiplied together and applied according to the kind of parameter:
38
+ *
39
+ * - Scale parameters (width, height, alpha, saturation, lightness, red, green, blue): `value * factor`
40
+ * - Angle parameters (rotation, hue): `value + factor * 360` degrees. For rotation, tilt instead sets the
41
+ * angle from the direction the pen leans (like a calligraphy nib).
42
+ * - Offset parameters (offsetX, offsetY): `value ± factor * brush size`, in a random direction (scatter)
43
+ *
44
+ * @example
45
+ * // Width varies randomly between 50% and 100% and follows pen pressure from 20% to 100%
46
+ * const widthConfig: BrushParamConfig = {
47
+ * useRandomise: true, minRandomise: 0.5, maxRandomise: 1,
48
+ * usePressure: true, minPressure: 0.2, maxPressure: 1,
49
+ * };
50
+ */
51
+ export interface BrushParamConfig {
52
+ /**
53
+ * Vary the parameter randomly for each stamp, between `minRandomise` and `maxRandomise`
54
+ * @default false
55
+ */
56
+ useRandomise?: boolean;
57
+ /**
58
+ * Lowest random factor (0–1)
59
+ * @default 1
60
+ */
61
+ minRandomise?: number;
62
+ /**
63
+ * Highest random factor (0–1)
64
+ * @default 1
65
+ */
66
+ maxRandomise?: number;
67
+ /**
68
+ * Vary the parameter with pen pressure, when the device provides it
69
+ * @default false
70
+ */
71
+ usePressure?: boolean;
72
+ /**
73
+ * Factor at the lightest pressure (0–1)
74
+ * @default 0
75
+ */
76
+ minPressure?: number;
77
+ /**
78
+ * Factor at full pressure (0–1)
79
+ * @default 1
80
+ */
81
+ maxPressure?: number;
82
+ /**
83
+ * Vary the parameter with pen tilt, when the device provides it
84
+ * @default false
85
+ */
86
+ useTilt?: boolean;
87
+ /**
88
+ * Factor when the pen is upright (0–1)
89
+ * @default 0
90
+ */
91
+ minTilt?: number;
92
+ /**
93
+ * Factor when the pen is flat (0–1)
94
+ * @default 1
95
+ */
96
+ maxTilt?: number;
97
+ }
98
+ export interface BrushConfig {
99
+ /** Unique ID */
100
+ id: string;
101
+ /** Brush name */
102
+ name?: string;
103
+ /** The family the preset belongs to (presets of the same group are listed together, e.g. "Round") */
104
+ group?: string;
105
+ /** Brush version */
106
+ version?: string;
107
+ /** Brush author */
108
+ author?: AssetAuthor;
109
+ /**
110
+ * Brush shape: an image whose alpha values define the shape (its colours are ignored).
111
+ * A data URL string, or raw image file bytes. Defaults to a hard round shape.
112
+ */
113
+ image?: string | Uint8Array;
114
+ /**
115
+ * Brush colour mode affects how colour settings are applied.
116
+ * @default ColourMode.HSL
117
+ */
118
+ colourMode?: ColourMode;
119
+ /**
120
+ * Initial colour hue value (0–359)
121
+ * @default 0
122
+ */
123
+ hue?: string | number;
124
+ /** How hue varies per stamp (angle: adds up to 360°; see {@link BrushParamConfig}) */
125
+ hueConfig?: BrushParamConfig;
126
+ /**
127
+ * Initial colour saturation value (0–100)
128
+ * @default 100
129
+ */
130
+ saturation?: string | number;
131
+ /** How saturation varies per stamp (scale; see {@link BrushParamConfig}) */
132
+ saturationConfig?: BrushParamConfig;
133
+ /**
134
+ * Initial colour lightness value (0–100)
135
+ * @default 50
136
+ */
137
+ lightness?: string | number;
138
+ /** How lightness varies per stamp (scale; see {@link BrushParamConfig}) */
139
+ lightnessConfig?: BrushParamConfig;
140
+ /**
141
+ * Initial colour red value (0–255)
142
+ * @default 0
143
+ */
144
+ red?: string | number;
145
+ /** How red varies per stamp (scale; see {@link BrushParamConfig}) */
146
+ redConfig?: BrushParamConfig;
147
+ /**
148
+ * Initial colour green value (0–255)
149
+ * @default 0
150
+ */
151
+ green?: string | number;
152
+ /** How green varies per stamp (scale; see {@link BrushParamConfig}) */
153
+ greenConfig?: BrushParamConfig;
154
+ /**
155
+ * Initial colour blue value (0–255)
156
+ * @default 0
157
+ */
158
+ blue?: string | number;
159
+ /** How blue varies per stamp (scale; see {@link BrushParamConfig}) */
160
+ blueConfig?: BrushParamConfig;
161
+ /**
162
+ * Initial alpha value (0–1)
163
+ * @default 1
164
+ */
165
+ alpha?: number;
166
+ /** How alpha varies per stamp (scale; see {@link BrushParamConfig}) */
167
+ alphaConfig?: BrushParamConfig;
168
+ /**
169
+ * Default width in pixels (the user can change it from 1 to 256)
170
+ * @default 1
171
+ */
172
+ width?: number;
173
+ /** How width varies per stamp (scale; see {@link BrushParamConfig}) */
174
+ widthConfig?: BrushParamConfig;
175
+ /**
176
+ * Default height in pixels (the user can change it from 1 to 256)
177
+ * @default 1
178
+ */
179
+ height?: number;
180
+ /** How height varies per stamp (scale; see {@link BrushParamConfig}) */
181
+ heightConfig?: BrushParamConfig;
182
+ /** Keep the width-to-height ratio when the size changes */
183
+ constrainProportions?: boolean;
184
+ /**
185
+ * Rotation in degrees
186
+ * @default 0
187
+ */
188
+ rotation?: number;
189
+ /** How rotation varies per stamp (angle: adds up to 360°; tilt sets the angle from the pen's lean direction; see {@link BrushParamConfig}) */
190
+ rotationConfig?: BrushParamConfig;
191
+ /**
192
+ * Horizontal offset of each stamp from the pointer, in pixels
193
+ * @default 0
194
+ */
195
+ offsetX?: number;
196
+ /** How offsetX varies per stamp (offset: scatters up to the factor × brush width either way; see {@link BrushParamConfig}) */
197
+ offsetXConfig?: BrushParamConfig;
198
+ /**
199
+ * Vertical offset of each stamp from the pointer, in pixels
200
+ * @default 0
201
+ */
202
+ offsetY?: number;
203
+ /** How offsetY varies per stamp (offset: scatters up to the factor × brush height either way; see {@link BrushParamConfig}) */
204
+ offsetYConfig?: BrushParamConfig;
205
+ /**
206
+ * How often (in milliseconds, 5–400) a new point is recorded while the pointer moves. Higher values record fewer points.
207
+ * No points are recorded while the pointer is still.
208
+ * @default 10
209
+ */
210
+ sampleRate?: number;
211
+ /**
212
+ * How the line between recorded points is drawn
213
+ * @default SmoothingType.Linear
214
+ */
215
+ smoothingType?: SmoothingType;
216
+ /**
217
+ * Distance in pixels (0–200) between stamps of the brush shape along the line. 0 stamps at every pixel.
218
+ * @default 5
219
+ */
220
+ spacing?: number;
221
+ /**
222
+ * Draw each stamp on whole pixels: its size is rounded to whole pixels and its top-left corner is rounded down
223
+ * (`Math.floor`), so it never covers part of a pixel. Rotation other than a multiple of 90° still leaves the grid.
224
+ * @default false
225
+ */
226
+ snapToPixelGrid?: boolean;
227
+ }
228
+ export type BrushesConfig = Record<string, BrushConfig>;
229
+ export interface BrushStrokePoint {
230
+ /** The X coordinate of the brush stroke point */
231
+ x: number;
232
+ /** The Y coordinate of the brush stroke point */
233
+ y: number;
234
+ /** The rotation (in radians) of the brush stroke point */
235
+ rotation?: number;
236
+ /** The pressure (0–1) of the brush stroke point, from `PointerEvent.pressure` */
237
+ pressure?: number;
238
+ /** The pen tilt (-90–90 degrees) along the X axis, from `PointerEvent.tiltX` */
239
+ tiltX?: number;
240
+ /** The pen tilt (-90–90 degrees) along the Y axis, from `PointerEvent.tiltY` */
241
+ tiltY?: number;
242
+ }
243
+ export type BrushStroke = BrushStrokePoint[];
@@ -0,0 +1,20 @@
1
+ // src/lib/brushes/types/index.ts
2
+ /** Which colour settings a brush varies */
3
+ var ColourMode = /* @__PURE__ */ function(ColourMode) {
4
+ ColourMode[ColourMode["HSL"] = 0] = "HSL";
5
+ ColourMode[ColourMode["RGB"] = 1] = "RGB";
6
+ return ColourMode;
7
+ }({});
8
+ /** How the line between a stroke's recorded points is drawn */
9
+ var SmoothingType = /* @__PURE__ */ function(SmoothingType) {
10
+ /** Same as Linear (kept for older presets) */
11
+ SmoothingType[SmoothingType["None"] = 0] = "None";
12
+ /** Straight lines between points */
13
+ SmoothingType[SmoothingType["Linear"] = 1] = "Linear";
14
+ /** Quadratic curves through the midpoints between points (smooth, no lag) */
15
+ SmoothingType[SmoothingType["BezierQuad"] = 2] = "BezierQuad";
16
+ /** Cubic curves whose handles follow the direction of movement before and after each point (smoothest; lags one point) */
17
+ SmoothingType[SmoothingType["BezierCubic"] = 3] = "BezierCubic";
18
+ return SmoothingType;
19
+ }({});
20
+ export { ColourMode, SmoothingType };
@@ -0,0 +1,55 @@
1
+ import type StrokeLog from "../StrokeLog";
2
+ /** How long drawing must pause after a stroke before background work runs (milliseconds) */
3
+ export declare const DRAWING_PAUSE_MS = 300;
4
+ /** Longest background work waits while drawing continues (milliseconds); it still only runs between strokes */
5
+ export declare const MAX_WAIT_MS = 1000;
6
+ /**
7
+ * Holds slow work that isn't urgent (syncing the drawing, redrawing the canvas map and layer thumbnails, saving) until
8
+ * drawing pauses, so it doesn't keep the page busy while the user is drawing or about to draw the next stroke.
9
+ *
10
+ * Work never runs during a stroke. Between strokes, it runs once `DRAWING_PAUSE_MS` has passed since the last stroke
11
+ * ended, or once it has waited `MAX_WAIT_MS` (so a long run of strokes doesn't hold it up forever).
12
+ * When nobody is drawing, it runs straight away (during `run`); work due when a stroke ends runs just after it. Work
13
+ * asked for again under the same name before it runs replaces the earlier request (keeping its place in the wait). With
14
+ * a stroke log, how long each piece of work took is logged.
15
+ *
16
+ * @example
17
+ * const work = new BackgroundWork(app.strokeLog);
18
+ * work.strokeStarted();
19
+ * work.run("map", () => map.drawThumbnail()); // waits
20
+ * work.strokeEnded(); // the map is redrawn 300ms later, unless another stroke starts first
21
+ */
22
+ export default class BackgroundWork {
23
+ /** Current time in milliseconds (replaceable for tests) */
24
+ now: () => number;
25
+ private readonly log?;
26
+ private readonly tasks;
27
+ private drawing;
28
+ /** When the last stroke ended */
29
+ private lastStroke;
30
+ private timer?;
31
+ constructor(log?: StrokeLog);
32
+ /** Names of the work waiting to run */
33
+ get pending(): readonly string[];
34
+ /**
35
+ * Run some work once drawing pauses (see the class description).
36
+ */
37
+ run(name: string, run: () => unknown): void;
38
+ /**
39
+ * Forget work that hasn't run yet.
40
+ */
41
+ cancel(name: string): void;
42
+ /** A stroke started: hold all work until it ends */
43
+ strokeStarted(): void;
44
+ /** A stroke ended (or was cancelled): run the work once drawing pauses */
45
+ strokeEnded(): void;
46
+ /**
47
+ * Run the waiting work now if it's due (and `now` allows), or set a timer for when it will be (unless drawing).
48
+ */
49
+ private plan;
50
+ /**
51
+ * Run all waiting work, logging how long each took. If any throws, the rest still runs, then the first error is
52
+ * thrown.
53
+ */
54
+ private flush;
55
+ }
@@ -0,0 +1,97 @@
1
+ // src/lib/classes/BackgroundWork/index.ts
2
+ /** How long drawing must pause after a stroke before background work runs (milliseconds) */
3
+ var DRAWING_PAUSE_MS = 300;
4
+ /** Longest background work waits while drawing continues (milliseconds); it still only runs between strokes */
5
+ var MAX_WAIT_MS = 1e3;
6
+ /**
7
+ * Holds slow work that isn't urgent (syncing the drawing, redrawing the canvas map and layer thumbnails, saving) until
8
+ * drawing pauses, so it doesn't keep the page busy while the user is drawing or about to draw the next stroke.
9
+ *
10
+ * Work never runs during a stroke. Between strokes, it runs once `DRAWING_PAUSE_MS` has passed since the last stroke
11
+ * ended, or once it has waited `MAX_WAIT_MS` (so a long run of strokes doesn't hold it up forever).
12
+ * When nobody is drawing, it runs straight away (during `run`); work due when a stroke ends runs just after it. Work
13
+ * asked for again under the same name before it runs replaces the earlier request (keeping its place in the wait). With
14
+ * a stroke log, how long each piece of work took is logged.
15
+ *
16
+ * @example
17
+ * const work = new BackgroundWork(app.strokeLog);
18
+ * work.strokeStarted();
19
+ * work.run("map", () => map.drawThumbnail()); // waits
20
+ * work.strokeEnded(); // the map is redrawn 300ms later, unless another stroke starts first
21
+ */
22
+ var BackgroundWork = class {
23
+ /** Current time in milliseconds (replaceable for tests) */
24
+ now = () => performance.now();
25
+ log;
26
+ tasks = /* @__PURE__ */ new Map();
27
+ drawing = false;
28
+ /** When the last stroke ended */
29
+ lastStroke = -Infinity;
30
+ timer;
31
+ constructor(log) {
32
+ this.log = log;
33
+ }
34
+ /** Names of the work waiting to run */
35
+ get pending() {
36
+ return [...this.tasks.keys()];
37
+ }
38
+ /**
39
+ * Run some work once drawing pauses (see the class description).
40
+ */
41
+ run(name, run) {
42
+ const since = this.tasks.get(name)?.since ?? this.now();
43
+ this.tasks.set(name, {
44
+ run,
45
+ since
46
+ });
47
+ this.plan();
48
+ }
49
+ /**
50
+ * Forget work that hasn't run yet.
51
+ */
52
+ cancel(name) {
53
+ this.tasks.delete(name);
54
+ this.plan();
55
+ }
56
+ /** A stroke started: hold all work until it ends */
57
+ strokeStarted() {
58
+ this.drawing = true;
59
+ this.plan();
60
+ }
61
+ /** A stroke ended (or was cancelled): run the work once drawing pauses */
62
+ strokeEnded() {
63
+ this.drawing = false;
64
+ this.lastStroke = this.now();
65
+ this.plan(false);
66
+ }
67
+ /**
68
+ * Run the waiting work now if it's due (and `now` allows), or set a timer for when it will be (unless drawing).
69
+ */
70
+ plan(now = true) {
71
+ clearTimeout(this.timer);
72
+ this.timer = void 0;
73
+ if (this.drawing || this.tasks.size === 0) return;
74
+ const oldest = Math.min(...[...this.tasks.values()].map((t) => t.since));
75
+ const wait = Math.min(this.lastStroke + 300, oldest + MAX_WAIT_MS) - this.now();
76
+ if (wait <= 0 && now) this.flush();
77
+ else this.timer = setTimeout(() => this.flush(), Math.max(0, wait));
78
+ }
79
+ /**
80
+ * Run all waiting work, logging how long each took. If any throws, the rest still runs, then the first error is
81
+ * thrown.
82
+ */
83
+ flush() {
84
+ this.timer = void 0;
85
+ const tasks = [...this.tasks];
86
+ this.tasks.clear();
87
+ const errors = [];
88
+ for (const [name, { run }] of tasks) try {
89
+ if (this.log) this.log.measure(name, run);
90
+ else run();
91
+ } catch (error) {
92
+ errors.push(error);
93
+ }
94
+ if (errors.length > 0) throw errors[0];
95
+ }
96
+ };
97
+ export { DRAWING_PAUSE_MS, MAX_WAIT_MS, BackgroundWork as default };