@lvl99dotcom/paintcanvas 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/lib/brushes/configRanges/index.d.ts +17 -0
  2. package/dist/lib/brushes/configRanges/index.js +31 -1
  3. package/dist/lib/brushes/params/index.d.ts +2 -1
  4. package/dist/lib/brushes/params/index.js +7 -4
  5. package/dist/lib/brushes/types/index.d.ts +8 -0
  6. package/dist/lib/classes/Layer/index.d.ts +10 -0
  7. package/dist/lib/classes/Layer/index.js +15 -1
  8. package/dist/lib/classes/LayerAutosave/index.d.ts +9 -15
  9. package/dist/lib/classes/LayerAutosave/index.js +30 -43
  10. package/dist/lib/classes/LayerStack/index.d.ts +15 -0
  11. package/dist/lib/classes/LayerStack/index.js +26 -2
  12. package/dist/lib/classes/PaintCanvas/index.d.ts +26 -3
  13. package/dist/lib/classes/PaintCanvas/index.js +39 -12
  14. package/dist/lib/classes/PngEncoder/index.d.ts +41 -0
  15. package/dist/lib/classes/PngEncoder/index.js +104 -0
  16. package/dist/lib/classes/ProfileGraphs/index.d.ts +87 -0
  17. package/dist/lib/classes/ProfileGraphs/index.js +148 -0
  18. package/dist/lib/classes/SettingsAutosave/index.d.ts +1 -1
  19. package/dist/lib/classes/SettingsAutosave/index.js +2 -1
  20. package/dist/lib/messages/schema.d.ts +720 -0
  21. package/dist/lib/presets/schema.d.ts +360 -0
  22. package/dist/lib/presets/schema.js +8 -1
  23. package/dist/lib/profiles/index.d.ts +61 -0
  24. package/dist/lib/profiles/index.js +131 -0
  25. package/dist/lib/profiles/schema.d.ts +73 -0
  26. package/dist/lib/profiles/schema.js +53 -0
  27. package/dist/lib/rendering/sample/index.d.ts +11 -0
  28. package/dist/lib/rendering/sample/index.js +36 -5
  29. package/dist/lib/settings/index.d.ts +2 -1
  30. package/dist/lib/settings/index.js +4 -1
  31. package/dist/lib/settings/schema.d.ts +49 -0
  32. package/dist/lib/settings/schema.js +6 -0
  33. package/dist/lib/validation/validators.generated.js +13064 -3696
  34. package/dist/locales/en-GB.js +30 -0
  35. package/dist/locales/en-US.js +30 -0
  36. package/dist/locales/fr.js +30 -0
  37. package/dist/locales/ja.js +30 -0
  38. package/dist/locales/ko.js +30 -0
  39. package/dist/locales/zh-Hans.js +30 -0
  40. package/dist/locales/zh-Hant.js +30 -0
  41. package/dist/package.js +1 -1
  42. package/dist/ui/ask/index.d.ts +48 -0
  43. package/dist/ui/ask/index.js +67 -0
  44. package/dist/ui/base/index.d.ts +8 -1
  45. package/dist/ui/base/index.js +19 -4
  46. package/dist/ui/elements/PaintCanvas/index.js +3 -1
  47. package/dist/ui/elements/PaintCanvas/style.js +1 -1
  48. package/dist/ui/elements/PcAppSettings/index.d.ts +6 -6
  49. package/dist/ui/elements/PcAppSettings/index.js +21 -65
  50. package/dist/ui/elements/PcBrushConfig/index.d.ts +25 -14
  51. package/dist/ui/elements/PcBrushConfig/index.js +216 -146
  52. package/dist/ui/elements/PcBrushConfig/style.js +1 -1
  53. package/dist/ui/elements/PcBrushTest/index.js +7 -2
  54. package/dist/ui/elements/PcBrushTest/style.js +1 -1
  55. package/dist/ui/elements/PcButton/index.d.ts +12 -3
  56. package/dist/ui/elements/PcButton/index.js +18 -10
  57. package/dist/ui/elements/PcCanvas/index.d.ts +6 -1
  58. package/dist/ui/elements/PcCanvas/index.js +10 -3
  59. package/dist/ui/elements/PcCanvas/style.js +1 -1
  60. package/dist/ui/elements/PcClipboardTools/index.d.ts +5 -4
  61. package/dist/ui/elements/PcClipboardTools/index.js +12 -5
  62. package/dist/ui/elements/PcDialog/index.d.ts +46 -10
  63. package/dist/ui/elements/PcDialog/index.js +102 -51
  64. package/dist/ui/elements/PcDialogWindow/index.d.ts +141 -0
  65. package/dist/ui/elements/PcDialogWindow/index.js +385 -0
  66. package/dist/ui/elements/PcPanelBrushes/index.d.ts +3 -2
  67. package/dist/ui/elements/PcPanelBrushes/index.js +7 -5
  68. package/dist/ui/elements/PcPanelBrushes/style.js +1 -1
  69. package/dist/ui/elements/PcPanelColours/index.js +2 -2
  70. package/dist/ui/elements/PcPanelColours/style.js +1 -1
  71. package/dist/ui/elements/PcPanelLayers/index.js +1 -1
  72. package/dist/ui/elements/PcPanelLayers/style.js +1 -1
  73. package/dist/ui/elements/PcProfileEditor/index.d.ts +103 -0
  74. package/dist/ui/elements/PcProfileEditor/index.js +259 -0
  75. package/dist/ui/elements/PcProfileGraph/index.d.ts +84 -0
  76. package/dist/ui/elements/PcProfileGraph/index.js +317 -0
  77. package/dist/ui/elements/PcShortcutSettings/index.js +9 -13
  78. package/dist/ui/elements/PcSliderRange/index.d.ts +147 -0
  79. package/dist/ui/elements/PcSliderRange/index.js +307 -0
  80. package/dist/ui/elements/PcStats/index.d.ts +19 -4
  81. package/dist/ui/elements/PcStats/index.js +29 -13
  82. package/dist/ui/elements/PcToolSettings/index.js +6 -6
  83. package/dist/ui/icons/images/icon-profile-graph@2x.js +3 -0
  84. package/dist/ui/icons/index.d.ts +1 -1
  85. package/dist/ui/icons/index.js +2 -0
  86. package/dist/ui/index.d.ts +6 -1
  87. package/dist/ui/index.js +6 -1
  88. package/dist/ui/styles/index.d.ts +21 -1
  89. package/dist/ui/styles/index.js +73 -14
  90. package/locales/en-GB.json +30 -0
  91. package/locales/en-US.json +30 -0
  92. package/locales/fr.json +30 -0
  93. package/locales/ja.json +30 -0
  94. package/locales/ko.json +30 -0
  95. package/locales/zh-Hans.json +30 -0
  96. package/locales/zh-Hant.json +30 -0
  97. package/package.json +25 -23
