@shortfuse/materialdesignweb 0.7.6 → 0.8.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 (114) hide show
  1. package/README.md +57 -68
  2. package/components/Badge.js +2 -2
  3. package/components/BottomAppBar.js +3 -5
  4. package/components/Box.js +33 -3
  5. package/components/Button.js +48 -21
  6. package/components/Button.md +9 -9
  7. package/components/Card.js +9 -16
  8. package/components/Checkbox.js +45 -36
  9. package/components/CheckboxIcon.js +2 -2
  10. package/components/Chip.js +1 -1
  11. package/components/Dialog.js +228 -359
  12. package/components/DialogActions.js +2 -2
  13. package/components/Divider.js +3 -3
  14. package/components/ExtendedFab.js +4 -8
  15. package/components/Fab.js +1 -2
  16. package/components/FilterChip.js +4 -4
  17. package/components/Headline.js +1 -1
  18. package/components/Icon.js +8 -8
  19. package/components/IconButton.js +9 -14
  20. package/components/Input.js +273 -1
  21. package/components/Layout.js +485 -16
  22. package/components/List.js +6 -4
  23. package/components/ListItem.js +12 -12
  24. package/components/ListOption.js +21 -5
  25. package/components/Listbox.js +239 -0
  26. package/components/Menu.js +77 -526
  27. package/components/MenuItem.js +12 -14
  28. package/components/Nav.js +0 -2
  29. package/components/NavBar.js +8 -79
  30. package/components/NavDrawer.js +12 -11
  31. package/components/NavDrawerItem.js +2 -1
  32. package/components/NavItem.js +18 -8
  33. package/components/NavRail.js +15 -7
  34. package/components/NavRailItem.js +3 -1
  35. package/components/Popup.js +20 -0
  36. package/components/Progress.js +24 -23
  37. package/components/Radio.js +42 -35
  38. package/components/RadioIcon.js +3 -3
  39. package/components/Ripple.js +2 -3
  40. package/components/Search.js +85 -0
  41. package/components/SegmentedButton.js +1 -10
  42. package/components/SegmentedButtonGroup.js +16 -10
  43. package/components/Select.js +4 -4
  44. package/components/Shape.js +1 -1
  45. package/components/Slider.js +43 -50
  46. package/components/Snackbar.js +4 -5
  47. package/components/Surface.js +3 -3
  48. package/components/Switch.js +55 -21
  49. package/components/SwitchIcon.js +10 -8
  50. package/components/Tab.js +11 -9
  51. package/components/TabContent.js +4 -3
  52. package/components/TabList.js +2 -2
  53. package/components/TabPanel.js +11 -8
  54. package/components/TextArea.js +38 -35
  55. package/components/Tooltip.js +2 -2
  56. package/components/TopAppBar.js +65 -147
  57. package/core/Composition.js +985 -628
  58. package/core/CompositionAdapter.js +315 -0
  59. package/core/CustomElement.js +153 -90
  60. package/core/DomAdapter.js +586 -0
  61. package/core/ICustomElement.d.ts +2 -2
  62. package/core/css.js +8 -7
  63. package/core/customTypes.js +53 -31
  64. package/{utils → core}/jsonMergePatch.js +36 -14
  65. package/core/observe.js +111 -57
  66. package/core/optimizations.js +23 -0
  67. package/core/template.js +17 -11
  68. package/core/test.js +126 -0
  69. package/core/typings.d.ts +11 -5
  70. package/core/uid.js +13 -0
  71. package/dist/index.min.js +83 -152
  72. package/dist/index.min.js.map +4 -4
  73. package/dist/meta.json +1 -1
  74. package/mixins/AriaReflectorMixin.js +1 -2
  75. package/mixins/AriaToolbarMixin.js +2 -3
  76. package/mixins/ControlMixin.js +25 -17
  77. package/mixins/DensityMixin.js +0 -1
  78. package/mixins/FlexableMixin.js +1 -2
  79. package/mixins/FormAssociatedMixin.js +13 -10
  80. package/mixins/InputMixin.js +2 -9
  81. package/mixins/KeyboardNavMixin.js +14 -1
  82. package/mixins/PopupMixin.js +757 -0
  83. package/mixins/RTLObserverMixin.js +0 -1
  84. package/mixins/ResizeObserverMixin.js +0 -1
  85. package/mixins/RippleMixin.js +3 -4
  86. package/mixins/ScrollListenerMixin.js +41 -32
  87. package/mixins/SemiStickyMixin.js +151 -0
  88. package/mixins/ShapeMixin.js +29 -24
  89. package/mixins/StateMixin.js +11 -6
  90. package/mixins/SurfaceMixin.js +3 -57
  91. package/mixins/TextFieldMixin.js +57 -65
  92. package/mixins/ThemableMixin.js +78 -156
  93. package/mixins/TooltipTriggerMixin.js +7 -13
  94. package/mixins/TouchTargetMixin.js +4 -3
  95. package/package.json +9 -5
  96. package/theming/index.js +1 -1
  97. package/theming/themableMixinLoader.js +12 -0
  98. package/utils/{hct → material-color}/blend.js +8 -10
  99. package/utils/{hct → material-color/hct}/Cam16.js +196 -69
  100. package/utils/{hct → material-color/hct}/Hct.js +61 -19
  101. package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
  102. package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
  103. package/utils/{hct → material-color}/helper.js +11 -18
  104. package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
  105. package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
  106. package/utils/material-color/scheme/Scheme.js +376 -0
  107. package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
  108. package/utils/popup.js +46 -25
  109. package/components/ListSelect.js +0 -220
  110. package/components/Option.js +0 -91
  111. package/components/Pane.js +0 -281
  112. package/core/identify.js +0 -40
  113. package/utils/hct/Scheme.js +0 -587
  114. /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
