simview 3.2__py3-none-any.whl

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 (163) hide show
  1. simview/__init__.py +69 -0
  2. simview/__main__.py +174 -0
  3. simview/launcher.py +109 -0
  4. simview/live.py +204 -0
  5. simview/merge.py +593 -0
  6. simview/model.py +690 -0
  7. simview/py.typed +0 -0
  8. simview/scene.py +603 -0
  9. simview/server.py +739 -0
  10. simview/state.py +190 -0
  11. simview/static/css/controls.css +36 -0
  12. simview/static/js/SimView.js +601 -0
  13. simview/static/js/components/AnimationController.js +654 -0
  14. simview/static/js/components/BatchManager.js +198 -0
  15. simview/static/js/components/InteractionController.js +446 -0
  16. simview/static/js/components/InteractionControls.js +116 -0
  17. simview/static/js/components/Scene.js +166 -0
  18. simview/static/js/components/StateStore.js +188 -0
  19. simview/static/js/config.js +233 -0
  20. simview/static/js/main.js +3 -0
  21. simview/static/js/objects/Body.js +616 -0
  22. simview/static/js/objects/StaticObject.js +181 -0
  23. simview/static/js/objects/Terrain.js +514 -0
  24. simview/static/js/objects/utils.js +378 -0
  25. simview/static/js/ui/AnalysisPanel.js +233 -0
  26. simview/static/js/ui/BatchLegend.js +207 -0
  27. simview/static/js/ui/BodyStateWindow.js +521 -0
  28. simview/static/js/ui/Controls.js +586 -0
  29. simview/static/js/ui/ErrorMetrics.js +664 -0
  30. simview/static/js/ui/Legend.js +87 -0
  31. simview/static/js/ui/PlaybackControls.js +314 -0
  32. simview/static/js/ui/ScalarPlotter.js +575 -0
  33. simview/static/js/utils/blobCodec.js +73 -0
  34. simview/static/js/utils/bodyTransforms.js +151 -0
  35. simview/static/js/utils/csv.js +46 -0
  36. simview/static/js/utils/errorMath.js +69 -0
  37. simview/static/js/utils/injectStyles.js +16 -0
  38. simview/static/js/utils/interpolate.js +65 -0
  39. simview/static/js/utils/liveFollow.js +17 -0
  40. simview/static/js/utils/loadRecordingLibs.js +34 -0
  41. simview/static/js/utils/viewState.js +226 -0
  42. simview/static/lib/chroma-js-3.1.2/index.min.js +8 -0
  43. simview/static/lib/chroma-js-3.1.2/src/Color.js +49 -0
  44. simview/static/lib/chroma-js-3.1.2/src/chroma.js +10 -0
  45. simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js +81 -0
  46. simview/static/lib/chroma-js-3.1.2/src/colors/w3cx11.js +164 -0
  47. simview/static/lib/chroma-js-3.1.2/src/generator/average.js +88 -0
  48. simview/static/lib/chroma-js-3.1.2/src/generator/bezier.js +86 -0
  49. simview/static/lib/chroma-js-3.1.2/src/generator/blend.js +57 -0
  50. simview/static/lib/chroma-js-3.1.2/src/generator/cubehelix.js +87 -0
  51. simview/static/lib/chroma-js-3.1.2/src/generator/mix.js +19 -0
  52. simview/static/lib/chroma-js-3.1.2/src/generator/random.js +12 -0
  53. simview/static/lib/chroma-js-3.1.2/src/generator/scale.js +394 -0
  54. simview/static/lib/chroma-js-3.1.2/src/interpolator/_hsx.js +59 -0
  55. simview/static/lib/chroma-js-3.1.2/src/interpolator/hcg.js +12 -0
  56. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsi.js +12 -0
  57. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsl.js +12 -0
  58. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsv.js +12 -0
  59. simview/static/lib/chroma-js-3.1.2/src/interpolator/index.js +1 -0
  60. simview/static/lib/chroma-js-3.1.2/src/interpolator/lab.js +19 -0
  61. simview/static/lib/chroma-js-3.1.2/src/interpolator/lch.js +13 -0
  62. simview/static/lib/chroma-js-3.1.2/src/interpolator/lrgb.js +19 -0
  63. simview/static/lib/chroma-js-3.1.2/src/interpolator/num.js +15 -0
  64. simview/static/lib/chroma-js-3.1.2/src/interpolator/oklab.js +19 -0
  65. simview/static/lib/chroma-js-3.1.2/src/interpolator/oklch.js +12 -0
  66. simview/static/lib/chroma-js-3.1.2/src/interpolator/rgb.js +18 -0
  67. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/cmyk2rgb.js +16 -0
  68. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/index.js +27 -0
  69. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/rgb2cmyk.js +17 -0
  70. simview/static/lib/chroma-js-3.1.2/src/io/css/css2rgb.js +238 -0
  71. simview/static/lib/chroma-js-3.1.2/src/io/css/hsl2css.js +26 -0
  72. simview/static/lib/chroma-js-3.1.2/src/io/css/index.js +27 -0
  73. simview/static/lib/chroma-js-3.1.2/src/io/css/lab2css.js +24 -0
  74. simview/static/lib/chroma-js-3.1.2/src/io/css/lch2css.js +24 -0
  75. simview/static/lib/chroma-js-3.1.2/src/io/css/oklab2css.js +16 -0
  76. simview/static/lib/chroma-js-3.1.2/src/io/css/oklch2css.js +16 -0
  77. simview/static/lib/chroma-js-3.1.2/src/io/css/rgb2css.js +61 -0
  78. simview/static/lib/chroma-js-3.1.2/src/io/gl/index.js +22 -0
  79. simview/static/lib/chroma-js-3.1.2/src/io/hcg/hcg2rgb.js +55 -0
  80. simview/static/lib/chroma-js-3.1.2/src/io/hcg/index.js +27 -0
  81. simview/static/lib/chroma-js-3.1.2/src/io/hcg/rgb2hcg.js +23 -0
  82. simview/static/lib/chroma-js-3.1.2/src/io/hex/hex2rgb.js +56 -0
  83. simview/static/lib/chroma-js-3.1.2/src/io/hex/index.js +29 -0
  84. simview/static/lib/chroma-js-3.1.2/src/io/hex/rgb2hex.js +29 -0
  85. simview/static/lib/chroma-js-3.1.2/src/io/hsi/hsi2rgb.js +45 -0
  86. simview/static/lib/chroma-js-3.1.2/src/io/hsi/index.js +27 -0
  87. simview/static/lib/chroma-js-3.1.2/src/io/hsi/rgb2hsi.js +31 -0
  88. simview/static/lib/chroma-js-3.1.2/src/io/hsl/hsl2rgb.js +35 -0
  89. simview/static/lib/chroma-js-3.1.2/src/io/hsl/index.js +27 -0
  90. simview/static/lib/chroma-js-3.1.2/src/io/hsl/rgb2hsl.js +45 -0
  91. simview/static/lib/chroma-js-3.1.2/src/io/hsv/hsv2rgb.js +47 -0
  92. simview/static/lib/chroma-js-3.1.2/src/io/hsv/index.js +27 -0
  93. simview/static/lib/chroma-js-3.1.2/src/io/hsv/rgb2hsv.js +32 -0
  94. simview/static/lib/chroma-js-3.1.2/src/io/input.js +4 -0
  95. simview/static/lib/chroma-js-3.1.2/src/io/lab/index.js +28 -0
  96. simview/static/lib/chroma-js-3.1.2/src/io/lab/lab-constants.js +120 -0
  97. simview/static/lib/chroma-js-3.1.2/src/io/lab/lab2rgb.js +101 -0
  98. simview/static/lib/chroma-js-3.1.2/src/io/lab/rgb2lab.js +67 -0
  99. simview/static/lib/chroma-js-3.1.2/src/io/lch/hcl2rgb.js +9 -0
  100. simview/static/lib/chroma-js-3.1.2/src/io/lch/index.js +35 -0
  101. simview/static/lib/chroma-js-3.1.2/src/io/lch/lab2lch.js +12 -0
  102. simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2lab.js +18 -0
  103. simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2rgb.js +13 -0
  104. simview/static/lib/chroma-js-3.1.2/src/io/lch/rgb2lch.js +12 -0
  105. simview/static/lib/chroma-js-3.1.2/src/io/named/index.js +30 -0
  106. simview/static/lib/chroma-js-3.1.2/src/io/num/index.js +32 -0
  107. simview/static/lib/chroma-js-3.1.2/src/io/num/num2rgb.js +13 -0
  108. simview/static/lib/chroma-js-3.1.2/src/io/num/rgb2num.js +8 -0
  109. simview/static/lib/chroma-js-3.1.2/src/io/oklab/index.js +27 -0
  110. simview/static/lib/chroma-js-3.1.2/src/io/oklab/oklab2rgb.js +34 -0
  111. simview/static/lib/chroma-js-3.1.2/src/io/oklab/rgb2oklab.js +37 -0
  112. simview/static/lib/chroma-js-3.1.2/src/io/oklch/index.js +27 -0
  113. simview/static/lib/chroma-js-3.1.2/src/io/oklch/oklch2rgb.js +13 -0
  114. simview/static/lib/chroma-js-3.1.2/src/io/oklch/rgb2oklch.js +12 -0
  115. simview/static/lib/chroma-js-3.1.2/src/io/rgb/index.js +44 -0
  116. simview/static/lib/chroma-js-3.1.2/src/io/temp/index.js +22 -0
  117. simview/static/lib/chroma-js-3.1.2/src/io/temp/rgb2temperature.js +30 -0
  118. simview/static/lib/chroma-js-3.1.2/src/io/temp/temperature2rgb.js +39 -0
  119. simview/static/lib/chroma-js-3.1.2/src/ops/alpha.js +13 -0
  120. simview/static/lib/chroma-js-3.1.2/src/ops/clipped.js +5 -0
  121. simview/static/lib/chroma-js-3.1.2/src/ops/darken.js +17 -0
  122. simview/static/lib/chroma-js-3.1.2/src/ops/get.js +13 -0
  123. simview/static/lib/chroma-js-3.1.2/src/ops/luminance.js +54 -0
  124. simview/static/lib/chroma-js-3.1.2/src/ops/mix.js +10 -0
  125. simview/static/lib/chroma-js-3.1.2/src/ops/premultiply.js +12 -0
  126. simview/static/lib/chroma-js-3.1.2/src/ops/saturate.js +15 -0
  127. simview/static/lib/chroma-js-3.1.2/src/ops/set.js +43 -0
  128. simview/static/lib/chroma-js-3.1.2/src/ops/shade.js +11 -0
  129. simview/static/lib/chroma-js-3.1.2/src/utils/analyze.js +191 -0
  130. simview/static/lib/chroma-js-3.1.2/src/utils/clip_rgb.js +15 -0
  131. simview/static/lib/chroma-js-3.1.2/src/utils/contrast.js +12 -0
  132. simview/static/lib/chroma-js-3.1.2/src/utils/contrastAPCA.js +68 -0
  133. simview/static/lib/chroma-js-3.1.2/src/utils/delta-e.js +62 -0
  134. simview/static/lib/chroma-js-3.1.2/src/utils/distance.js +17 -0
  135. simview/static/lib/chroma-js-3.1.2/src/utils/index.js +27 -0
  136. simview/static/lib/chroma-js-3.1.2/src/utils/last.js +8 -0
  137. simview/static/lib/chroma-js-3.1.2/src/utils/limit.js +5 -0
  138. simview/static/lib/chroma-js-3.1.2/src/utils/multiply-matrices.js +36 -0
  139. simview/static/lib/chroma-js-3.1.2/src/utils/scales.js +15 -0
  140. simview/static/lib/chroma-js-3.1.2/src/utils/type.js +18 -0
  141. simview/static/lib/chroma-js-3.1.2/src/utils/unpack.js +17 -0
  142. simview/static/lib/chroma-js-3.1.2/src/utils/valid.js +11 -0
  143. simview/static/lib/chroma-js-3.1.2/src/version.js +2 -0
  144. simview/static/lib/download.js +132 -0
  145. simview/static/lib/js-colormaps.js +19335 -0
  146. simview/static/lib/tar.js +334 -0
  147. simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +1556 -0
  148. simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +8 -0
  149. simview/static/lib/three-0.174.0/three.core.js +48830 -0
  150. simview/static/lib/three-0.174.0/three.module.js +17313 -0
  151. simview/static/lib/uPlot.esm.js +6140 -0
  152. simview/static/lib/uPlot.min.css +2 -0
  153. simview/static/textures/contacts/red-cross0.png +0 -0
  154. simview/static/textures/points/ball0.png +0 -0
  155. simview/static/textures/points/ball1.png +0 -0
  156. simview/templates/index.html +81 -0
  157. simview/utils.py +41 -0
  158. simview-3.2.dist-info/METADATA +552 -0
  159. simview-3.2.dist-info/RECORD +163 -0
  160. simview-3.2.dist-info/WHEEL +5 -0
  161. simview-3.2.dist-info/entry_points.txt +2 -0
  162. simview-3.2.dist-info/licenses/LICENSE +28 -0
  163. simview-3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,12 @@