@@ -139,6 +139,36 @@ export declare const brushPresetSchema: {
139
139
  readonly minimum: 0;
140
140
  readonly maximum: 1;
141
141
  };
142
+ readonly profile: {
143
+ readonly type: "array";
144
+ readonly minItems: 2;
145
+ readonly maxItems: 32;
146
+ readonly items: {
147
+ readonly type: "object";
148
+ readonly additionalProperties: false;
149
+ readonly required: readonly ["x", "y", "i"];
150
+ readonly properties: {
151
+ readonly x: {
152
+ readonly type: "number";
153
+ readonly minimum: 0;
154
+ readonly maximum: 10;
155
+ };
156
+ readonly y: {
157
+ readonly type: "number";
158
+ readonly minimum: number;
159
+ readonly maximum: 0;
160
+ };
161
+ readonly i: {
162
+ readonly enum: ("linear" | "bezier-cubic")[];
163
+ };
164
+ };
165
+ };
166
+ };
167
+ readonly profileId: {
168
+ readonly type: "string";
169
+ readonly minLength: 1;
170
+ readonly maxLength: 100;
171
+ };
142
172
  };
143
173
  };
144
174
  readonly saturation: {
@@ -192,6 +222,36 @@ export declare const brushPresetSchema: {
192
222
  readonly minimum: 0;
193
223
  readonly maximum: 1;
194
224
  };
225
+ readonly profile: {
226
+ readonly type: "array";
227
+ readonly minItems: 2;
228
+ readonly maxItems: 32;
229
+ readonly items: {
230
+ readonly type: "object";
231
+ readonly additionalProperties: false;
232
+ readonly required: readonly ["x", "y", "i"];
233
+ readonly properties: {
234
+ readonly x: {
235
+ readonly type: "number";
236
+ readonly minimum: 0;
237
+ readonly maximum: 10;
238
+ };
239
+ readonly y: {
240
+ readonly type: "number";
241
+ readonly minimum: number;
242
+ readonly maximum: 0;
243
+ };
244
+ readonly i: {
245
+ readonly enum: ("linear" | "bezier-cubic")[];
246
+ };
247
+ };
248
+ };
249
+ };
250
+ readonly profileId: {
251
+ readonly type: "string";
252
+ readonly minLength: 1;
253
+ readonly maxLength: 100;
254
+ };
195
255
  };