@@ -15,16 +15,14 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- // libmonet is designed to have a consistent API across platforms
19
- // and modular components that can be moved around easily. Using a class as a
20
- // namespace facilitates this.
21
- //
22
- // tslint:disable:class-as-namespace
18
+ import Cam16 from './hct/Cam16.js';
19
+ import Hct from './hct/Hct.js';
20
+ import * as colorUtils from './utils/color.js';
21
+ import * as mathUtils from './utils/math.js';
23
22
 
24
- import Cam16 from './Cam16.js';
25
- import Hct from './Hct.js';
26
- import * as colorUtils from './colorUtils.js';
27
- import * as mathUtils from './mathUtils.js';
23
+ /**
24
+ * Functions for blending in HCT and CAM16.
25
+ */
28
26
 
29
27
  /**
30
28
  * Blend the design color's HCT hue towards the key color's HCT
@@ -43,7 +41,7 @@ export function harmonize(designColor, sourceColor) {
43
41
  const rotationDegrees = Math.min(differenceDegrees * 0.5, 15);
44
42
  const outputHue = mathUtils.sanitizeDegreesDouble(
45
43
  fromHct.hue
46
- + rotationDegrees * mathUtils.rotationDirection(fromHct.hue, toHct.hue),
44
+ + rotationDegrees * mathUtils.rotationDirection(fromHct.hue, toHct.hue),
47
45
  );
48
46
  return Hct.from(outputHue, fromHct.chroma, fromHct.tone).toInt();
49
47
  }
@@ -15,9 +15,10 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
+ import * as utils from '../utils/color.js';
19
+ import * as math from '../utils/math.js';
20
+
18
21
  import ViewingConditions from './ViewingConditions.js';
19
- import * as utils from './colorUtils.js';
20
- import * as math from './mathUtils.js';
21
22
 
22
23
  /**
23
24
  * CAM16, a color appearance model. Colors are not just defined by their hex
@@ -37,62 +38,6 @@ import * as math from './mathUtils.js';
37
38
  * hue 203, chroma 3, lightness 100)
38
39
  */