1
+ import { unpack, RAD2DEG } from '../../utils/index.js';
2
+ const { sqrt, atan2, round } = Math;
3
+
4
+ const lab2lch = (...args) => {
5
+ const [l, a, b] = unpack(args, 'lab');
6
+ const c = sqrt(a * a + b * b);
7
+ let h = (atan2(b, a) * RAD2DEG + 360) % 360;
8
+ if (round(c * 10000) === 0) h = Number.NaN;
9
+ return [l, c, h];
10
+ };
11
+
12
+ export default lab2lch;
@@ -0,0 +1,18 @@
1
+ import { unpack, DEG2RAD } from '../../utils/index.js';
2
+ const { sin, cos } = Math;
3
+
4
+ const lch2lab = (...args) => {
5
+ /*
6
+ Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
7
+ These formulas were invented by David Dalrymple to obtain maximum contrast without going
8
+ out of gamut if the parameters are in the range 0-1.
9
+
10
+ A saturation multiplier was added by Gregor Aisch
11
+ */
12
+ let [l, c, h] = unpack(args, 'lch');
13
+ if (isNaN(h)) h = 0;
14
+ h = h * DEG2RAD;
15
+ return [l, cos(h) * c, sin(h) * c];
16
+ };
17
+
18
+ export default lch2lab;
@@ -0,0 +1,13 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import lch2lab from './lch2lab.js';
3
+ import lab2rgb from '../lab/lab2rgb.js';
4
+
5
+ const lch2rgb = (...args) => {
6
+ args = unpack(args, 'lch');
7
+ const [l, c, h] = args;
8
+ const [L, a, b_] = lch2lab(l, c, h);
9
+ const [r, g, b] = lab2rgb(L, a, b_);
10
+ return [r, g, b, args.length > 3 ? args[3] : 1];
11
+ };
12
+
13
+ export default lch2rgb;
@@ -0,0 +1,12 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import rgb2lab from '../lab/rgb2lab.js';
3
+ import lab2lch from './lab2lch.js';
4
+
5
+ const rgb2lch = (...args) => {
6
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
7
+ const [l, a, b_] = rgb2lab(r, g, b);
8
+ const [L, c, h] = lab2lch(l, a, b_);
9
+ return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
10
+ };
11
+
12
+ export default rgb2lch;
@@ -0,0 +1,30 @@
1
+ import Color from '../../Color.js';
2
+ import input from '../input.js';
3
+ import { type } from '../../utils/index.js';
4
+
5
+ import w3cx11 from '../../colors/w3cx11.js';
6
+ import hex2rgb from '../hex/hex2rgb.js';
7
+ import rgb2hex from '../hex/rgb2hex.js';
8
+
9
+ Color.prototype.name = function () {
10
+ const hex = rgb2hex(this._rgb, 'rgb');
11
+ for (let n of Object.keys(w3cx11)) {
12
+ if (w3cx11[n] === hex) return n.toLowerCase();
13
+ }
14
+ return hex;
15
+ };
16
+
17
+ input.format.named = (name) => {
18
+ name = name.toLowerCase();
19
+ if (w3cx11[name]) return hex2rgb(w3cx11[name]);
20
+ throw new Error('unknown color name: ' + name);
21
+ };
22
+
23
+ input.autodetect.push({
24
+ p: 5,
25
+ test: (h, ...rest) => {
26
+ if (!rest.length && type(h) === 'string' && w3cx11[h.toLowerCase()]) {
27
+ return 'named';
28
+ }
29
+ }
30
+ });
@@ -0,0 +1,32 @@
1
+ import chroma from '../../chroma.js';
2
+ import Color from '../../Color.js';
3
+ import input from '../input.js';
4
+ import { type } from '../../utils/index.js';
5
+ import num2rgb from './num2rgb.js';
6
+ import rgb2num from './rgb2num.js';
7
+
8
+ Color.prototype.num = function () {
9
+ return rgb2num(this._rgb);
10
+ };
11
+
12
+ const num = (...args) => new Color(...args, 'num');
13
+
14
+ Object.assign(chroma, { num });
15
+
16
+ input.format.num = num2rgb;
17
+
18
+ input.autodetect.push({
19
+ p: 5,
20
+ test: (...args) => {
21
+ if (
22
+ args.length === 1 &&
23
+ type(args[0]) === 'number' &&
24
+ args[0] >= 0 &&
25
+ args[0] <= 0xffffff
26
+ ) {
27
+ return 'num';
28
+ }
29
+ }
30
+ });
31
+
32
+ export { num };
@@ -0,0 +1,13 @@
1
+ import { type } from '../../utils/index.js';
2
+
3
+ const num2rgb = (num) => {
4
+ if (type(num) == 'number' && num >= 0 && num <= 0xffffff) {
5
+ const r = num >> 16;
6
+ const g = (num >> 8) & 0xff;
7
+ const b = num & 0xff;
8
+ return [r, g, b, 1];
9
+ }
10
+ throw new Error('unknown num color: ' + num);
11
+ };
12
+
13
+ export default num2rgb;
@@ -0,0 +1,8 @@
1
+ import { unpack } from '../../utils/index.js';
2
+
3
+ const rgb2num = (...args) => {
4
+ const [r, g, b] = unpack(args, 'rgb');
5
+ return (r << 16) + (g << 8) + b;
6
+ };
7
+
8
+ export default rgb2num;
@@ -0,0 +1,27 @@
1
+ import { unpack, type } from '../../utils/index.js';
2
+ import chroma from '../../chroma.js';
3
+ import Color from '../../Color.js';
4
+ import input from '../input.js';
5
+ import oklab2rgb from './oklab2rgb.js';
6
+ import rgb2oklab from './rgb2oklab.js';
7
+
8
+ Color.prototype.oklab = function () {
9
+ return rgb2oklab(this._rgb);
10
+ };
11
+
12
+ const oklab = (...args) => new Color(...args, 'oklab');
13
+ Object.assign(chroma, { oklab });
14
+
15
+ input.format.oklab = oklab2rgb;
16
+
17
+ input.autodetect.push({
18
+ p: 2,
19
+ test: (...args) => {
20
+ args = unpack(args, 'oklab');
21
+ if (type(args) === 'array' && args.length === 3) {
22
+ return 'oklab';
23
+ }
24
+ }
25
+ });
26
+
27
+ export { oklab };
@@ -0,0 +1,34 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import multiplyMatrices from '../../utils/multiply-matrices.js';
3
+ import { xyz2rgb } from '../lab/lab2rgb.js';
4
+
5
+ const oklab2rgb = (...args) => {
6
+ args = unpack(args, 'lab');
7
+ const [L, a, b, ...rest] = args;
8
+ const [X, Y, Z] = OKLab_to_XYZ([L, a, b]);
9
+ const [r, g, b_] = xyz2rgb(X, Y, Z);
10
+ return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
11
+ };
12
+
13
+ // from https://www.w3.org/TR/css-color-4/#color-conversion-code
14
+ function OKLab_to_XYZ(OKLab) {
15
+ // Given OKLab, convert to XYZ relative to D65
16
+ var LMStoXYZ = [
17
+ [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
18
+ [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
19
+ [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
20
+ ];
21
+ var OKLabtoLMS = [
22
+ [1.0, 0.3963377773761749, 0.2158037573099136],
23
+ [1.0, -0.1055613458156586, -0.0638541728258133],
24
+ [1.0, -0.0894841775298119, -1.2914855480194092]
25
+ ];
26
+
27
+ var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
28
+ return multiplyMatrices(
29
+ LMStoXYZ,
30
+ LMSnl.map((c) => c ** 3)
31
+ );
32
+ }
33
+
34
+ export default oklab2rgb;
@@ -0,0 +1,37 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import multiplyMatrices from '../../utils/multiply-matrices.js';
3
+ import { rgb2xyz } from '../lab/rgb2lab.js';
4
+
5
+ const rgb2oklab = (...args) => {
6
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
7
+ const xyz = rgb2xyz(r, g, b);
8
+ const oklab = XYZ_to_OKLab(xyz);
9
+ return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
10
+ };
11
+
12
+ // from https://www.w3.org/TR/css-color-4/#color-conversion-code
13
+ function XYZ_to_OKLab(XYZ) {
14
+ // Given XYZ relative to D65, convert to OKLab
15
+ const XYZtoLMS = [
16
+ [0.819022437996703, 0.3619062600528904, -0.1288737815209879],
17
+ [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
18
+ [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
19
+ ];
20
+ const LMStoOKLab = [
21
+ [0.210454268309314, 0.7936177747023054, -0.0040720430116193],
22
+ [1.9779985324311684, -2.4285922420485799, 0.450593709617411],
23
+ [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
24
+ ];
25
+
26
+ const LMS = multiplyMatrices(XYZtoLMS, XYZ);
27
+ // JavaScript Math.cbrt returns a sign-matched cube root
28
+ // beware if porting to other languages
29
+ // especially if tempted to use a general power function
30
+ return multiplyMatrices(
31
+ LMStoOKLab,
32
+ LMS.map((c) => Math.cbrt(c))
33
+ );
34
+ // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
35
+ }
36
+
37
+ export default rgb2oklab;
@@ -0,0 +1,27 @@
1
+ import { unpack, type } from '../../utils/index.js';
2
+ import chroma from '../../chroma.js';
3
+ import Color from '../../Color.js';
4
+ import input from '../input.js';
5
+ import oklch2rgb from './oklch2rgb.js';
6
+ import rgb2oklch from './rgb2oklch.js';
7
+
8
+ Color.prototype.oklch = function () {
9
+ return rgb2oklch(this._rgb);
10
+ };
11
+
12
+ const oklch = (...args) => new Color(...args, 'oklch');
13
+ Object.assign(chroma, { oklch });
14
+
15
+ input.format.oklch = oklch2rgb;
16
+
17
+ input.autodetect.push({
18
+ p: 2,
19
+ test: (...args) => {
20
+ args = unpack(args, 'oklch');
21
+ if (type(args) === 'array' && args.length === 3) {
22
+ return 'oklch';
23
+ }
24
+ }
25
+ });
26
+
27
+ export { oklch };
@@ -0,0 +1,13 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import lch2lab from '../lch/lch2lab.js';
3
+ import oklab2rgb from '../oklab/oklab2rgb.js';
4
+
5
+ const oklch2rgb = (...args) => {
6
+ args = unpack(args, 'lch');
7
+ const [l, c, h, ...rest] = args;
8
+ const [L, a, b_] = lch2lab(l, c, h);
9
+ const [r, g, b] = oklab2rgb(L, a, b_);
10
+ return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
11
+ };
12
+
13
+ export default oklch2rgb;
@@ -0,0 +1,12 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ import rgb2oklab from '../oklab/rgb2oklab.js';
3
+ import lab2lch from '../lch/lab2lch.js';
4
+
5
+ const rgb2oklch = (...args) => {
6
+ const [r, g, b, ...rest] = unpack(args, 'rgb');
7
+ const [l, a, b_] = rgb2oklab(r, g, b);
8
+ const [L, c, h] = lab2lch(l, a, b_);
9
+ return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
10
+ };
11
+
12
+ export default rgb2oklch;
@@ -0,0 +1,44 @@
1
+ import chroma from '../../chroma.js';
2
+ import Color from '../../Color.js';
3
+ import input from '../input.js';
4
+ import { unpack, type } from '../../utils/index.js';
5
+ const { round } = Math;
6
+
7
+ Color.prototype.rgb = function (rnd = true) {
8
+ if (rnd === false) return this._rgb.slice(0, 3);
9
+ return this._rgb.slice(0, 3).map(round);
10
+ };
11
+
12
+ Color.prototype.rgba = function (rnd = true) {
13
+ return this._rgb.slice(0, 4).map((v, i) => {
14
+ return i < 3 ? (rnd === false ? v : round(v)) : v;
15
+ });
16
+ };
17
+
18
+ const rgb = (...args) => new Color(...args, 'rgb');
19
+ Object.assign(chroma, { rgb });
20
+
21
+ input.format.rgb = (...args) => {
22
+ const rgba = unpack(args, 'rgba');
23
+ if (rgba[3] === undefined) rgba[3] = 1;
24
+ return rgba;
25
+ };
26
+
27
+ input.autodetect.push({
28
+ p: 3,
29
+ test: (...args) => {
30
+ args = unpack(args, 'rgba');
31
+ if (
32
+ type(args) === 'array' &&
33
+ (args.length === 3 ||
34
+ (args.length === 4 &&
35
+ type(args[3]) == 'number' &&
36
+ args[3] >= 0 &&
37
+ args[3] <= 1))
38
+ ) {
39
+ return 'rgb';
40
+ }
41
+ }
42
+ });
43
+
44
+ export { rgb };
@@ -0,0 +1,22 @@
1
+ import chroma from '../../chroma.js';
2
+ import Color from '../../Color.js';
3
+ import input from '../input.js';
4
+ import temperature2rgb from './temperature2rgb.js';
5
+ import rgb2temperature from './rgb2temperature.js';
6
+
7
+ Color.prototype.temp =
8
+ Color.prototype.kelvin =
9
+ Color.prototype.temperature =
10
+ function () {
11
+ return rgb2temperature(this._rgb);
12
+ };
13
+
14
+ const temp = (...args) => new Color(...args, 'temp');
15
+ Object.assign(chroma, { temp, kelvin: temp, temperature: temp });
16
+
17
+ input.format.temp =
18
+ input.format.kelvin =
19
+ input.format.temperature =
20
+ temperature2rgb;
21
+
22
+ export { temp, temp as kelvin, temp as temperature };
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Based on implementation by Neil Bartlett
3
+ * https://github.com/neilbartlett/color-temperature
4
+ **/
5
+
6
+ import temperature2rgb from './temperature2rgb.js';
7
+ import { unpack } from '../../utils/index.js';
8
+ const { round } = Math;
9
+
10
+ const rgb2temperature = (...args) => {
11
+ const rgb = unpack(args, 'rgb');
12
+ const r = rgb[0],
13
+ b = rgb[2];
14
+ let minTemp = 1000;
15
+ let maxTemp = 40000;
16
+ const eps = 0.4;
17
+ let temp;
18
+ while (maxTemp - minTemp > eps) {
19
+ temp = (maxTemp + minTemp) * 0.5;
20
+ const rgb = temperature2rgb(temp);
21
+ if (rgb[2] / rgb[0] >= b / r) {
22
+ maxTemp = temp;
23
+ } else {
24
+ minTemp = temp;
25
+ }
26
+ }
27
+ return round(temp);
28
+ };
29
+
30
+ export default rgb2temperature;
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Based on implementation by Neil Bartlett
3
+ * https://github.com/neilbartlett/color-temperature
4
+ */
5
+
6
+ const { log } = Math;
7
+
8
+ const temperature2rgb = (kelvin) => {
9
+ const temp = kelvin / 100;
10
+ let r, g, b;
11
+ if (temp < 66) {
12
+ r = 255;
13
+ g =
14
+ temp < 6
15
+ ? 0
16
+ : -155.25485562709179 -
17
+ 0.44596950469579133 * (g = temp - 2) +
18
+ 104.49216199393888 * log(g);
19
+ b =
20
+ temp < 20
21
+ ? 0
22
+ : -254.76935184120902 +
23
+ 0.8274096064007395 * (b = temp - 10) +
24
+ 115.67994401066147 * log(b);
25
+ } else {
26
+ r =
27
+ 351.97690566805693 +
28
+ 0.114206453784165 * (r = temp - 55) -
29
+ 40.25366309332127 * log(r);
30
+ g =
31
+ 325.4494125711974 +
32
+ 0.07943456536662342 * (g = temp - 50) -
33
+ 28.0852963507957 * log(g);
34
+ b = 255;
35
+ }
36
+ return [r, g, b, 1];
37
+ };
38
+
39
+ export default temperature2rgb;
@@ -0,0 +1,13 @@
1
+ import Color from '../Color.js';
2
+ import { type } from '../utils/index.js';
3
+
4
+ Color.prototype.alpha = function (a, mutate = false) {
5
+ if (a !== undefined && type(a) === 'number') {
6
+ if (mutate) {
7
+ this._rgb[3] = a;
8
+ return this;
9
+ }
10
+ return new Color([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');
11
+ }
12
+ return this._rgb[3];
13
+ };
@@ -0,0 +1,5 @@
1
+ import Color from '../Color.js';
2
+
3
+ Color.prototype.clipped = function () {
4
+ return this._rgb._clipped || false;
5
+ };
@@ -0,0 +1,17 @@
1
+ import '../io/lab/index.js';
2
+ import Color from '../Color.js';
3
+ import LAB_CONSTANTS from '../io/lab/lab-constants.js';
4
+
5
+ Color.prototype.darken = function (amount = 1) {
6
+ const me = this;
7
+ const lab = me.lab();
8
+ lab[0] -= LAB_CONSTANTS.Kn * amount;
9
+ return new Color(lab, 'lab').alpha(me.alpha(), true);
10
+ };
11
+
12
+ Color.prototype.brighten = function (amount = 1) {
13
+ return this.darken(-amount);
14
+ };
15
+
16
+ Color.prototype.darker = Color.prototype.darken;
17
+ Color.prototype.brighter = Color.prototype.brighten;
@@ -0,0 +1,13 @@
1
+ import Color from '../Color.js';
2
+
3
+ Color.prototype.get = function (mc) {
4
+ const [mode, channel] = mc.split('.');
5
+ const src = this[mode]();
6
+ if (channel) {
7
+ const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
8
+ if (i > -1) return src[i];
9
+ throw new Error(`unknown channel ${channel} in mode ${mode}`);
10
+ } else {
11
+ return src;
12
+ }
13
+ };
@@ -0,0 +1,54 @@
1
+ import Color from '../Color.js';
2
+ import { type } from '../utils/index.js';
3
+ const { pow } = Math;
4
+
5
+ const EPS = 1e-7;
6
+ const MAX_ITER = 20;
7
+
8
+ Color.prototype.luminance = function (lum, mode = 'rgb') {
9
+ if (lum !== undefined && type(lum) === 'number') {
10
+ if (lum === 0) {
11
+ // return pure black
12
+ return new Color([0, 0, 0, this._rgb[3]], 'rgb');
13
+ }
14
+ if (lum === 1) {
15
+ // return pure white
16
+ return new Color([255, 255, 255, this._rgb[3]], 'rgb');
17
+ }
18
+ // compute new color using...
19
+ let cur_lum = this.luminance();
20
+ let max_iter = MAX_ITER;
21
+
22
+ const test = (low, high) => {
23
+ const mid = low.interpolate(high, 0.5, mode);
24
+ const lm = mid.luminance();
25
+ if (Math.abs(lum - lm) < EPS || !max_iter--) {
26
+ // close enough
27
+ return mid;
28
+ }
29
+ return lm > lum ? test(low, mid) : test(mid, high);
30
+ };
31
+
32
+ const rgb = (
33
+ cur_lum > lum
34
+ ? test(new Color([0, 0, 0]), this)
35
+ : test(this, new Color([255, 255, 255]))
36
+ ).rgb();
37
+ return new Color([...rgb, this._rgb[3]]);
38
+ }
39
+ return rgb2luminance(...this._rgb.slice(0, 3));
40
+ };
41
+
42
+ const rgb2luminance = (r, g, b) => {
43
+ // relative luminance
44
+ // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
45
+ r = luminance_x(r);
46
+ g = luminance_x(g);
47
+ b = luminance_x(b);
48
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
49
+ };
50
+
51
+ const luminance_x = (x) => {
52
+ x /= 255;
53
+ return x <= 0.03928 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);
54
+ };
@@ -0,0 +1,10 @@
1
+ import Color from '../Color.js';
2
+ import mix from '../generator/mix.js';
3
+
4
+ Color.prototype.mix = Color.prototype.interpolate = function (
5
+ col2,
6
+ f = 0.5,
7
+ ...rest
8
+ ) {
9
+ return mix(this, col2, f, ...rest);
10
+ };
@@ -0,0 +1,12 @@
1
+ import Color from '../Color.js';
2
+
3
+ Color.prototype.premultiply = function (mutate = false) {
4
+ const rgb = this._rgb;
5
+ const a = rgb[3];
6
+ if (mutate) {
7
+ this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];
8
+ return this;
9
+ } else {
10
+ return new Color([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');
11
+ }
12
+ };
@@ -0,0 +1,15 @@
1
+ import '../io/lch/index.js';
2
+ import Color from '../Color.js';
3
+ import LAB_CONSTANTS from '../io/lab/lab-constants.js';
4
+
5
+ Color.prototype.saturate = function (amount = 1) {
6
+ const me = this;
7
+ const lch = me.lch();
8
+ lch[1] += LAB_CONSTANTS.Kn * amount;
9
+ if (lch[1] < 0) lch[1] = 0;
10
+ return new Color(lch, 'lch').alpha(me.alpha(), true);
11
+ };
12
+
13
+ Color.prototype.desaturate = function (amount = 1) {
14
+ return this.saturate(-amount);
15
+ };
@@ -0,0 +1,43 @@
1
+ import Color from '../Color.js';
2
+ import { type } from '../utils/index.js';
3
+
4
+ Color.prototype.set = function (mc, value, mutate = false) {
5
+ const [mode, channel] = mc.split('.');
6
+ const src = this[mode]();
7
+ if (channel) {
8
+ const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
9
+ if (i > -1) {
10
+ if (type(value) == 'string') {
11
+ switch (value.charAt(0)) {
12
+ case '+':
13
+ src[i] += +value;
14
+ break;
15
+ case '-':
16
+ src[i] += +value;
17
+ break;
18
+ case '*':
19
+ src[i] *= +value.substr(1);
20
+ break;
21
+ case '/':
22
+ src[i] /= +value.substr(1);
23
+ break;
24
+ default:
25
+ src[i] = +value;
26
+ }
27
+ } else if (type(value) === 'number') {
28
+ src[i] = value;
29
+ } else {
30
+ throw new Error(`unsupported value for Color.set`);
31
+ }
32
+ const out = new Color(src, mode);
33
+ if (mutate) {
34
+ this._rgb = out._rgb;
35
+ return this;
36
+ }
37
+ return out;
38
+ }
39
+ throw new Error(`unknown channel ${channel} in mode ${mode}`);
40
+ } else {
41
+ return src;
42
+ }
43
+ };
@@ -0,0 +1,11 @@
1
+ import '../io/lab/index.js';
2
+ import Color from '../Color.js';
3
+ import mix from '../generator/mix.js';
4
+
5
+ Color.prototype.tint = function (f = 0.5, ...rest) {
6
+ return mix(this, 'white', f, ...rest);
7
+ };
8
+
9
+ Color.prototype.shade = function (f = 0.5, ...rest) {
10
+ return mix(this, 'black', f, ...rest);
11
+ };