196
256
  };
197
257
  readonly lightness: {
@@ -245,6 +305,36 @@ export declare const brushPresetSchema: {
245
305
  readonly minimum: 0;
246
306
  readonly maximum: 1;
247
307
  };
308
+ readonly profile: {
309
+ readonly type: "array";
310
+ readonly minItems: 2;
311
+ readonly maxItems: 32;
312
+ readonly items: {
313
+ readonly type: "object";
314
+ readonly additionalProperties: false;
315
+ readonly required: readonly ["x", "y", "i"];
316
+ readonly properties: {
317
+ readonly x: {
318
+ readonly type: "number";
319
+ readonly minimum: 0;
320
+ readonly maximum: 10;
321
+ };
322
+ readonly y: {
323
+ readonly type: "number";
324
+ readonly minimum: number;
325
+ readonly maximum: 0;
326
+ };
327
+ readonly i: {
328
+ readonly enum: ("linear" | "bezier-cubic")[];
329
+ };
330
+ };
331
+ };
332
+ };
333
+ readonly profileId: {
334
+ readonly type: "string";
335
+ readonly minLength: 1;
336
+ readonly maxLength: 100;
337
+ };
248
338
  };
249
339
  };
250
340
  readonly red: {
@@ -298,6 +388,36 @@ export declare const brushPresetSchema: {
298
388
  readonly minimum: 0;
299
389
  readonly maximum: 1;
300
390
  };
391
+ readonly profile: {
392
+ readonly type: "array";
393
+ readonly minItems: 2;
394
+ readonly maxItems: 32;
395
+ readonly items: {
396
+ readonly type: "object";
397
+ readonly additionalProperties: false;
398
+ readonly required: readonly ["x", "y", "i"];
399
+ readonly properties: {
400
+ readonly x: {
401
+ readonly type: "number";
402
+ readonly minimum: 0;
403
+ readonly maximum: 10;
404
+ };
405
+ readonly y: {
406
+ readonly type: "number";
407
+ readonly minimum: number;
408
+ readonly maximum: 0;
409
+ };
410
+ readonly i: {
411
+ readonly enum: ("linear" | "bezier-cubic")[];
412
+ };
413
+ };
414
+ };
415
+ };
416
+ readonly profileId: {
417
+ readonly type: "string";
418
+ readonly minLength: 1;
419
+ readonly maxLength: 100;
420
+ };
301
421
  };
302
422
  };