39
40
  export default class Cam16 {
40
- /**
41
- * All of the CAM16 dimensions can be calculated from 3 of the dimensions, in
42
- * the following combinations:
43
- * - {j or q} and {c, m, or s} and hue
44
- * - jstar, astar, bstar
45
- * Prefer using a static method that constructs from 3 of those dimensions.
46
- * This constructor is intended for those methods to use to return all
47
- * possible dimensions.
48
- * @param {number} hue
49
- * @param {number} chroma informally, colorfulness / color intensity. like saturation
50
- * in HSL, except perceptually accurate.
51
- * @param {number} j lightness
52
- * @param {number} q brightness; ratio of lightness to white point's lightness
53
- * @param {number} m colorfulness
54
- * @param {number} s saturation; ratio of chroma to white point's chroma
55
- * @param {number} jstar CAM16-UCS J coordinate
56
- * @param {number} astar CAM16-UCS a coordinate
57
- * @param {number} bstar CAM16-UCS b coordinate
58
- */
59
- constructor(hue, chroma, j, q, m, s, jstar, astar, bstar) {
60
- /** @readonly */
61
- this.hue = hue;
62
- /** @readonly */
63
- this.chroma = chroma;
64
- /** @readonly */
65
- this.j = j;
66
- /** @readonly */
67
- this.q = q;
68
- /** @readonly */
69
- this.m = m;
70
- /** @readonly */
71
- this.s = s;
72
- /** @readonly */
73
- this.jstar = jstar;
74
- /** @readonly */
75
- this.astar = astar;
76
- /** @readonly */
77
- this.bstar = bstar;
78
- }
79
-
80
- /**
81
- * CAM16 instances also have coordinates in the CAM16-UCS space, called J*,
82
- * a*, b*, or jstar, astar, bstar in code. CAM16-UCS is included in the CAM16
83
- * specification, and is used to measure distances between colors.
84
- * @param {Cam16} other
85
- * @return {number}
86
- */
87
- distance(other) {
88
- const dJ = this.jstar - other.jstar;
89
- const dA = this.astar - other.astar;
90
- const dB = this.bstar - other.bstar;
91
- const dEPrime = Math.sqrt(dJ * dJ + dA * dA + dB * dB);
92
- const dE = 1.41 * dEPrime ** 0.63;
93
- return dE;
94
- }
95
-
96
41
  /**
97
42
  * @param {number} argb ARGB representation of a color.
98
43
  * @return {Cam16} CAM16 color, assuming the color was viewed in default viewing
@@ -148,19 +93,19 @@ export default class Cam16 {
148
93
 
149
94
  const ac = p2 * viewingConditions.nbb;
150
95
  const j = 100
151
- * (ac / viewingConditions.aw) ** (viewingConditions.c * viewingConditions.z);
96
+ * (ac / viewingConditions.aw) ** (viewingConditions.c * viewingConditions.z);
152
97
  const q = (4 / viewingConditions.c) * Math.sqrt(j / 100)
153
- * (viewingConditions.aw + 4) * viewingConditions.fLRoot;
98
+ * (viewingConditions.aw + 4) * viewingConditions.fLRoot;
154
99
  const huePrime = hue < 20.14 ? hue + 360 : hue;
155
100
  const eHue = 0.25 * (Math.cos((huePrime * Math.PI) / 180 + 2) + 3.8);
156
101
  const p1 = (50_000 / 13) * eHue * viewingConditions.nc * viewingConditions.ncb;
157
102
  const t = (p1 * Math.sqrt(a * a + b * b)) / (u + 0.305);
158
103
  const alpha = t ** 0.9
159
- * (1.64 - 0.29 ** viewingConditions.n) ** 0.73;
104
+ * (1.64 - 0.29 ** viewingConditions.n) ** 0.73;
160
105
  const c = alpha * Math.sqrt(j / 100);
161
106
  const m = c * viewingConditions.fLRoot;
162
107
  const s = 50
163
- * Math.sqrt((alpha * viewingConditions.c) / (viewingConditions.aw + 4));
108
+ * Math.sqrt((alpha * viewingConditions.c) / (viewingConditions.aw + 4));
164
109
  const jstar = ((1 + 100 * 0.007) * j) / (1 + 0.007 * j);
165
110
  const mstar = (1 / 0.0228) * Math.log(1 + 0.0228 * m);
166
111
  const astar = mstar * Math.cos(hueRadians);
@@ -188,11 +133,11 @@ export default class Cam16 {
188
133
  */
189
134
  static fromJchInViewingConditions(j, c, h, viewingConditions) {
190
135
  const q = (4 / viewingConditions.c) * Math.sqrt(j / 100)
191
- * (viewingConditions.aw + 4) * viewingConditions.fLRoot;
136
+ * (viewingConditions.aw + 4) * viewingConditions.fLRoot;
192
137
  const m = c * viewingConditions.fLRoot;
193
138
  const alpha = c / Math.sqrt(j / 100);
194
139
  const s = 50
195
- * Math.sqrt((alpha * viewingConditions.c) / (viewingConditions.aw + 4));
140
+ * Math.sqrt((alpha * viewingConditions.c) / (viewingConditions.aw + 4));
196
141
  const hueRadians = (h * Math.PI) / 180;
197
142
  const jstar = ((1 + 100 * 0.007) * j) / (1 + 0.007 * j);
198
143
  const mstar = (1 / 0.0228) * Math.log(1 + 0.0228 * m);
@@ -236,6 +181,137 @@ export default class Cam16 {
236
181
  return Cam16.fromJchInViewingConditions(j, c, h, viewingConditions);
237
182
  }
238
183
 
184
+ /**
185
+ * Given color expressed in XYZ and viewed in [viewingConditions], convert to
186
+ * CAM16.
187
+ * @param {number} x
188
+ * @param {number} y
189
+ * @param {number} z
190
+ * @param {ViewingConditions} viewingConditions
191
+ * @return {Cam16}
192
+ */
193
+ static fromXyzInViewingConditions(x, y, z, viewingConditions) {
194
+ // Transform XYZ to 'cone'/'rgb' responses
195
+
196
+ const rC = 0.401_288 * x + 0.650_173 * y - 0.051_461 * z;
197
+ const gC = -0.250_268 * x + 1.204_414 * y + 0.045_854 * z;
198
+ const bC = -0.002_079 * x + 0.048_952 * y + 0.953_127 * z;
199
+
200
+ // Discount illuminant
201
+ const rD = viewingConditions.rgbD[0] * rC;
202
+ const gD = viewingConditions.rgbD[1] * gC;
203
+ const bD = viewingConditions.rgbD[2] * bC;
204
+
205
+ // chromatic adaptation
206
+ const rAF = ((viewingConditions.fl * Math.abs(rD)) / 100) ** 0.42;
207
+ const gAF = ((viewingConditions.fl * Math.abs(gD)) / 100) ** 0.42;
208
+ const bAF = ((viewingConditions.fl * Math.abs(bD)) / 100) ** 0.42;
209
+ const rA = (math.signum(rD) * 400 * rAF) / (rAF + 27.13);
210
+ const gA = (math.signum(gD) * 400 * gAF) / (gAF + 27.13);
211
+ const bA = (math.signum(bD) * 400 * bAF) / (bAF + 27.13);
212
+
213
+ // redness-greenness
214
+ const a = (11 * rA + -12 * gA + bA) / 11;
215
+ // yellowness-blueness
216
+ const b = (rA + gA - 2 * bA) / 9;
217
+
218
+ // auxiliary components
219
+ const u = (20 * rA + 20 * gA + 21 * bA) / 20;
220
+ const p2 = (40 * rA + 20 * gA + bA) / 20;
221
+
222
+ // hue
223
+ const atan2 = Math.atan2(b, a);
224
+ const atanDegrees = (atan2 * 180) / Math.PI;
225
+ const hue = atanDegrees < 0 ? atanDegrees + 360
226
+ : (atanDegrees >= 360 ? atanDegrees - 360
227
+ : atanDegrees);
228
+ const hueRadians = (hue * Math.PI) / 180;
229
+
230
+ // achromatic response to color
231
+ const ac = p2 * viewingConditions.nbb;
232
+
233
+ // CAM16 lightness and brightness
234
+ const J = 100
235
+ * (ac / viewingConditions.aw) ** (viewingConditions.c * viewingConditions.z);
236
+ const Q = (4 / viewingConditions.c) * Math.sqrt(J / 100)
237
+ * (viewingConditions.aw + 4) * (viewingConditions.fLRoot);
238
+
239
+ const huePrime = (hue < 20.14) ? hue + 360 : hue;
240
+ const eHue = (1 / 4) * (Math.cos((huePrime * Math.PI) / 180 + 2) + 3.8);
241
+ const p1 = (50_000 / 13) * eHue * viewingConditions.nc * viewingConditions.ncb;
242
+ const t = (p1 * Math.sqrt(a * a + b * b)) / (u + 0.305);
243
+ const alpha = t ** 0.9
244
+ * (1.64 - 0.29 ** viewingConditions.n) ** 0.73;
245
+ // CAM16 chroma, colorfulness, chroma
246
+ const C = alpha * Math.sqrt(J / 100);
247
+ const M = C * viewingConditions.fLRoot;
248
+ const s = 50
249
+ * Math.sqrt((alpha * viewingConditions.c) / (viewingConditions.aw + 4));
250
+
251
+ // CAM16-UCS components
252
+ const jstar = ((1 + 100 * 0.007) * J) / (1 + 0.007 * J);
253
+ const mstar = Math.log(1 + 0.0228 * M) / 0.0228;
254
+ const astar = mstar * Math.cos(hueRadians);
255
+ const bstar = mstar * Math.sin(hueRadians);
256
+ return new Cam16(hue, C, J, Q, M, s, jstar, astar, bstar);
257
+ }
258
+
259
+ /**
260
+ * All of the CAM16 dimensions can be calculated from 3 of the dimensions, in
261
+ * the following combinations:
262
+ * - {j or q} and {c, m, or s} and hue
263
+ * - jstar, astar, bstar
264
+ * Prefer using a static method that constructs from 3 of those dimensions.
265
+ * This constructor is intended for those methods to use to return all
266
+ * possible dimensions.
267
+ * @param {number} hue
268
+ * @param {number} chroma informally, colorfulness / color intensity. like saturation
269
+ * in HSL, except perceptually accurate.
270
+ * @param {number} j lightness
271
+ * @param {number} q brightness; ratio of lightness to white point's lightness
272
+ * @param {number} m colorfulness
273
+ * @param {number} s saturation; ratio of chroma to white point's chroma
274
+ * @param {number} jstar CAM16-UCS J coordinate
275
+ * @param {number} astar CAM16-UCS a coordinate
276
+ * @param {number} bstar CAM16-UCS b coordinate
277
+ */
278
+ constructor(hue, chroma, j, q, m, s, jstar, astar, bstar) {
279
+ /** @readonly */
280
+ this.hue = hue;
281
+ /** @readonly */
282
+ this.chroma = chroma;
283
+ /** @readonly */
284
+ this.j = j;
285
+ /** @readonly */
286
+ this.q = q;
287
+ /** @readonly */
288
+ this.m = m;
289
+ /** @readonly */
290
+ this.s = s;
291
+ /** @readonly */
292
+ this.jstar = jstar;
293
+ /** @readonly */
294
+ this.astar = astar;
295
+ /** @readonly */
296
+ this.bstar = bstar;
297
+ }
298
+
299
+ /**
300
+ * CAM16 instances also have coordinates in the CAM16-UCS space, called J*,
301
+ * a*, b*, or jstar, astar, bstar in code. CAM16-UCS is included in the CAM16
302
+ * specification, and is used to measure distances between colors.
303
+ * @param {Cam16} other
304
+ * @return {number}
305
+ */
306
+ distance(other) {
307
+ const dJ = this.jstar - other.jstar;
308
+ const dA = this.astar - other.astar;
309
+ const dB = this.bstar - other.bstar;
310
+ const dEPrime = Math.sqrt(dJ * dJ + dA * dA + dB * dB);
311
+ const dE = 1.41 * dEPrime ** 0.63;
312
+ return dE;
313
+ }
314
+
239
315
  /**
240
316
  * @return {number} ARGB representation of color, assuming the color was viewed in
241
317
  * default viewing conditions, which are near-identical to the default
@@ -260,7 +336,7 @@ export default class Cam16 {
260
336
 
261
337
  const eHue = 0.25 * (Math.cos(hRad + 2) + 3.8);
262
338
  const ac = viewingConditions.aw
263
- * (this.j / 100) ** (1 / viewingConditions.c / viewingConditions.z);
339
+ * (this.j / 100) ** (1 / viewingConditions.c / viewingConditions.z);
264
340
  const p1 = eHue * (50_000 / 13) * viewingConditions.nc * viewingConditions.ncb;
265
341
  const p2 = ac / viewingConditions.nbb;
266
342
 
@@ -268,7 +344,7 @@ export default class Cam16 {
268
344
  const hCos = Math.cos(hRad);
269
345
 
270
346
  const gamma = (23 * (p2 + 0.305) * t)
271
- / (23 * p1 + 11 * t * hCos + 108 * t * hSin);
347
+ / (23 * p1 + 11 * t * hCos + 108 * t * hSin);
272
348
  const a = gamma * hCos;
273
349
  const b = gamma * hSin;
274
350
  const rA = (460 * p2 + 451 * a + 288 * b) / 1403;
@@ -277,13 +353,13 @@ export default class Cam16 {
277
353
 
278
354
  const rCBase = Math.max(0, (27.13 * Math.abs(rA)) / (400 - Math.abs(rA)));
279
355
  const rC = math.signum(rA) * (100 / viewingConditions.fl)
280
- * rCBase ** (1 / 0.42);
356
+ * rCBase ** (1 / 0.42);
281
357
  const gCBase = Math.max(0, (27.13 * Math.abs(gA)) / (400 - Math.abs(gA)));
282
358
  const gC = math.signum(gA) * (100 / viewingConditions.fl)
283
- * gCBase ** (1 / 0.42);
359
+ * gCBase ** (1 / 0.42);
284
360
  const bCBase = Math.max(0, (27.13 * Math.abs(bA)) / (400 - Math.abs(bA)));
285
361
  const bC = math.signum(bA) * (100 / viewingConditions.fl)
286
- * bCBase ** (1 / 0.42);
362
+ * bCBase ** (1 / 0.42);
287
363
  const rF = rC / viewingConditions.rgbD[0];
288
364
  const gF = gC / viewingConditions.rgbD[1];
289
365
  const bF = bC / viewingConditions.rgbD[2];
@@ -295,4 +371,55 @@ export default class Cam16 {
295
371
  const argb = utils.argbFromXyz(x, y, z);
296
372
  return argb;
297
373
  }
374
+
375
+ /**
376
+ * XYZ representation of CAM16 seen in [viewingConditions].
377
+ * @param {ViewingConditions} viewingConditions
378
+ * @return {number[]}
379
+ */
380
+ xyzInViewingConditions(viewingConditions) {
381
+ const alpha = (this.chroma === 0 || this.j === 0)
382
+ ? 0
383
+ : this.chroma / Math.sqrt(this.j / 100);
384
+
385
+ const t = (alpha / (1.64 - 0.29 ** viewingConditions.n) ** 0.73) ** (1 / 0.9);
386
+ const hRad = (this.hue * Math.PI) / 180;
387
+
388
+ const eHue = 0.25 * (Math.cos(hRad + 2) + 3.8);
389
+ const ac = viewingConditions.aw
390
+ * (this.j / 100) ** (1 / viewingConditions.c / viewingConditions.z);
391
+ const p1 = eHue * (50_000 / 13) * viewingConditions.nc * viewingConditions.ncb;
392
+
393
+ const p2 = (ac / viewingConditions.nbb);
394
+
395
+ const hSin = Math.sin(hRad);
396
+ const hCos = Math.cos(hRad);
397
+
398
+ const gamma = (23 * (p2 + 0.305) * t)
399
+ / (23 * p1 + 11 * t * hCos + 108 * t * hSin);
400
+ const a = gamma * hCos;
401
+ const b = gamma * hSin;
402
+ const rA = (460 * p2 + 451 * a + 288 * b) / 1403;
403
+ const gA = (460 * p2 - 891 * a - 261 * b) / 1403;
404
+ const bA = (460 * p2 - 220 * a - 6300 * b) / 1403;
405
+
406
+ const rCBase = Math.max(0, (27.13 * Math.abs(rA)) / (400 - Math.abs(rA)));
407
+ const rC = math.signum(rA) * (100 / viewingConditions.fl)
408
+ * rCBase ** (1 / 0.42);
409
+ const gCBase = Math.max(0, (27.13 * Math.abs(gA)) / (400 - Math.abs(gA)));
410
+ const gC = math.signum(gA) * (100 / viewingConditions.fl)
411
+ * gCBase ** (1 / 0.42);
412
+ const bCBase = Math.max(0, (27.13 * Math.abs(bA)) / (400 - Math.abs(bA)));
413
+ const bC = math.signum(bA) * (100 / viewingConditions.fl)
414
+ * bCBase ** (1 / 0.42);
415
+ const rF = rC / viewingConditions.rgbD[0];
416
+ const gF = gC / viewingConditions.rgbD[1];
417
+ const bF = bC / viewingConditions.rgbD[2];
418
+
419
+ const x = 1.862_067_86 * rF - 1.011_254_63 * gF + 0.149_186_77 * bF;
420
+ const y = 0.387_526_54 * rF + 0.621_447_44 * gF - 0.008_973_98 * bF;
421
+ const z = -0.015_841_5 * rF - 0.034_122_94 * gF + 1.049_964_44 * bF;
422
+
423
+ return [x, y, z];
424
+ }
298
425
  }
@@ -31,8 +31,10 @@
31
31
  * and a difference of 50 guarantees a contrast ratio >= 4.5.
32
32
  */
33
33
 
34
+ import * as utils from '../utils/color.js';
35
+
34
36
  import Cam16 from './Cam16.js';
35
- import * as utils from './colorUtils.js';
37
+ import ViewingConditions from './ViewingConditions.js';
36
38
  import * as hctSolver from './hctSolver.js';
37
39
 
38
40
  /**
@@ -50,15 +52,6 @@ export default class Hct {
50
52
  * @return HCT representation of a color in default viewing conditions.
51
53
  */
52
54
 
53
- /** @type {number} */
54
- internalHue;
55
-
56
- /** @type {number} */
57
- internalChroma;
58
-
59
- /** @type {number} */
60
- internalTone;
61
-
62
55
  /**
63
56
  * @param {number} hue
64
57
  * @param {number} chroma
@@ -77,6 +70,24 @@ export default class Hct {
77
70
  return new Hct(argb);
78
71
  }
79
72
 
73
+ /** @type {number} */
74
+ internalHue;
75
+
76
+ /** @type {number} */
77
+ internalChroma;
78
+
79
+ /** @type {number} */
80
+ internalTone;
81
+
82
+ /** @param {number} argb */
83
+ constructor(argb) {
84
+ const cam = Cam16.fromInt(argb);
85
+ this.internalHue = cam.hue;
86
+ this.internalChroma = cam.chroma;
87
+ this.internalTone = utils.lstarFromArgb(argb);
88
+ this.argb = argb;
89
+ }
90
+
80
91
  /** @return {number} */
81
92
  toInt() {
82
93
  return this.argb;
@@ -149,15 +160,6 @@ export default class Hct {
149
160
  );
150
161
  }
151
162
 
152
- /** @param {number} argb */
153
- constructor(argb) {
154
- const cam = Cam16.fromInt(argb);
155
- this.internalHue = cam.hue;
156
- this.internalChroma = cam.chroma;
157
- this.internalTone = utils.lstarFromArgb(argb);
158
- this.argb = argb;
159
- }
160
-
161
163
  /**
162
164
  * @private
163
165
  * @param {number} argb
@@ -169,4 +171,44 @@ export default class Hct {
169
171
  this.internalTone = utils.lstarFromArgb(argb);
170
172
  this.argb = argb;
171
173
  }
174
+
175
+ /**
176
+ * Translates a color into different [ViewingConditions].
177
+ *
178
+ * Colors change appearance. They look different with lights on versus off,
179
+ * the same color, as in hex code, on white looks different when on black.
180
+ * This is called color relativity, most famously explicated by Josef Albers
181
+ * in Interaction of Color.
182
+ *
183
+ * In color science, color appearance models can account for this and
184
+ * calculate the appearance of a color in different settings. HCT is based on
185
+ * CAM16, a color appearance model, and uses it to make these calculations.
186
+ *
187
+ * See [ViewingConditions.make] for parameters affecting color appearance.
188
+ * @param {ViewingConditions} vc
189
+ * @return {Hct}
190
+ */
191
+ inViewingConditions(vc) {
192
+ // 1. Use CAM16 to find XYZ coordinates of color in specified VC.
193
+ const cam = Cam16.fromInt(this.toInt());
194
+ const viewedInVc = cam.xyzInViewingConditions(vc);
195
+
196
+ // 2. Create CAM16 of those XYZ coordinates in default VC.
197
+ const recastInVc = Cam16.fromXyzInViewingConditions(
198
+ viewedInVc[0],
199
+ viewedInVc[1],
200
+ viewedInVc[2],
201
+ ViewingConditions.make(),
202
+ );
203
+
204
+ // 3. Create HCT from:
205
+ // - CAM16 using default VC with XYZ coordinates in specified VC.
206
+ // - L* converted from Y in XYZ coordinates in specified VC.
207
+ const recastHct = Hct.from(
208
+ recastInVc.hue,
209
+ recastInVc.chroma,
210
+ utils.lstarFromY(viewedInVc[1]),
211
+ );
212
+ return recastHct;
213
+ }
172
214
  }