303
423
  readonly green: {
@@ -351,6 +471,36 @@ export declare const brushPresetSchema: {
351
471
  readonly minimum: 0;
352
472
  readonly maximum: 1;
353
473
  };
474
+ readonly profile: {
475
+ readonly type: "array";
476
+ readonly minItems: 2;
477
+ readonly maxItems: 32;
478
+ readonly items: {
479
+ readonly type: "object";
480
+ readonly additionalProperties: false;
481
+ readonly required: readonly ["x", "y", "i"];
482
+ readonly properties: {
483
+ readonly x: {
484
+ readonly type: "number";
485
+ readonly minimum: 0;
486
+ readonly maximum: 10;
487
+ };
488
+ readonly y: {
489
+ readonly type: "number";
490
+ readonly minimum: number;
491
+ readonly maximum: 0;
492
+ };
493
+ readonly i: {
494
+ readonly enum: ("linear" | "bezier-cubic")[];
495
+ };
496
+ };
497
+ };
498
+ };
499
+ readonly profileId: {
500
+ readonly type: "string";
501
+ readonly minLength: 1;
502
+ readonly maxLength: 100;
503
+ };
354
504
  };
355
505
  };
356
506
  readonly blue: {
@@ -404,6 +554,36 @@ export declare const brushPresetSchema: {
404
554
  readonly minimum: 0;
405
555
  readonly maximum: 1;
406
556
  };
557
+ readonly profile: {
558
+ readonly type: "array";
559
+ readonly minItems: 2;
560
+ readonly maxItems: 32;
561
+ readonly items: {
562
+ readonly type: "object";
563
+ readonly additionalProperties: false;
564
+ readonly required: readonly ["x", "y", "i"];
565
+ readonly properties: {
566
+ readonly x: {
567
+ readonly type: "number";
568
+ readonly minimum: 0;
569
+ readonly maximum: 10;
570
+ };
571
+ readonly y: {
572
+ readonly type: "number";
573
+ readonly minimum: number;
574
+ readonly maximum: 0;
575
+ };
576
+ readonly i: {
577
+ readonly enum: ("linear" | "bezier-cubic")[];
578
+ };
579
+ };
580
+ };
581
+ };
582
+ readonly profileId: {
583
+ readonly type: "string";
584
+ readonly minLength: 1;
585
+ readonly maxLength: 100;
586
+ };
407
587
  };
408
588
  };
409
589
  readonly alpha: {
@@ -454,6 +634,36 @@ export declare const brushPresetSchema: {
454
634
  readonly minimum: 0;
455
635
  readonly maximum: 1;
456
636
  };
637
+ readonly profile: {
638
+ readonly type: "array";
639
+ readonly minItems: 2;
640
+ readonly maxItems: 32;
641
+ readonly items: {
642
+ readonly type: "object";
643
+ readonly additionalProperties: false;
644
+ readonly required: readonly ["x", "y", "i"];
645
+ readonly properties: {
646
+ readonly x: {
647
+ readonly type: "number";
648
+ readonly minimum: 0;
649
+ readonly maximum: 10;
650
+ };
651
+ readonly y: {
652
+ readonly type: "number";
653
+ readonly minimum: number;
654
+ readonly maximum: 0;
655
+ };
656
+ readonly i: {
657
+ readonly enum: ("linear" | "bezier-cubic")[];
658
+ };
659
+ };
660
+ };
661
+ };
662
+ readonly profileId: {
663
+ readonly type: "string";
664
+ readonly minLength: 1;
665
+ readonly maxLength: 100;
666
+ };
457
667
  };
458
668
  };