@@ -15,8 +15,8 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import * as utils from './colorUtils.js';
19
- import * as math from './mathUtils.js';
18
+ import * as utils from '../utils/color.js';
19
+ import * as math from '../utils/math.js';
20
20
 
21
21
  /**
22
22
  * In traditional color spaces, a color can be identified solely by the
@@ -85,7 +85,7 @@ export default class ViewingConditions {
85
85
  const k4 = k * k * k * k;
86
86
  const k4F = 1 - k4;
87
87
  const fl = k4 * adaptingLuminance
88
- + 0.1 * k4F * k4F * Math.cbrt(5 * adaptingLuminance);
88
+ + 0.1 * k4F * k4F * Math.cbrt(5 * adaptingLuminance);
89
89
  const n = utils.yFromLstar(backgroundLstar) / whitePoint[1];
90
90
  const z = 1.48 + Math.sqrt(n);
91
91
  const nbb = 0.725 / n ** 0.2;
@@ -15,19 +15,11 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
+ import * as colorUtils from '../utils/color.js';
19
+ import * as mathUtils from '../utils/math.js';
20
+
18
21
  import Cam16 from './Cam16.js';
19
22
  import ViewingConditions from './ViewingConditions.js';
20
- import * as colorUtils from './colorUtils.js';
21
- import * as mathUtils from './mathUtils.js';
22
-
23
- /**
24
- * A class that solves the HCT equation.
25
- */
26
- // libmonet is designed to have a consistent API across platforms
27
- // and modular components that can be moved around easily. Using a class as a
28
- // namespace facilitates this.
29
- //
30
- // tslint:disable-next-line:class-as-namespace
31
23
 