459
669
  readonly width: {
@@ -504,6 +714,36 @@ export declare const brushPresetSchema: {
504
714
  readonly minimum: 0;
505
715
  readonly maximum: 1;
506
716
  };
717
+ readonly profile: {
718
+ readonly type: "array";
719
+ readonly minItems: 2;
720
+ readonly maxItems: 32;
721
+ readonly items: {
722
+ readonly type: "object";
723
+ readonly additionalProperties: false;
724
+ readonly required: readonly ["x", "y", "i"];
725
+ readonly properties: {
726
+ readonly x: {
727
+ readonly type: "number";
728
+ readonly minimum: 0;
729
+ readonly maximum: 10;
730
+ };
731
+ readonly y: {
732
+ readonly type: "number";
733
+ readonly minimum: number;
734
+ readonly maximum: 0;
735
+ };
736
+ readonly i: {
737
+ readonly enum: ("linear" | "bezier-cubic")[];
738
+ };
739
+ };
740
+ };
741
+ };
742
+ readonly profileId: {
743
+ readonly type: "string";
744
+ readonly minLength: 1;
745
+ readonly maxLength: 100;
746
+ };
507
747
  };
508
748
  };
509
749
  readonly height: {
@@ -554,6 +794,36 @@ export declare const brushPresetSchema: {
554
794
  readonly minimum: 0;
555
795
  readonly maximum: 1;
556
796
  };
797
+ readonly profile: {
798
+ readonly type: "array";
799
+ readonly minItems: 2;
800
+ readonly maxItems: 32;
801
+ readonly items: {
802
+ readonly type: "object";
803
+ readonly additionalProperties: false;
804
+ readonly required: readonly ["x", "y", "i"];
805
+ readonly properties: {
806
+ readonly x: {
807
+ readonly type: "number";
808
+ readonly minimum: 0;
809
+ readonly maximum: 10;
810
+ };
811
+ readonly y: {
812
+ readonly type: "number";
813
+ readonly minimum: number;
814
+ readonly maximum: 0;
815
+ };
816
+ readonly i: {
817
+ readonly enum: ("linear" | "bezier-cubic")[];
818
+ };
819
+ };
820
+ };
821
+ };
822
+ readonly profileId: {
823
+ readonly type: "string";
824
+ readonly minLength: 1;
825
+ readonly maxLength: 100;
826
+ };
557
827
  };
558
828
  };
559
829
  readonly constrainProportions: {
@@ -607,6 +877,36 @@ export declare const brushPresetSchema: {
607
877
  readonly minimum: 0;
608
878
  readonly maximum: 1;
609
879
  };
880
+ readonly profile: {
881
+ readonly type: "array";
882
+ readonly minItems: 2;
883
+ readonly maxItems: 32;
884
+ readonly items: {
885
+ readonly type: "object";
886
+ readonly additionalProperties: false;
887
+ readonly required: readonly ["x", "y", "i"];
888
+ readonly properties: {
889
+ readonly x: {
890
+ readonly type: "number";
891
+ readonly minimum: 0;
892
+ readonly maximum: 10;
893
+ };
894
+ readonly y: {
895
+ readonly type: "number";
896
+ readonly minimum: number;
897
+ readonly maximum: 0;
898
+ };
899
+ readonly i: {
900
+ readonly enum: ("linear" | "bezier-cubic")[];
901
+ };
902
+ };
903
+ };
904
+ };
905
+ readonly profileId: {
906
+ readonly type: "string";
907
+ readonly minLength: 1;
908
+ readonly maxLength: 100;
909
+ };
610
910
  };
611
911
  };
612
912
  readonly offsetX: {
@@ -657,6 +957,36 @@ export declare const brushPresetSchema: {
657
957
  readonly minimum: 0;
658
958
  readonly maximum: 1;
659
959
  };
960
+ readonly profile: {
961
+ readonly type: "array";
962
+ readonly minItems: 2;
963
+ readonly maxItems: 32;
964
+ readonly items: {
965
+ readonly type: "object";
966
+ readonly additionalProperties: false;
967
+ readonly required: readonly ["x", "y", "i"];
968
+ readonly properties: {
969
+ readonly x: {
970
+ readonly type: "number";
971
+ readonly minimum: 0;
972
+ readonly maximum: 10;
973
+ };
974
+ readonly y: {
975
+ readonly type: "number";
976
+ readonly minimum: number;
977
+ readonly maximum: 0;
978
+ };
979
+ readonly i: {
980
+ readonly enum: ("linear" | "bezier-cubic")[];
981
+ };
982
+ };
983
+ };
984
+ };
985
+ readonly profileId: {
986
+ readonly type: "string";
987
+ readonly minLength: 1;
988
+ readonly maxLength: 100;
989
+ };
660
990
  };
661
991
  };
662
992
  readonly offsetY: {
@@ -707,6 +1037,36 @@ export declare const brushPresetSchema: {
707
1037
  readonly minimum: 0;
708
1038
  readonly maximum: 1;
709
1039
  };
1040
+ readonly profile: {
1041
+ readonly type: "array";
1042
+ readonly minItems: 2;
1043
+ readonly maxItems: 32;
1044
+ readonly items: {
1045
+ readonly type: "object";
1046
+ readonly additionalProperties: false;
1047
+ readonly required: readonly ["x", "y", "i"];
1048
+ readonly properties: {
1049
+ readonly x: {
1050
+ readonly type: "number";
1051
+ readonly minimum: 0;
1052
+ readonly maximum: 10;
1053
+ };
1054
+ readonly y: {
1055
+ readonly type: "number";
1056
+ readonly minimum: number;
1057
+ readonly maximum: 0;
1058
+ };
1059
+ readonly i: {
1060
+ readonly enum: ("linear" | "bezier-cubic")[];
1061
+ };
1062
+ };
1063
+ };
1064
+ };
1065
+ readonly profileId: {
1066
+ readonly type: "string";
1067
+ readonly minLength: 1;
1068
+ readonly maxLength: 100;
1069
+ };
710
1070
  };
711
1071
  };
712
1072
  readonly sampleRate: {
@@ -1,3 +1,4 @@
1
+ import { profilePointsSchema } from "../profiles/schema.js";
1
2
  // src/lib/presets/schema.ts
2
3
  /** Matches a lowercase UUID */
3
4
  var UUID_PATTERN = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
@@ -36,7 +37,13 @@ var paramConfig = {
36
37
  maxPressure: factor,
37
38
  useTilt: { type: "boolean" },
38
39
  minTilt: factor,
39
- maxTilt: factor
40
+ maxTilt: factor,
41
+ profile: profilePointsSchema,
42
+ profileId: {
43
+ type: "string",
44
+ minLength: 1,
45
+ maxLength: 100
46
+ }
40
47
  }
41
48
  };
42
49
  /** A colour value: a number, or a number as text */