32
24
  export const SCALED_DISCOUNT_FROM_LINRGB = [
33
25
  [
@@ -476,9 +468,10 @@ function findResultByJ(hueRadians, chroma, y) {
476
468
  const alpha = chroma === 0 || j === 0 ? 0 : chroma / Math.sqrt(jNormalized);
477
469
  const t = (alpha * tInnerCoeff) ** (1 / 0.9);
478
470
  const ac = viewingConditions.aw
479
- * jNormalized ** (1 / viewingConditions.c / viewingConditions.z);
471
+ * jNormalized ** (1 / viewingConditions.c / viewingConditions.z);
480
472
  const p2 = ac / viewingConditions.nbb;
481
- const gamma = 23 * (p2 + 0.305) * t / (23 * p1 + 11 * t * hCos + 108 * t * hSin);
473
+ const gamma = (23 * (p2 + 0.305) * t)
474
+ / (23 * p1 + 11 * t * hCos + 108 * t * hSin);
482
475
  const a = gamma * hCos;
483
476
  const b = gamma * hSin;
484
477
  const rA = (460 * p2 + 451 * a + 288 * b) / 1403;
@@ -491,9 +484,9 @@ function findResultByJ(hueRadians, chroma, y) {
491
484
  [rCScaled, gCScaled, bCScaled],
492
485
  LINRGB_FROM_SCALED_DISCOUNT,
493
486
  );
494
- // ===========================================================
495
- // Operations inlined from Cam16 to avoid repeated calculation
496
- // ===========================================================
487
+ // ===========================================================
488
+ // Operations inlined from Cam16 to avoid repeated calculation
489
+ // ===========================================================
497
490
  if (linrgb[0] < 0 || linrgb[1] < 0 || linrgb[2] < 0) {
498
491
  return 0;
499
492
  }
@@ -1,9 +1,9 @@
1
- import CorePalette from './CorePalette.js';
2
- import Scheme from './Scheme.js';
3
1
  import { harmonize } from './blend.js';
4
- import * as colorUtils from './colorUtils.js';
2
+ import CorePalette from './palettes/CorePalette.js';
3
+ import Scheme from './scheme/Scheme.js';
4
+ import * as colorUtils from './utils/color.js';
5
5
 
6
- /** @typedef {import('./TonalPalette.js').default} TonalPalette */
6
+ /** @typedef {import("./palettes/TonalPalette.js").default} TonalPalette */
7
7
 
8
8
  /**
9
9
  * @param {string} value
@@ -109,7 +109,13 @@ function cssVariablesFromScheme(scheme) {
109
109
  --mdw-color__on-background: ${cssVarFromArgb(scheme.onBackground)};
110
110
  --mdw-color__surface: ${cssVarFromArgb(scheme.surface)};
111
111
  --mdw-color__on-surface: ${cssVarFromArgb(scheme.onSurface)};
112
- --mdw-color__surface-variant: ${cssVarFromArgb(scheme.surfaceVariant)};
112
+ --mdw-color__surface-dim: ${cssVarFromArgb(scheme.surfaceDim)};
113
+ --mdw-color__surface-bright: ${cssVarFromArgb(scheme.surfaceBright)};
114
+ --mdw-color__surface-container-lowest: ${cssVarFromArgb(scheme.surfaceContainerLowest)};
115
+ --mdw-color__surface-container-low: ${cssVarFromArgb(scheme.surfaceContainerLow)};
116
+ --mdw-color__surface-container: ${cssVarFromArgb(scheme.surfaceContainer)};
117
+ --mdw-color__surface-container-high: ${cssVarFromArgb(scheme.surfaceContainerHigh)};
118
+ --mdw-color__surface-container-highest: ${cssVarFromArgb(scheme.surfaceContainerHighest)};
113
119
  --mdw-color__on-surface-variant: ${cssVarFromArgb(scheme.onSurfaceVariant)};
114
120
  --mdw-color__outline: ${cssVarFromArgb(scheme.outline)};
115
121
  --mdw-color__outline-variant: ${cssVarFromArgb(scheme.outlineVariant)};
@@ -135,19 +141,6 @@ function cssVariablesFromCustom(name, tonalPalette, isDark) {
135
141
  --mdw-color__${name}-container: ${cssVarFromArgb(tonalPalette.tone(isDark ? 30 : 90))};
136
142
  --mdw-color__on-${name}-container: ${cssVarFromArgb(tonalPalette.tone(isDark ? 90 : 10))};
137
143
  }
138
- .mdw-custom[color="${name}"] {
139
- --mdw-bg: var(--mdw-color__${name});
140
- --mdw-ink: var(--mdw-color__on-${name});
141
- }
142
- .mdw-custom[color="${name}-container"] {
143
- --mdw-bg: var(--mdw-color__${name}-container);
144
- --mdw-ink: var(--mdw-color__on-${name}-container);
145
- }
146
- .mdw-custom[ink="${name}"] {
147
- --mdw-ink: var(--mdw-color__${name});
148
- }
149
-
150
-
151
144
  `;
152
145
  }
153
146