@@ -0,0 +1,61 @@
1
+ /** How the curve runs through a point (a plain object, not an enum, so schemas can use it in scripts run by Node) */
2
+ export declare const Interpolation: {
3
+ /** A sharp corner: straight towards the points either side */
4
+ readonly Linear: "linear";
5
+ /** A smooth curve through the point */
6
+ readonly BezierCubic: "bezier-cubic";
7
+ };
8
+ /** How the curve runs through a point: `Interpolation.Linear` or `Interpolation.BezierCubic` */
9
+ export type Interpolation = (typeof Interpolation)[keyof typeof Interpolation];
10
+ /**
11
+ * A point on a profile graph, in grid units: `x` from 0 (no input) to 10 (full input), `y` from -10 (the setting's min)
12
+ * to 0 (its max), and how the curve runs through it (`i`).
13
+ */
14
+ export interface ProfilePoint {
15
+ x: number;
16
+ y: number;
17
+ i: Interpolation;
18
+ }
19
+ /** A named profile graph */
20
+ export interface ProfileGraph {
21
+ /** Kebab-case for presets (e.g. "overweight"), a UUID for the user's own */
22
+ id: string;
23
+ name: string;
24
+ /** Its points from left to right; the first is at x = 0 and the last at x = 10 */
25
+ points: ProfilePoint[];
26
+ }
27
+ /** How many grid units the graph is across and up */
28
+ export declare const GRID_UNITS = 10;
29
+ /** Most points a profile graph can have */
30
+ export declare const MAX_PROFILE_POINTS = 32;
31
+ /** The ID of the straight-line preset, which changes nothing (the default) */
32
+ export declare const LINEAR_PROFILE_ID = "linear";
33
+ /** The profile graphs PaintCanvas comes with: Linear, Overweight and Underweight */
34
+ export declare const PROFILE_PRESETS: readonly ProfileGraph[];
35
+ /**
36
+ * A copy of the Linear preset's points, e.g. for a new graph.
37
+ */
38
+ export declare const linearPoints: () => ProfilePoint[];
39
+ /**
40
+ * Whether two lists of points are the same.
41
+ *
42
+ * @example
43
+ * samePoints(linearPoints(), linearPoints()); // true
44
+ */
45
+ export declare const samePoints: (a: readonly ProfilePoint[], b: readonly ProfilePoint[]) => boolean;
46
+ /** Whether a list of points draws a straight line from the setting's min to its max, which changes nothing */
47
+ export declare const isLinear: (points: readonly ProfilePoint[]) => boolean;
48
+ /**
49
+ * Where the curve is (in grid units, -10 to 0) at an x in grid units (0 to 10). Between two points it's a cubic curve
50
+ * that leaves and reaches each with its slope (see `slopeAt`), so it's a straight line between two sharp corners.
51
+ */
52
+ export declare const profileY: (points: readonly ProfilePoint[], x: number) => number;
53
+ /**
54
+ * Shape an input (0–1) with a profile graph: how far between the setting's min (0) and max (1) it puts it. Without
55
+ * points, the input is used as it is. The result is kept within 0–1.
56
+ *
57
+ * @example
58
+ * applyProfile(undefined, 0.3); // 0.3
59
+ * applyProfile(PROFILE_PRESETS[1].points, 0.3); // 0.7 (Overweight: a light touch goes most of the way)
60
+ */
61
+ export declare const applyProfile: (points: readonly ProfilePoint[] | undefined, input: number) => number;
@@ -0,0 +1,131 @@
1
+ // src/lib/profiles/index.ts
2
+ /** How the curve runs through a point (a plain object, not an enum, so schemas can use it in scripts run by Node) */
3
+ var Interpolation = {
4
+ /** A sharp corner: straight towards the points either side */
5
+ Linear: "linear",
6
+ /** A smooth curve through the point */
7
+ BezierCubic: "bezier-cubic"
8
+ };
9
+ /** How many grid units the graph is across and up */
10
+ var GRID_UNITS = 10;
11
+ /** Most points a profile graph can have */
12
+ var MAX_PROFILE_POINTS = 32;
13
+ /** The ID of the straight-line preset, which changes nothing (the default) */
14
+ var LINEAR_PROFILE_ID = "linear";
15
+ /** The profile graphs PaintCanvas comes with: Linear, Overweight and Underweight */
16
+ var PROFILE_PRESETS = [
17
+ {
18
+ id: LINEAR_PROFILE_ID,
19
+ name: "Linear",
20
+ points: [{
21
+ x: 0,
22
+ y: -10,
23
+ i: Interpolation.Linear
24
+ }, {
25
+ x: 10,
26
+ y: 0,
27
+ i: Interpolation.Linear
28
+ }]
29
+ },
30
+ {
31
+ id: "overweight",
32
+ name: "Overweight",
33
+ points: [
34
+ {
35
+ x: 0,
36
+ y: -10,
37
+ i: Interpolation.Linear
38
+ },
39
+ {
40
+ x: 3,
41
+ y: -3,
42
+ i: Interpolation.BezierCubic
43
+ },
44
+ {
45
+ x: 10,
46
+ y: 0,
47
+ i: Interpolation.Linear
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ id: "underweight",
53
+ name: "Underweight",
54
+ points: [
55
+ {
56
+ x: 0,
57
+ y: -10,
58
+ i: Interpolation.Linear
59
+ },
60
+ {
61
+ x: 7,
62
+ y: -7,
63
+ i: Interpolation.BezierCubic
64
+ },
65
+ {
66
+ x: 10,
67
+ y: 0,
68
+ i: Interpolation.Linear
69
+ }
70
+ ]
71
+ }
72
+ ];
73
+ /**
74
+ * A copy of the Linear preset's points, e.g. for a new graph.
75
+ */
76
+ var linearPoints = () => PROFILE_PRESETS[0].points.map((point) => ({ ...point }));
77
+ /**
78
+ * Whether two lists of points are the same.
79
+ *
80
+ * @example
81
+ * samePoints(linearPoints(), linearPoints()); // true
82
+ */
83
+ var samePoints = (a, b) => a.length === b.length && a.every((point, index) => point.x === b[index]?.x && point.y === b[index]?.y && point.i === b[index]?.i);
84
+ /** Whether a list of points draws a straight line from the setting's min to its max, which changes nothing */
85
+ var isLinear = (points) => samePoints(points, linearPoints());
86
+ /**
87
+ * The slope a segment of the curve leaves (or reaches) a point with: the segment's own slope at a sharp corner, or the
88
+ * slope between the points either side at a smooth point (the slope between the segment's ends at the first and last).
89
+ */
90
+ var slopeAt = (points, index, segmentSlope) => {
91
+ const point = points[index];
92
+ const before = points[index - 1];
93
+ const after = points[index + 1];
94
+ if (point.i === Interpolation.Linear || !before || !after) return segmentSlope;
95
+ return (after.y - before.y) / (after.x - before.x);
96
+ };
97
+ /**
98
+ * Where the curve is (in grid units, -10 to 0) at an x in grid units (0 to 10). Between two points it's a cubic curve
99
+ * that leaves and reaches each with its slope (see `slopeAt`), so it's a straight line between two sharp corners.
100
+ */
101
+ var profileY = (points, x) => {
102
+ const last = points.length - 1;
103
+ let index = 0;
104
+ while (index < last - 1 && points[index + 1].x < x) index++;
105
+ const a = points[index];
106
+ const b = points[index + 1] ?? a;
107
+ const width = b.x - a.x;
108
+ if (width <= 0) return x < a.x ? a.y : b.y;
109
+ const segmentSlope = (b.y - a.y) / width;
110
+ const startSlope = slopeAt(points, index, segmentSlope) * width;
111
+ const endSlope = slopeAt(points, index + 1, segmentSlope) * width;
112
+ const t = Math.min(1, Math.max(0, (x - a.x) / width));
113
+ const t2 = t * t;
114
+ const t3 = t2 * t;
115
+ return (2 * t3 - 3 * t2 + 1) * a.y + (t3 - 2 * t2 + t) * startSlope + (-2 * t3 + 3 * t2) * b.y + (t3 - t2) * endSlope;
116
+ };
117
+ /**
118
+ * Shape an input (0–1) with a profile graph: how far between the setting's min (0) and max (1) it puts it. Without
119
+ * points, the input is used as it is. The result is kept within 0–1.
120
+ *
121
+ * @example
122
+ * applyProfile(undefined, 0.3); // 0.3
123
+ * applyProfile(PROFILE_PRESETS[1].points, 0.3); // 0.7 (Overweight: a light touch goes most of the way)
124
+ */
125
+ var applyProfile = (points, input) => {
126
+ const amount = Math.min(1, Math.max(0, input));
127
+ if (!points || points.length < 2) return amount;
128
+ const y = profileY(points, amount * 10);
129
+ return Math.min(1, Math.max(0, (y + 10) / 10));
130
+ };
131
+ export { GRID_UNITS, Interpolation, LINEAR_PROFILE_ID, MAX_PROFILE_POINTS, PROFILE_PRESETS, applyProfile, isLinear, linearPoints, profileY, samePoints };