@decidables/detectable-elements 0.4.4 → 0.5.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.
- package/CHANGELOG.md +23 -0
- package/README.md +1 -1
- package/lib/detectableElements.esm.js +2666 -246
- package/lib/detectableElements.esm.js.map +1 -1
- package/lib/detectableElements.esm.min.js +223 -228
- package/lib/detectableElements.esm.min.js.map +1 -1
- package/lib/detectableElements.umd.js +2666 -246
- package/lib/detectableElements.umd.js.map +1 -1
- package/lib/detectableElements.umd.min.js +171 -176
- package/lib/detectableElements.umd.min.js.map +1 -1
- package/package.json +8 -5
- package/src/components/detectable-control.js +1 -1
- package/src/components/detectable-response.js +1 -1
- package/src/components/detectable-table.js +1 -1
- package/src/components/rdk-task.js +1 -1
- package/src/components/roc-space.js +36 -19
- package/src/components/sdt-model.js +8 -5
- package/src/components/sdt-parameters.js +1 -1
- package/src/examples/sdt-example.js +1 -1
|
@@ -2376,13 +2376,13 @@ function define (constructor, factory, prototype) {
|
|
|
2376
2376
|
constructor.prototype = factory.prototype = prototype;
|
|
2377
2377
|
prototype.constructor = constructor;
|
|
2378
2378
|
}
|
|
2379
|
-
function extend(parent, definition) {
|
|
2379
|
+
function extend$1(parent, definition) {
|
|
2380
2380
|
var prototype = Object.create(parent.prototype);
|
|
2381
2381
|
for (var key in definition) prototype[key] = definition[key];
|
|
2382
2382
|
return prototype;
|
|
2383
2383
|
}
|
|
2384
2384
|
|
|
2385
|
-
function Color() {}
|
|
2385
|
+
function Color$1() {}
|
|
2386
2386
|
var darker = 0.7;
|
|
2387
2387
|
var brighter = 1 / darker;
|
|
2388
2388
|
var reI = "\\s*([+-]?\\d+)\\s*",
|
|
@@ -2545,7 +2545,7 @@ var named = {
|
|
|
2545
2545
|
yellow: 0xffff00,
|
|
2546
2546
|
yellowgreen: 0x9acd32
|
|
2547
2547
|
};
|
|
2548
|
-
define(Color, color, {
|
|
2548
|
+
define(Color$1, color, {
|
|
2549
2549
|
copy(channels) {
|
|
2550
2550
|
return Object.assign(new this.constructor(), this, channels);
|
|
2551
2551
|
},
|
|
@@ -2597,7 +2597,7 @@ function rgba(r, g, b, a) {
|
|
|
2597
2597
|
return new Rgb(r, g, b, a);
|
|
2598
2598
|
}
|
|
2599
2599
|
function rgbConvert(o) {
|
|
2600
|
-
if (!(o instanceof Color)) o = color(o);
|
|
2600
|
+
if (!(o instanceof Color$1)) o = color(o);
|
|
2601
2601
|
if (!o) return new Rgb();
|
|
2602
2602
|
o = o.rgb();
|
|
2603
2603
|
return new Rgb(o.r, o.g, o.b, o.opacity);
|
|
@@ -2611,7 +2611,7 @@ function Rgb(r, g, b, opacity) {
|
|
|
2611
2611
|
this.b = +b;
|
|
2612
2612
|
this.opacity = +opacity;
|
|
2613
2613
|
}
|
|
2614
|
-
define(Rgb, rgb, extend(Color, {
|
|
2614
|
+
define(Rgb, rgb, extend$1(Color$1, {
|
|
2615
2615
|
brighter(k) {
|
|
2616
2616
|
k = k == null ? brighter : Math.pow(brighter, k);
|
|
2617
2617
|
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
|
|
@@ -2662,7 +2662,7 @@ function hsla(h, s, l, a) {
|
|
|
2662
2662
|
}
|
|
2663
2663
|
function hslConvert(o) {
|
|
2664
2664
|
if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
|
|
2665
|
-
if (!(o instanceof Color)) o = color(o);
|
|
2665
|
+
if (!(o instanceof Color$1)) o = color(o);
|
|
2666
2666
|
if (!o) return new Hsl();
|
|
2667
2667
|
if (o instanceof Hsl) return o;
|
|
2668
2668
|
o = o.rgb();
|
|
@@ -2692,7 +2692,7 @@ function Hsl(h, s, l, opacity) {
|
|
|
2692
2692
|
this.l = +l;
|
|
2693
2693
|
this.opacity = +opacity;
|
|
2694
2694
|
}
|
|
2695
|
-
define(Hsl, hsl, extend(Color, {
|
|
2695
|
+
define(Hsl, hsl, extend$1(Color$1, {
|
|
2696
2696
|
brighter(k) {
|
|
2697
2697
|
k = k == null ? brighter : Math.pow(brighter, k);
|
|
2698
2698
|
return new Hsl(this.h, this.s, this.l * k, this.opacity);
|
|
@@ -4793,8 +4793,8 @@ function clipRejoin (segments, compareIntersection, startInside, interpolate, st
|
|
|
4793
4793
|
});
|
|
4794
4794
|
if (!subject.length) return;
|
|
4795
4795
|
clip.sort(compareIntersection);
|
|
4796
|
-
link(subject);
|
|
4797
|
-
link(clip);
|
|
4796
|
+
link$1(subject);
|
|
4797
|
+
link$1(clip);
|
|
4798
4798
|
for (i = 0, n = clip.length; i < n; ++i) {
|
|
4799
4799
|
clip[i].e = startInside = !startInside;
|
|
4800
4800
|
}
|
|
@@ -4833,7 +4833,7 @@ function clipRejoin (segments, compareIntersection, startInside, interpolate, st
|
|
|
4833
4833
|
stream.lineEnd();
|
|
4834
4834
|
}
|
|
4835
4835
|
}
|
|
4836
|
-
function link(array) {
|
|
4836
|
+
function link$1(array) {
|
|
4837
4837
|
if (!(n = array.length)) return;
|
|
4838
4838
|
var n,
|
|
4839
4839
|
i = 0,
|
|
@@ -6124,54 +6124,12 @@ class DecidablesElement extends i {
|
|
|
6124
6124
|
const ambientS = rotate ? `${-ambientM.y}px ${ambientM.y / 2}px ${ambientM.b}px ${ambientM.s}px` : `${ambientM.y / 2}px ${ambientM.y}px ${ambientM.b}px ${ambientM.s}px`;
|
|
6125
6125
|
return `${umbraS} ${umbraC}, ${penumbraS} ${penumbraC}, ${ambientS} ${ambientC}`;
|
|
6126
6126
|
}
|
|
6127
|
-
static get svgDefs() {
|
|
6128
|
-
const shadows = DecidablesElement.shadows; /* eslint-disable-line prefer-destructuring */
|
|
6129
|
-
|
|
6130
|
-
const filters = shadows.elevations.map(z => {
|
|
6131
|
-
return `
|
|
6132
|
-
<filter id=${`shadow-${z}`} filterUnits="userSpaceOnUse" x="-100%" y="-100%" width="200%" height="200%">
|
|
6133
|
-
<feComponentTransfer in="SourceAlpha" result="solid">
|
|
6134
|
-
<feFuncA type="table" tableValues="0 1 1"/>
|
|
6135
|
-
</feComponentTransfer>
|
|
6136
|
-
<feOffset in="solid" result="offU" dx=${shadows.mapUmbra[z].y / 2} dy=${shadows.mapUmbra[z].y} />
|
|
6137
|
-
<feOffset in="solid" result="offP" dx=${shadows.mapPenumbra[z].y / 2} dy=${shadows.mapPenumbra[z].y} />
|
|
6138
|
-
<feOffset in="solid" result="offA" dx=${shadows.mapAmbient[z].y / 2} dy=${shadows.mapAmbient[z].y} />
|
|
6139
|
-
${shadows.mapUmbra[z].s === 0 ? '' : `<feMorphology in="offU" result="spreadU" operator=${shadows.mapUmbra[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapUmbra[z].s)} />`}
|
|
6140
|
-
${shadows.mapPenumbra[z].s === 0 ? '' : `<feMorphology in="offP" result="spreadP" operator=${shadows.mapPenumbra[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapPenumbra[z].s)} />`}
|
|
6141
|
-
${shadows.mapAmbient[z].s === 0 ? '' : `<feMorphology in="offA" result="spreadA" operator=${shadows.mapAmbient[z].s > 0 ? 'dilate' : 'erode'} radius=${Math.abs(shadows.mapAmbient[z].s)} />`}
|
|
6142
|
-
<feGaussianBlur in=${shadows.mapUmbra[z].s === 0 ? 'offU' : 'spreadU'} result="blurU" stdDeviation=${shadows.mapUmbra[z].b / 2} />
|
|
6143
|
-
<feGaussianBlur in=${shadows.mapPenumbra[z].s === 0 ? 'offP' : 'spreadP'} result="blurP" stdDeviation=${shadows.mapPenumbra[z].b / 2} />
|
|
6144
|
-
<feGaussianBlur in=${shadows.mapAmbient[z].s === 0 ? 'offA' : 'spreadA'} result="blurA" stdDeviation=${shadows.mapAmbient[z].b / 2} />
|
|
6145
|
-
<feFlood in="SourceGraphic" result="opU" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityUmbra + shadows.opacityBoost} />
|
|
6146
|
-
<feFlood in="SourceGraphic" result="opP" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityPenumbra + shadows.opacityBoost} />
|
|
6147
|
-
<feFlood in="SourceGraphic" result="opA" flood-color=${shadows.baselineColor} flood-opacity=${shadows.opacityAmbient + shadows.opacityBoost} />
|
|
6148
|
-
<feComposite in="opU" in2="blurU" result="shU" operator="in" />
|
|
6149
|
-
<feComposite in="opP" in2="blurP" result="shP" operator="in" />
|
|
6150
|
-
<feComposite in="opA" in2="blurA" result="shA" operator="in" />
|
|
6151
|
-
<feMorphology in="solid" result="smaller" operator="erode" radius="1" />
|
|
6152
|
-
<feComposite in="shU" in2="smaller" result="finalU" operator="out" />
|
|
6153
|
-
<feComposite in="shP" in2="smaller" result="finalP" operator="out" />
|
|
6154
|
-
<feComposite in="shA" in2="smaller" result="finalA" operator="out" />
|
|
6155
|
-
<feMerge>
|
|
6156
|
-
<feMergeNode in="finalU" />
|
|
6157
|
-
<feMergeNode in="finalP" />
|
|
6158
|
-
<feMergeNode in="finalA" />
|
|
6159
|
-
<feMergeNode in="SourceGraphic" />
|
|
6160
|
-
</feMerge>
|
|
6161
|
-
</filter>`;
|
|
6162
|
-
});
|
|
6163
|
-
return `
|
|
6164
|
-
<defs>
|
|
6165
|
-
${filters}
|
|
6166
|
-
</defs>
|
|
6167
|
-
`;
|
|
6168
|
-
}
|
|
6169
6127
|
static get svgFilters() {
|
|
6170
6128
|
const shadows = DecidablesElement.shadows; /* eslint-disable-line prefer-destructuring */
|
|
6171
6129
|
|
|
6172
6130
|
const filters = shadows.elevations.map(z => {
|
|
6173
6131
|
return b`
|
|
6174
|
-
<filter id=${`shadow-${z}`} x="-
|
|
6132
|
+
<filter id=${`shadow-${z}`} filterUnits="userSpaceOnUse" x="-100%" y="-100%" width="200%" height="200%">
|
|
6175
6133
|
<feComponentTransfer in="SourceAlpha" result="solid">
|
|
6176
6134
|
<feFuncA type="table" tableValues="0 1 1"/>
|
|
6177
6135
|
</feComponentTransfer>
|
|
@@ -6203,11 +6161,9 @@ class DecidablesElement extends i {
|
|
|
6203
6161
|
</filter>`;
|
|
6204
6162
|
});
|
|
6205
6163
|
return b`
|
|
6206
|
-
<
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
</defs>
|
|
6210
|
-
</svg>
|
|
6164
|
+
<defs class="filtersUser">
|
|
6165
|
+
${filters}
|
|
6166
|
+
</defs>
|
|
6211
6167
|
`;
|
|
6212
6168
|
}
|
|
6213
6169
|
static get styles() {
|
|
@@ -13616,195 +13572,2649 @@ class RDKTask extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
13616
13572
|
}
|
|
13617
13573
|
customElements.define('rdk-task', RDKTask);
|
|
13618
13574
|
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13575
|
+
function ownKeys(object, enumerableOnly) {
|
|
13576
|
+
var keys = Object.keys(object);
|
|
13577
|
+
if (Object.getOwnPropertySymbols) {
|
|
13578
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
13579
|
+
if (enumerableOnly) {
|
|
13580
|
+
symbols = symbols.filter(function (sym) {
|
|
13581
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
13582
|
+
});
|
|
13583
|
+
}
|
|
13584
|
+
keys.push.apply(keys, symbols);
|
|
13585
|
+
}
|
|
13586
|
+
return keys;
|
|
13587
|
+
}
|
|
13588
|
+
function _objectSpread2(target) {
|
|
13589
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
13590
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
13591
|
+
if (i % 2) {
|
|
13592
|
+
ownKeys(Object(source), true).forEach(function (key) {
|
|
13593
|
+
_defineProperty(target, key, source[key]);
|
|
13594
|
+
});
|
|
13595
|
+
} else if (Object.getOwnPropertyDescriptors) {
|
|
13596
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
13597
|
+
} else {
|
|
13598
|
+
ownKeys(Object(source)).forEach(function (key) {
|
|
13599
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
13600
|
+
});
|
|
13601
|
+
}
|
|
13602
|
+
}
|
|
13603
|
+
return target;
|
|
13604
|
+
}
|
|
13605
|
+
function _typeof(obj) {
|
|
13606
|
+
"@babel/helpers - typeof";
|
|
13632
13607
|
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
13636
|
-
|
|
13637
|
-
|
|
13638
|
-
|
|
13639
|
-
|
|
13640
|
-
attribute: 'contour',
|
|
13641
|
-
type: String,
|
|
13642
|
-
reflect: true
|
|
13643
|
-
},
|
|
13644
|
-
point: {
|
|
13645
|
-
attribute: 'point',
|
|
13646
|
-
type: String,
|
|
13647
|
-
reflect: true
|
|
13648
|
-
},
|
|
13649
|
-
isoD: {
|
|
13650
|
-
attribute: 'iso-d',
|
|
13651
|
-
type: String,
|
|
13652
|
-
reflect: true
|
|
13653
|
-
},
|
|
13654
|
-
isoC: {
|
|
13655
|
-
attribute: 'iso-c',
|
|
13656
|
-
type: String,
|
|
13657
|
-
reflect: true
|
|
13658
|
-
},
|
|
13659
|
-
zRoc: {
|
|
13660
|
-
attribute: 'z-roc',
|
|
13661
|
-
type: Boolean,
|
|
13662
|
-
reflect: true
|
|
13663
|
-
},
|
|
13664
|
-
far: {
|
|
13665
|
-
attribute: 'far',
|
|
13666
|
-
type: Number,
|
|
13667
|
-
reflect: true
|
|
13668
|
-
},
|
|
13669
|
-
hr: {
|
|
13670
|
-
attribute: 'hr',
|
|
13671
|
-
type: Number,
|
|
13672
|
-
reflect: true
|
|
13673
|
-
},
|
|
13674
|
-
d: {
|
|
13675
|
-
attribute: false,
|
|
13676
|
-
type: Number,
|
|
13677
|
-
reflect: false
|
|
13678
|
-
},
|
|
13679
|
-
c: {
|
|
13680
|
-
attribute: false,
|
|
13681
|
-
type: Number,
|
|
13682
|
-
reflect: false
|
|
13683
|
-
},
|
|
13684
|
-
s: {
|
|
13685
|
-
attribute: false,
|
|
13686
|
-
type: Number,
|
|
13687
|
-
reflect: false
|
|
13688
|
-
}
|
|
13608
|
+
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
13609
|
+
_typeof = function (obj) {
|
|
13610
|
+
return typeof obj;
|
|
13611
|
+
};
|
|
13612
|
+
} else {
|
|
13613
|
+
_typeof = function (obj) {
|
|
13614
|
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
13689
13615
|
};
|
|
13690
13616
|
}
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
this.isoDs = ['all', 'first', 'rest', 'none'];
|
|
13701
|
-
this.isoD = 'first';
|
|
13702
|
-
this.isoCs = ['all', 'first', 'rest', 'none'];
|
|
13703
|
-
this.isoC = 'first';
|
|
13704
|
-
this.zRoc = false;
|
|
13705
|
-
this.far = 0.25;
|
|
13706
|
-
this.hr = 0.75;
|
|
13707
|
-
this.s = SDTMath.s.DEFAULT;
|
|
13708
|
-
this.label = '';
|
|
13709
|
-
this.locations = [{
|
|
13710
|
-
name: 'default',
|
|
13711
|
-
far: this.far,
|
|
13712
|
-
hr: this.hr,
|
|
13713
|
-
s: this.s,
|
|
13714
|
-
label: ''
|
|
13715
|
-
}];
|
|
13716
|
-
this.pointArray = [];
|
|
13717
|
-
this.isoDArray = [];
|
|
13718
|
-
this.isoCArray = [];
|
|
13719
|
-
this.alignState();
|
|
13720
|
-
}
|
|
13721
|
-
alignState() {
|
|
13722
|
-
this.locations[0].hr = this.hr;
|
|
13723
|
-
this.locations[0].far = this.far;
|
|
13724
|
-
this.locations[0].s = this.s;
|
|
13725
|
-
this.locations[0].label = this.label;
|
|
13726
|
-
this.d = SDTMath.hrFar2D(this.hr, this.far, this.s);
|
|
13727
|
-
this.c = SDTMath.hrFar2C(this.hr, this.far, this.s);
|
|
13728
|
-
this.pointArray = [];
|
|
13729
|
-
this.isoDArray = [];
|
|
13730
|
-
this.isoCArray = [];
|
|
13731
|
-
this.locations.forEach((item, index) => {
|
|
13732
|
-
item.d = SDTMath.hrFar2D(item.hr, item.far, item.s);
|
|
13733
|
-
item.c = SDTMath.hrFar2C(item.hr, item.far, item.s);
|
|
13734
|
-
if (index === 0 && (this.point === 'first' || this.point === 'all')) {
|
|
13735
|
-
this.pointArray.push(item);
|
|
13736
|
-
} else if (index > 0 && (this.point === 'rest' || this.point === 'all')) {
|
|
13737
|
-
this.pointArray.push(item);
|
|
13738
|
-
}
|
|
13739
|
-
if (index === 0 && (this.isoD === 'first' || this.isoD === 'all')) {
|
|
13740
|
-
this.isoDArray.push(item);
|
|
13741
|
-
} else if (index > 0 && (this.isoD === 'rest' || this.isoD === 'all')) {
|
|
13742
|
-
this.isoDArray.push(item);
|
|
13743
|
-
}
|
|
13744
|
-
if (index === 0 && (this.isoC === 'first' || this.isoC === 'all')) {
|
|
13745
|
-
this.isoCArray.push(item);
|
|
13746
|
-
} else if (index > 0 && (this.isoC === 'rest' || this.isoC === 'all')) {
|
|
13747
|
-
this.isoCArray.push(item);
|
|
13748
|
-
}
|
|
13617
|
+
return _typeof(obj);
|
|
13618
|
+
}
|
|
13619
|
+
function _defineProperty(obj, key, value) {
|
|
13620
|
+
if (key in obj) {
|
|
13621
|
+
Object.defineProperty(obj, key, {
|
|
13622
|
+
value: value,
|
|
13623
|
+
enumerable: true,
|
|
13624
|
+
configurable: true,
|
|
13625
|
+
writable: true
|
|
13749
13626
|
});
|
|
13627
|
+
} else {
|
|
13628
|
+
obj[key] = value;
|
|
13750
13629
|
}
|
|
13751
|
-
|
|
13752
|
-
|
|
13753
|
-
|
|
13754
|
-
|
|
13755
|
-
|
|
13756
|
-
|
|
13630
|
+
return obj;
|
|
13631
|
+
}
|
|
13632
|
+
function _extends() {
|
|
13633
|
+
_extends = Object.assign || function (target) {
|
|
13634
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
13635
|
+
var source = arguments[i];
|
|
13636
|
+
for (var key in source) {
|
|
13637
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
13638
|
+
target[key] = source[key];
|
|
13639
|
+
}
|
|
13640
|
+
}
|
|
13757
13641
|
}
|
|
13758
|
-
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13642
|
+
return target;
|
|
13643
|
+
};
|
|
13644
|
+
return _extends.apply(this, arguments);
|
|
13645
|
+
}
|
|
13646
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
13647
|
+
if (!o) return;
|
|
13648
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
13649
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
13650
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
13651
|
+
if (n === "Map" || n === "Set") return Array.from(o);
|
|
13652
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
13653
|
+
}
|
|
13654
|
+
function _arrayLikeToArray(arr, len) {
|
|
13655
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
13656
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
13657
|
+
return arr2;
|
|
13658
|
+
}
|
|
13659
|
+
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
13660
|
+
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
13661
|
+
if (!it) {
|
|
13662
|
+
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike) {
|
|
13663
|
+
if (it) o = it;
|
|
13664
|
+
var i = 0;
|
|
13665
|
+
var F = function () {};
|
|
13666
|
+
return {
|
|
13667
|
+
s: F,
|
|
13668
|
+
n: function () {
|
|
13669
|
+
if (i >= o.length) return {
|
|
13670
|
+
done: true
|
|
13671
|
+
};
|
|
13672
|
+
return {
|
|
13673
|
+
done: false,
|
|
13674
|
+
value: o[i++]
|
|
13675
|
+
};
|
|
13676
|
+
},
|
|
13677
|
+
e: function (e) {
|
|
13678
|
+
throw e;
|
|
13679
|
+
},
|
|
13680
|
+
f: F
|
|
13681
|
+
};
|
|
13774
13682
|
}
|
|
13775
|
-
|
|
13683
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
13776
13684
|
}
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13685
|
+
var normalCompletion = true,
|
|
13686
|
+
didErr = false,
|
|
13687
|
+
err;
|
|
13688
|
+
return {
|
|
13689
|
+
s: function () {
|
|
13690
|
+
it = it.call(o);
|
|
13691
|
+
},
|
|
13692
|
+
n: function () {
|
|
13693
|
+
var step = it.next();
|
|
13694
|
+
normalCompletion = step.done;
|
|
13695
|
+
return step;
|
|
13696
|
+
},
|
|
13697
|
+
e: function (e) {
|
|
13698
|
+
didErr = true;
|
|
13699
|
+
err = e;
|
|
13700
|
+
},
|
|
13701
|
+
f: function () {
|
|
13702
|
+
try {
|
|
13703
|
+
if (!normalCompletion && it.return != null) it.return();
|
|
13704
|
+
} finally {
|
|
13705
|
+
if (didErr) throw err;
|
|
13706
|
+
}
|
|
13783
13707
|
}
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
|
|
13708
|
+
};
|
|
13709
|
+
}
|
|
13710
|
+
|
|
13711
|
+
/**
|
|
13712
|
+
* de Casteljau's algorithm for drawing and splitting bezier curves.
|
|
13713
|
+
* Inspired by https://pomax.github.io/bezierinfo/
|
|
13714
|
+
*
|
|
13715
|
+
* @param {Number[][]} points Array of [x,y] points: [start, control1, control2, ..., end]
|
|
13716
|
+
* The original segment to split.
|
|
13717
|
+
* @param {Number} t Where to split the curve (value between [0, 1])
|
|
13718
|
+
* @return {Object} An object { left, right } where left is the segment from 0..t and
|
|
13719
|
+
* right is the segment from t..1.
|
|
13720
|
+
*/
|
|
13721
|
+
function decasteljau(points, t) {
|
|
13722
|
+
var left = [];
|
|
13723
|
+
var right = [];
|
|
13724
|
+
function decasteljauRecurse(points, t) {
|
|
13725
|
+
if (points.length === 1) {
|
|
13726
|
+
left.push(points[0]);
|
|
13727
|
+
right.push(points[0]);
|
|
13795
13728
|
} else {
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13729
|
+
var newPoints = Array(points.length - 1);
|
|
13730
|
+
for (var i = 0; i < newPoints.length; i++) {
|
|
13731
|
+
if (i === 0) {
|
|
13732
|
+
left.push(points[0]);
|
|
13733
|
+
}
|
|
13734
|
+
if (i === newPoints.length - 1) {
|
|
13735
|
+
right.push(points[i + 1]);
|
|
13736
|
+
}
|
|
13737
|
+
newPoints[i] = [(1 - t) * points[i][0] + t * points[i + 1][0], (1 - t) * points[i][1] + t * points[i + 1][1]];
|
|
13738
|
+
}
|
|
13739
|
+
decasteljauRecurse(newPoints, t);
|
|
13800
13740
|
}
|
|
13801
|
-
this.sdt = true;
|
|
13802
|
-
this.requestUpdate();
|
|
13803
13741
|
}
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13742
|
+
if (points.length) {
|
|
13743
|
+
decasteljauRecurse(points, t);
|
|
13744
|
+
}
|
|
13745
|
+
return {
|
|
13746
|
+
left: left,
|
|
13747
|
+
right: right.reverse()
|
|
13748
|
+
};
|
|
13749
|
+
}
|
|
13750
|
+
/**
|
|
13751
|
+
* Convert segments represented as points back into a command object
|
|
13752
|
+
*
|
|
13753
|
+
* @param {Number[][]} points Array of [x,y] points: [start, control1, control2, ..., end]
|
|
13754
|
+
* Represents a segment
|
|
13755
|
+
* @return {Object} A command object representing the segment.
|
|
13756
|
+
*/
|
|
13757
|
+
|
|
13758
|
+
function pointsToCommand(points) {
|
|
13759
|
+
var command = {};
|
|
13760
|
+
if (points.length === 4) {
|
|
13761
|
+
command.x2 = points[2][0];
|
|
13762
|
+
command.y2 = points[2][1];
|
|
13763
|
+
}
|
|
13764
|
+
if (points.length >= 3) {
|
|
13765
|
+
command.x1 = points[1][0];
|
|
13766
|
+
command.y1 = points[1][1];
|
|
13767
|
+
}
|
|
13768
|
+
command.x = points[points.length - 1][0];
|
|
13769
|
+
command.y = points[points.length - 1][1];
|
|
13770
|
+
if (points.length === 4) {
|
|
13771
|
+
// start, control1, control2, end
|
|
13772
|
+
command.type = 'C';
|
|
13773
|
+
} else if (points.length === 3) {
|
|
13774
|
+
// start, control, end
|
|
13775
|
+
command.type = 'Q';
|
|
13776
|
+
} else {
|
|
13777
|
+
// start, end
|
|
13778
|
+
command.type = 'L';
|
|
13779
|
+
}
|
|
13780
|
+
return command;
|
|
13781
|
+
}
|
|
13782
|
+
/**
|
|
13783
|
+
* Runs de Casteljau's algorithm enough times to produce the desired number of segments.
|
|
13784
|
+
*
|
|
13785
|
+
* @param {Number[][]} points Array of [x,y] points for de Casteljau (the initial segment to split)
|
|
13786
|
+
* @param {Number} segmentCount Number of segments to split the original into
|
|
13787
|
+
* @return {Number[][][]} Array of segments
|
|
13788
|
+
*/
|
|
13789
|
+
|
|
13790
|
+
function splitCurveAsPoints(points, segmentCount) {
|
|
13791
|
+
segmentCount = segmentCount || 2;
|
|
13792
|
+
var segments = [];
|
|
13793
|
+
var remainingCurve = points;
|
|
13794
|
+
var tIncrement = 1 / segmentCount; // x-----x-----x-----x
|
|
13795
|
+
// t= 0.33 0.66 1
|
|
13796
|
+
// x-----o-----------x
|
|
13797
|
+
// r= 0.33
|
|
13798
|
+
// x-----o-----x
|
|
13799
|
+
// r= 0.5 (0.33 / (1 - 0.33)) === tIncrement / (1 - (tIncrement * (i - 1))
|
|
13800
|
+
// x-----x-----x-----x----x
|
|
13801
|
+
// t= 0.25 0.5 0.75 1
|
|
13802
|
+
// x-----o----------------x
|
|
13803
|
+
// r= 0.25
|
|
13804
|
+
// x-----o----------x
|
|
13805
|
+
// r= 0.33 (0.25 / (1 - 0.25))
|
|
13806
|
+
// x-----o----x
|
|
13807
|
+
// r= 0.5 (0.25 / (1 - 0.5))
|
|
13808
|
+
|
|
13809
|
+
for (var i = 0; i < segmentCount - 1; i++) {
|
|
13810
|
+
var tRelative = tIncrement / (1 - tIncrement * i);
|
|
13811
|
+
var split = decasteljau(remainingCurve, tRelative);
|
|
13812
|
+
segments.push(split.left);
|
|
13813
|
+
remainingCurve = split.right;
|
|
13814
|
+
} // last segment is just to the end from the last point
|
|
13815
|
+
|
|
13816
|
+
segments.push(remainingCurve);
|
|
13817
|
+
return segments;
|
|
13818
|
+
}
|
|
13819
|
+
/**
|
|
13820
|
+
* Convert command objects to arrays of points, run de Casteljau's algorithm on it
|
|
13821
|
+
* to split into to the desired number of segments.
|
|
13822
|
+
*
|
|
13823
|
+
* @param {Object} commandStart The start command object
|
|
13824
|
+
* @param {Object} commandEnd The end command object
|
|
13825
|
+
* @param {Number} segmentCount The number of segments to create
|
|
13826
|
+
* @return {Object[]} An array of commands representing the segments in sequence
|
|
13827
|
+
*/
|
|
13828
|
+
|
|
13829
|
+
function splitCurve(commandStart, commandEnd, segmentCount) {
|
|
13830
|
+
var points = [[commandStart.x, commandStart.y]];
|
|
13831
|
+
if (commandEnd.x1 != null) {
|
|
13832
|
+
points.push([commandEnd.x1, commandEnd.y1]);
|
|
13833
|
+
}
|
|
13834
|
+
if (commandEnd.x2 != null) {
|
|
13835
|
+
points.push([commandEnd.x2, commandEnd.y2]);
|
|
13836
|
+
}
|
|
13837
|
+
points.push([commandEnd.x, commandEnd.y]);
|
|
13838
|
+
return splitCurveAsPoints(points, segmentCount).map(pointsToCommand);
|
|
13839
|
+
}
|
|
13840
|
+
var commandTokenRegex = /[MLCSTQAHVZmlcstqahv]|-?[\d.e+-]+/g;
|
|
13841
|
+
/**
|
|
13842
|
+
* List of params for each command type in a path `d` attribute
|
|
13843
|
+
*/
|
|
13844
|
+
|
|
13845
|
+
var typeMap = {
|
|
13846
|
+
M: ['x', 'y'],
|
|
13847
|
+
L: ['x', 'y'],
|
|
13848
|
+
H: ['x'],
|
|
13849
|
+
V: ['y'],
|
|
13850
|
+
C: ['x1', 'y1', 'x2', 'y2', 'x', 'y'],
|
|
13851
|
+
S: ['x2', 'y2', 'x', 'y'],
|
|
13852
|
+
Q: ['x1', 'y1', 'x', 'y'],
|
|
13853
|
+
T: ['x', 'y'],
|
|
13854
|
+
A: ['rx', 'ry', 'xAxisRotation', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
|
|
13855
|
+
Z: []
|
|
13856
|
+
}; // Add lower case entries too matching uppercase (e.g. 'm' == 'M')
|
|
13857
|
+
|
|
13858
|
+
Object.keys(typeMap).forEach(function (key) {
|
|
13859
|
+
typeMap[key.toLowerCase()] = typeMap[key];
|
|
13860
|
+
});
|
|
13861
|
+
function arrayOfLength(length, value) {
|
|
13862
|
+
var array = Array(length);
|
|
13863
|
+
for (var i = 0; i < length; i++) {
|
|
13864
|
+
array[i] = value;
|
|
13865
|
+
}
|
|
13866
|
+
return array;
|
|
13867
|
+
}
|
|
13868
|
+
/**
|
|
13869
|
+
* Converts a command object to a string to be used in a `d` attribute
|
|
13870
|
+
* @param {Object} command A command object
|
|
13871
|
+
* @return {String} The string for the `d` attribute
|
|
13872
|
+
*/
|
|
13873
|
+
|
|
13874
|
+
function commandToString(command) {
|
|
13875
|
+
return "".concat(command.type).concat(typeMap[command.type].map(function (p) {
|
|
13876
|
+
return command[p];
|
|
13877
|
+
}).join(','));
|
|
13878
|
+
}
|
|
13879
|
+
/**
|
|
13880
|
+
* Converts command A to have the same type as command B.
|
|
13881
|
+
*
|
|
13882
|
+
* e.g., L0,5 -> C0,5,0,5,0,5
|
|
13883
|
+
*
|
|
13884
|
+
* Uses these rules:
|
|
13885
|
+
* x1 <- x
|
|
13886
|
+
* x2 <- x
|
|
13887
|
+
* y1 <- y
|
|
13888
|
+
* y2 <- y
|
|
13889
|
+
* rx <- 0
|
|
13890
|
+
* ry <- 0
|
|
13891
|
+
* xAxisRotation <- read from B
|
|
13892
|
+
* largeArcFlag <- read from B
|
|
13893
|
+
* sweepflag <- read from B
|
|
13894
|
+
*
|
|
13895
|
+
* @param {Object} aCommand Command object from path `d` attribute
|
|
13896
|
+
* @param {Object} bCommand Command object from path `d` attribute to match against
|
|
13897
|
+
* @return {Object} aCommand converted to type of bCommand
|
|
13898
|
+
*/
|
|
13899
|
+
|
|
13900
|
+
function convertToSameType(aCommand, bCommand) {
|
|
13901
|
+
var conversionMap = {
|
|
13902
|
+
x1: 'x',
|
|
13903
|
+
y1: 'y',
|
|
13904
|
+
x2: 'x',
|
|
13905
|
+
y2: 'y'
|
|
13906
|
+
};
|
|
13907
|
+
var readFromBKeys = ['xAxisRotation', 'largeArcFlag', 'sweepFlag']; // convert (but ignore M types)
|
|
13908
|
+
|
|
13909
|
+
if (aCommand.type !== bCommand.type && bCommand.type.toUpperCase() !== 'M') {
|
|
13910
|
+
var aConverted = {};
|
|
13911
|
+
Object.keys(bCommand).forEach(function (bKey) {
|
|
13912
|
+
var bValue = bCommand[bKey]; // first read from the A command
|
|
13913
|
+
|
|
13914
|
+
var aValue = aCommand[bKey]; // if it is one of these values, read from B no matter what
|
|
13915
|
+
|
|
13916
|
+
if (aValue === undefined) {
|
|
13917
|
+
if (readFromBKeys.includes(bKey)) {
|
|
13918
|
+
aValue = bValue;
|
|
13919
|
+
} else {
|
|
13920
|
+
// if it wasn't in the A command, see if an equivalent was
|
|
13921
|
+
if (aValue === undefined && conversionMap[bKey]) {
|
|
13922
|
+
aValue = aCommand[conversionMap[bKey]];
|
|
13923
|
+
} // if it doesn't have a converted value, use 0
|
|
13924
|
+
|
|
13925
|
+
if (aValue === undefined) {
|
|
13926
|
+
aValue = 0;
|
|
13927
|
+
}
|
|
13928
|
+
}
|
|
13929
|
+
}
|
|
13930
|
+
aConverted[bKey] = aValue;
|
|
13931
|
+
}); // update the type to match B
|
|
13932
|
+
|
|
13933
|
+
aConverted.type = bCommand.type;
|
|
13934
|
+
aCommand = aConverted;
|
|
13935
|
+
}
|
|
13936
|
+
return aCommand;
|
|
13937
|
+
}
|
|
13938
|
+
/**
|
|
13939
|
+
* Interpolate between command objects commandStart and commandEnd segmentCount times.
|
|
13940
|
+
* If the types are L, Q, or C then the curves are split as per de Casteljau's algorithm.
|
|
13941
|
+
* Otherwise we just copy commandStart segmentCount - 1 times, finally ending with commandEnd.
|
|
13942
|
+
*
|
|
13943
|
+
* @param {Object} commandStart Command object at the beginning of the segment
|
|
13944
|
+
* @param {Object} commandEnd Command object at the end of the segment
|
|
13945
|
+
* @param {Number} segmentCount The number of segments to split this into. If only 1
|
|
13946
|
+
* Then [commandEnd] is returned.
|
|
13947
|
+
* @return {Object[]} Array of ~segmentCount command objects between commandStart and
|
|
13948
|
+
* commandEnd. (Can be segmentCount+1 objects if commandStart is type M).
|
|
13949
|
+
*/
|
|
13950
|
+
|
|
13951
|
+
function splitSegment(commandStart, commandEnd, segmentCount) {
|
|
13952
|
+
var segments = []; // line, quadratic bezier, or cubic bezier
|
|
13953
|
+
|
|
13954
|
+
if (commandEnd.type === 'L' || commandEnd.type === 'Q' || commandEnd.type === 'C') {
|
|
13955
|
+
segments = segments.concat(splitCurve(commandStart, commandEnd, segmentCount)); // general case - just copy the same point
|
|
13956
|
+
} else {
|
|
13957
|
+
var copyCommand = _extends({}, commandStart); // convert M to L
|
|
13958
|
+
|
|
13959
|
+
if (copyCommand.type === 'M') {
|
|
13960
|
+
copyCommand.type = 'L';
|
|
13961
|
+
}
|
|
13962
|
+
segments = segments.concat(arrayOfLength(segmentCount - 1).map(function () {
|
|
13963
|
+
return copyCommand;
|
|
13964
|
+
}));
|
|
13965
|
+
segments.push(commandEnd);
|
|
13966
|
+
}
|
|
13967
|
+
return segments;
|
|
13968
|
+
}
|
|
13969
|
+
/**
|
|
13970
|
+
* Extends an array of commandsToExtend to the length of the referenceCommands by
|
|
13971
|
+
* splitting segments until the number of commands match. Ensures all the actual
|
|
13972
|
+
* points of commandsToExtend are in the extended array.
|
|
13973
|
+
*
|
|
13974
|
+
* @param {Object[]} commandsToExtend The command object array to extend
|
|
13975
|
+
* @param {Object[]} referenceCommands The command object array to match in length
|
|
13976
|
+
* @param {Function} excludeSegment a function that takes a start command object and
|
|
13977
|
+
* end command object and returns true if the segment should be excluded from splitting.
|
|
13978
|
+
* @return {Object[]} The extended commandsToExtend array
|
|
13979
|
+
*/
|
|
13980
|
+
|
|
13981
|
+
function extend(commandsToExtend, referenceCommands, excludeSegment) {
|
|
13982
|
+
// compute insertion points:
|
|
13983
|
+
// number of segments in the path to extend
|
|
13984
|
+
var numSegmentsToExtend = commandsToExtend.length - 1; // number of segments in the reference path.
|
|
13985
|
+
|
|
13986
|
+
var numReferenceSegments = referenceCommands.length - 1; // this value is always between [0, 1].
|
|
13987
|
+
|
|
13988
|
+
var segmentRatio = numSegmentsToExtend / numReferenceSegments; // create a map, mapping segments in referenceCommands to how many points
|
|
13989
|
+
// should be added in that segment (should always be >= 1 since we need each
|
|
13990
|
+
// point itself).
|
|
13991
|
+
// 0 = segment 0-1, 1 = segment 1-2, n-1 = last vertex
|
|
13992
|
+
|
|
13993
|
+
var countPointsPerSegment = arrayOfLength(numReferenceSegments).reduce(function (accum, d, i) {
|
|
13994
|
+
var insertIndex = Math.floor(segmentRatio * i); // handle excluding segments
|
|
13995
|
+
|
|
13996
|
+
if (excludeSegment && insertIndex < commandsToExtend.length - 1 && excludeSegment(commandsToExtend[insertIndex], commandsToExtend[insertIndex + 1])) {
|
|
13997
|
+
// set the insertIndex to the segment that this point should be added to:
|
|
13998
|
+
// round the insertIndex essentially so we split half and half on
|
|
13999
|
+
// neighbouring segments. hence the segmentRatio * i < 0.5
|
|
14000
|
+
var addToPriorSegment = segmentRatio * i % 1 < 0.5; // only skip segment if we already have 1 point in it (can't entirely remove a segment)
|
|
14001
|
+
|
|
14002
|
+
if (accum[insertIndex]) {
|
|
14003
|
+
// TODO - Note this is a naive algorithm that should work for most d3-area use cases
|
|
14004
|
+
// but if two adjacent segments are supposed to be skipped, this will not perform as
|
|
14005
|
+
// expected. Could be updated to search for nearest segment to place the point in, but
|
|
14006
|
+
// will only do that if necessary.
|
|
14007
|
+
// add to the prior segment
|
|
14008
|
+
if (addToPriorSegment) {
|
|
14009
|
+
if (insertIndex > 0) {
|
|
14010
|
+
insertIndex -= 1; // not possible to add to previous so adding to next
|
|
14011
|
+
} else if (insertIndex < commandsToExtend.length - 1) {
|
|
14012
|
+
insertIndex += 1;
|
|
14013
|
+
} // add to next segment
|
|
14014
|
+
} else if (insertIndex < commandsToExtend.length - 1) {
|
|
14015
|
+
insertIndex += 1; // not possible to add to next so adding to previous
|
|
14016
|
+
} else if (insertIndex > 0) {
|
|
14017
|
+
insertIndex -= 1;
|
|
14018
|
+
}
|
|
14019
|
+
}
|
|
14020
|
+
}
|
|
14021
|
+
accum[insertIndex] = (accum[insertIndex] || 0) + 1;
|
|
14022
|
+
return accum;
|
|
14023
|
+
}, []); // extend each segment to have the correct number of points for a smooth interpolation
|
|
14024
|
+
|
|
14025
|
+
var extended = countPointsPerSegment.reduce(function (extended, segmentCount, i) {
|
|
14026
|
+
// if last command, just add `segmentCount` number of times
|
|
14027
|
+
if (i === commandsToExtend.length - 1) {
|
|
14028
|
+
var lastCommandCopies = arrayOfLength(segmentCount, _extends({}, commandsToExtend[commandsToExtend.length - 1])); // convert M to L
|
|
14029
|
+
|
|
14030
|
+
if (lastCommandCopies[0].type === 'M') {
|
|
14031
|
+
lastCommandCopies.forEach(function (d) {
|
|
14032
|
+
d.type = 'L';
|
|
14033
|
+
});
|
|
14034
|
+
}
|
|
14035
|
+
return extended.concat(lastCommandCopies);
|
|
14036
|
+
} // otherwise, split the segment segmentCount times.
|
|
14037
|
+
|
|
14038
|
+
return extended.concat(splitSegment(commandsToExtend[i], commandsToExtend[i + 1], segmentCount));
|
|
14039
|
+
}, []); // add in the very first point since splitSegment only adds in the ones after it
|
|
14040
|
+
|
|
14041
|
+
extended.unshift(commandsToExtend[0]);
|
|
14042
|
+
return extended;
|
|
14043
|
+
}
|
|
14044
|
+
/**
|
|
14045
|
+
* Takes a path `d` string and converts it into an array of command
|
|
14046
|
+
* objects. Drops the `Z` character.
|
|
14047
|
+
*
|
|
14048
|
+
* @param {String|null} d A path `d` string
|
|
14049
|
+
*/
|
|
14050
|
+
|
|
14051
|
+
function pathCommandsFromString(d) {
|
|
14052
|
+
// split into valid tokens
|
|
14053
|
+
var tokens = (d || '').match(commandTokenRegex) || [];
|
|
14054
|
+
var commands = [];
|
|
14055
|
+
var commandArgs;
|
|
14056
|
+
var command; // iterate over each token, checking if we are at a new command
|
|
14057
|
+
// by presence in the typeMap
|
|
14058
|
+
|
|
14059
|
+
for (var i = 0; i < tokens.length; ++i) {
|
|
14060
|
+
commandArgs = typeMap[tokens[i]]; // new command found:
|
|
14061
|
+
|
|
14062
|
+
if (commandArgs) {
|
|
14063
|
+
command = {
|
|
14064
|
+
type: tokens[i]
|
|
14065
|
+
}; // add each of the expected args for this command:
|
|
14066
|
+
|
|
14067
|
+
for (var a = 0; a < commandArgs.length; ++a) {
|
|
14068
|
+
command[commandArgs[a]] = +tokens[i + a + 1];
|
|
14069
|
+
} // need to increment our token index appropriately since
|
|
14070
|
+
// we consumed token args
|
|
14071
|
+
|
|
14072
|
+
i += commandArgs.length;
|
|
14073
|
+
commands.push(command);
|
|
14074
|
+
}
|
|
14075
|
+
}
|
|
14076
|
+
return commands;
|
|
14077
|
+
}
|
|
14078
|
+
/**
|
|
14079
|
+
* Interpolate from A to B by extending A and B during interpolation to have
|
|
14080
|
+
* the same number of points. This allows for a smooth transition when they
|
|
14081
|
+
* have a different number of points.
|
|
14082
|
+
*
|
|
14083
|
+
* Ignores the `Z` command in paths unless both A and B end with it.
|
|
14084
|
+
*
|
|
14085
|
+
* This function works directly with arrays of command objects instead of with
|
|
14086
|
+
* path `d` strings (see interpolatePath for working with `d` strings).
|
|
14087
|
+
*
|
|
14088
|
+
* @param {Object[]} aCommandsInput Array of path commands
|
|
14089
|
+
* @param {Object[]} bCommandsInput Array of path commands
|
|
14090
|
+
* @param {(Function|Object)} interpolateOptions
|
|
14091
|
+
* @param {Function} interpolateOptions.excludeSegment a function that takes a start command object and
|
|
14092
|
+
* end command object and returns true if the segment should be excluded from splitting.
|
|
14093
|
+
* @param {Boolean} interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
|
|
14094
|
+
* be sourced from input argument or computed.
|
|
14095
|
+
* @returns {Function} Interpolation function that maps t ([0, 1]) to an array of path commands.
|
|
14096
|
+
*/
|
|
14097
|
+
|
|
14098
|
+
function interpolatePathCommands(aCommandsInput, bCommandsInput, interpolateOptions) {
|
|
14099
|
+
// make a copy so we don't mess with the input arrays
|
|
14100
|
+
var aCommands = aCommandsInput == null ? [] : aCommandsInput.slice();
|
|
14101
|
+
var bCommands = bCommandsInput == null ? [] : bCommandsInput.slice();
|
|
14102
|
+
var _ref = _typeof(interpolateOptions) === 'object' ? interpolateOptions : {
|
|
14103
|
+
excludeSegment: interpolateOptions,
|
|
14104
|
+
snapEndsToInput: true
|
|
14105
|
+
},
|
|
14106
|
+
excludeSegment = _ref.excludeSegment,
|
|
14107
|
+
snapEndsToInput = _ref.snapEndsToInput; // both input sets are empty, so we don't interpolate
|
|
14108
|
+
|
|
14109
|
+
if (!aCommands.length && !bCommands.length) {
|
|
14110
|
+
return function nullInterpolator() {
|
|
14111
|
+
return [];
|
|
14112
|
+
};
|
|
14113
|
+
} // do we add Z during interpolation? yes if both have it. (we'd expect both to have it or not)
|
|
14114
|
+
|
|
14115
|
+
var addZ = (aCommands.length === 0 || aCommands[aCommands.length - 1].type === 'Z') && (bCommands.length === 0 || bCommands[bCommands.length - 1].type === 'Z'); // we temporarily remove Z
|
|
14116
|
+
|
|
14117
|
+
if (aCommands.length > 0 && aCommands[aCommands.length - 1].type === 'Z') {
|
|
14118
|
+
aCommands.pop();
|
|
14119
|
+
}
|
|
14120
|
+
if (bCommands.length > 0 && bCommands[bCommands.length - 1].type === 'Z') {
|
|
14121
|
+
bCommands.pop();
|
|
14122
|
+
} // if A is empty, treat it as if it used to contain just the first point
|
|
14123
|
+
// of B. This makes it so the line extends out of from that first point.
|
|
14124
|
+
|
|
14125
|
+
if (!aCommands.length) {
|
|
14126
|
+
aCommands.push(bCommands[0]); // otherwise if B is empty, treat it as if it contains the first point
|
|
14127
|
+
// of A. This makes it so the line retracts into the first point.
|
|
14128
|
+
} else if (!bCommands.length) {
|
|
14129
|
+
bCommands.push(aCommands[0]);
|
|
14130
|
+
} // extend to match equal size
|
|
14131
|
+
|
|
14132
|
+
var numPointsToExtend = Math.abs(bCommands.length - aCommands.length);
|
|
14133
|
+
if (numPointsToExtend !== 0) {
|
|
14134
|
+
// B has more points than A, so add points to A before interpolating
|
|
14135
|
+
if (bCommands.length > aCommands.length) {
|
|
14136
|
+
aCommands = extend(aCommands, bCommands, excludeSegment); // else if A has more points than B, add more points to B
|
|
14137
|
+
} else if (bCommands.length < aCommands.length) {
|
|
14138
|
+
bCommands = extend(bCommands, aCommands, excludeSegment);
|
|
14139
|
+
}
|
|
14140
|
+
} // commands have same length now.
|
|
14141
|
+
// convert commands in A to the same type as those in B
|
|
14142
|
+
|
|
14143
|
+
aCommands = aCommands.map(function (aCommand, i) {
|
|
14144
|
+
return convertToSameType(aCommand, bCommands[i]);
|
|
14145
|
+
}); // create mutable interpolated command objects
|
|
14146
|
+
|
|
14147
|
+
var interpolatedCommands = aCommands.map(function (aCommand) {
|
|
14148
|
+
return _objectSpread2({}, aCommand);
|
|
14149
|
+
});
|
|
14150
|
+
if (addZ) {
|
|
14151
|
+
interpolatedCommands.push({
|
|
14152
|
+
type: 'Z'
|
|
14153
|
+
});
|
|
14154
|
+
aCommands.push({
|
|
14155
|
+
type: 'Z'
|
|
14156
|
+
}); // required for when returning at t == 0
|
|
14157
|
+
}
|
|
14158
|
+
return function pathCommandInterpolator(t) {
|
|
14159
|
+
// at 1 return the final value without the extensions used during interpolation
|
|
14160
|
+
if (t === 1 && snapEndsToInput) {
|
|
14161
|
+
return bCommandsInput == null ? [] : bCommandsInput;
|
|
14162
|
+
} // work with aCommands directly since interpolatedCommands are mutated
|
|
14163
|
+
|
|
14164
|
+
if (t === 0) {
|
|
14165
|
+
return aCommands;
|
|
14166
|
+
} // interpolate the commands using the mutable interpolated command objs
|
|
14167
|
+
|
|
14168
|
+
for (var i = 0; i < interpolatedCommands.length; ++i) {
|
|
14169
|
+
// if (interpolatedCommands[i].type === 'Z') continue;
|
|
14170
|
+
var aCommand = aCommands[i];
|
|
14171
|
+
var bCommand = bCommands[i];
|
|
14172
|
+
var interpolatedCommand = interpolatedCommands[i];
|
|
14173
|
+
var _iterator = _createForOfIteratorHelper(typeMap[interpolatedCommand.type]),
|
|
14174
|
+
_step;
|
|
14175
|
+
try {
|
|
14176
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
14177
|
+
var arg = _step.value;
|
|
14178
|
+
interpolatedCommand[arg] = (1 - t) * aCommand[arg] + t * bCommand[arg]; // do not use floats for flags (#27), round to integer
|
|
14179
|
+
|
|
14180
|
+
if (arg === 'largeArcFlag' || arg === 'sweepFlag') {
|
|
14181
|
+
interpolatedCommand[arg] = Math.round(interpolatedCommand[arg]);
|
|
14182
|
+
}
|
|
14183
|
+
}
|
|
14184
|
+
} catch (err) {
|
|
14185
|
+
_iterator.e(err);
|
|
14186
|
+
} finally {
|
|
14187
|
+
_iterator.f();
|
|
14188
|
+
}
|
|
14189
|
+
}
|
|
14190
|
+
return interpolatedCommands;
|
|
14191
|
+
};
|
|
14192
|
+
}
|
|
14193
|
+
/** @typedef InterpolateOptions */
|
|
14194
|
+
|
|
14195
|
+
/**
|
|
14196
|
+
* Interpolate from A to B by extending A and B during interpolation to have
|
|
14197
|
+
* the same number of points. This allows for a smooth transition when they
|
|
14198
|
+
* have a different number of points.
|
|
14199
|
+
*
|
|
14200
|
+
* Ignores the `Z` character in paths unless both A and B end with it.
|
|
14201
|
+
*
|
|
14202
|
+
* @param {String} a The `d` attribute for a path
|
|
14203
|
+
* @param {String} b The `d` attribute for a path
|
|
14204
|
+
* @param {((command1, command2) => boolean|{
|
|
14205
|
+
* excludeSegment?: (command1, command2) => boolean;
|
|
14206
|
+
* snapEndsToInput?: boolean
|
|
14207
|
+
* })} interpolateOptions The excludeSegment function or an options object
|
|
14208
|
+
* - interpolateOptions.excludeSegment a function that takes a start command object and
|
|
14209
|
+
* end command object and returns true if the segment should be excluded from splitting.
|
|
14210
|
+
* - interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
|
|
14211
|
+
* be sourced from input argument or computed.
|
|
14212
|
+
* @returns {Function} Interpolation function that maps t ([0, 1]) to a path `d` string.
|
|
14213
|
+
*/
|
|
14214
|
+
|
|
14215
|
+
function interpolatePath(a, b, interpolateOptions) {
|
|
14216
|
+
var aCommands = pathCommandsFromString(a);
|
|
14217
|
+
var bCommands = pathCommandsFromString(b);
|
|
14218
|
+
var _ref2 = _typeof(interpolateOptions) === 'object' ? interpolateOptions : {
|
|
14219
|
+
excludeSegment: interpolateOptions,
|
|
14220
|
+
snapEndsToInput: true
|
|
14221
|
+
},
|
|
14222
|
+
excludeSegment = _ref2.excludeSegment,
|
|
14223
|
+
snapEndsToInput = _ref2.snapEndsToInput;
|
|
14224
|
+
if (!aCommands.length && !bCommands.length) {
|
|
14225
|
+
return function nullInterpolator() {
|
|
14226
|
+
return '';
|
|
14227
|
+
};
|
|
14228
|
+
}
|
|
14229
|
+
var commandInterpolator = interpolatePathCommands(aCommands, bCommands, {
|
|
14230
|
+
excludeSegment: excludeSegment,
|
|
14231
|
+
snapEndsToInput: snapEndsToInput
|
|
14232
|
+
});
|
|
14233
|
+
return function pathStringInterpolator(t) {
|
|
14234
|
+
// at 1 return the final value without the extensions used during interpolation
|
|
14235
|
+
if (t === 1 && snapEndsToInput) {
|
|
14236
|
+
return b == null ? '' : b;
|
|
14237
|
+
}
|
|
14238
|
+
var interpolatedCommands = commandInterpolator(t); // convert to a string (fastest concat: https://jsperf.com/join-concat/150)
|
|
14239
|
+
|
|
14240
|
+
var interpolatedString = '';
|
|
14241
|
+
var _iterator2 = _createForOfIteratorHelper(interpolatedCommands),
|
|
14242
|
+
_step2;
|
|
14243
|
+
try {
|
|
14244
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
14245
|
+
var interpolatedCommand = _step2.value;
|
|
14246
|
+
interpolatedString += commandToString(interpolatedCommand);
|
|
14247
|
+
}
|
|
14248
|
+
} catch (err) {
|
|
14249
|
+
_iterator2.e(err);
|
|
14250
|
+
} finally {
|
|
14251
|
+
_iterator2.f();
|
|
14252
|
+
}
|
|
14253
|
+
return interpolatedString;
|
|
14254
|
+
};
|
|
14255
|
+
}
|
|
14256
|
+
|
|
14257
|
+
var cssKeywords = {
|
|
14258
|
+
aliceblue: [240, 248, 255],
|
|
14259
|
+
antiquewhite: [250, 235, 215],
|
|
14260
|
+
aqua: [0, 255, 255],
|
|
14261
|
+
aquamarine: [127, 255, 212],
|
|
14262
|
+
azure: [240, 255, 255],
|
|
14263
|
+
beige: [245, 245, 220],
|
|
14264
|
+
bisque: [255, 228, 196],
|
|
14265
|
+
black: [0, 0, 0],
|
|
14266
|
+
blanchedalmond: [255, 235, 205],
|
|
14267
|
+
blue: [0, 0, 255],
|
|
14268
|
+
blueviolet: [138, 43, 226],
|
|
14269
|
+
brown: [165, 42, 42],
|
|
14270
|
+
burlywood: [222, 184, 135],
|
|
14271
|
+
cadetblue: [95, 158, 160],
|
|
14272
|
+
chartreuse: [127, 255, 0],
|
|
14273
|
+
chocolate: [210, 105, 30],
|
|
14274
|
+
coral: [255, 127, 80],
|
|
14275
|
+
cornflowerblue: [100, 149, 237],
|
|
14276
|
+
cornsilk: [255, 248, 220],
|
|
14277
|
+
crimson: [220, 20, 60],
|
|
14278
|
+
cyan: [0, 255, 255],
|
|
14279
|
+
darkblue: [0, 0, 139],
|
|
14280
|
+
darkcyan: [0, 139, 139],
|
|
14281
|
+
darkgoldenrod: [184, 134, 11],
|
|
14282
|
+
darkgray: [169, 169, 169],
|
|
14283
|
+
darkgreen: [0, 100, 0],
|
|
14284
|
+
darkgrey: [169, 169, 169],
|
|
14285
|
+
darkkhaki: [189, 183, 107],
|
|
14286
|
+
darkmagenta: [139, 0, 139],
|
|
14287
|
+
darkolivegreen: [85, 107, 47],
|
|
14288
|
+
darkorange: [255, 140, 0],
|
|
14289
|
+
darkorchid: [153, 50, 204],
|
|
14290
|
+
darkred: [139, 0, 0],
|
|
14291
|
+
darksalmon: [233, 150, 122],
|
|
14292
|
+
darkseagreen: [143, 188, 143],
|
|
14293
|
+
darkslateblue: [72, 61, 139],
|
|
14294
|
+
darkslategray: [47, 79, 79],
|
|
14295
|
+
darkslategrey: [47, 79, 79],
|
|
14296
|
+
darkturquoise: [0, 206, 209],
|
|
14297
|
+
darkviolet: [148, 0, 211],
|
|
14298
|
+
deeppink: [255, 20, 147],
|
|
14299
|
+
deepskyblue: [0, 191, 255],
|
|
14300
|
+
dimgray: [105, 105, 105],
|
|
14301
|
+
dimgrey: [105, 105, 105],
|
|
14302
|
+
dodgerblue: [30, 144, 255],
|
|
14303
|
+
firebrick: [178, 34, 34],
|
|
14304
|
+
floralwhite: [255, 250, 240],
|
|
14305
|
+
forestgreen: [34, 139, 34],
|
|
14306
|
+
fuchsia: [255, 0, 255],
|
|
14307
|
+
gainsboro: [220, 220, 220],
|
|
14308
|
+
ghostwhite: [248, 248, 255],
|
|
14309
|
+
gold: [255, 215, 0],
|
|
14310
|
+
goldenrod: [218, 165, 32],
|
|
14311
|
+
gray: [128, 128, 128],
|
|
14312
|
+
green: [0, 128, 0],
|
|
14313
|
+
greenyellow: [173, 255, 47],
|
|
14314
|
+
grey: [128, 128, 128],
|
|
14315
|
+
honeydew: [240, 255, 240],
|
|
14316
|
+
hotpink: [255, 105, 180],
|
|
14317
|
+
indianred: [205, 92, 92],
|
|
14318
|
+
indigo: [75, 0, 130],
|
|
14319
|
+
ivory: [255, 255, 240],
|
|
14320
|
+
khaki: [240, 230, 140],
|
|
14321
|
+
lavender: [230, 230, 250],
|
|
14322
|
+
lavenderblush: [255, 240, 245],
|
|
14323
|
+
lawngreen: [124, 252, 0],
|
|
14324
|
+
lemonchiffon: [255, 250, 205],
|
|
14325
|
+
lightblue: [173, 216, 230],
|
|
14326
|
+
lightcoral: [240, 128, 128],
|
|
14327
|
+
lightcyan: [224, 255, 255],
|
|
14328
|
+
lightgoldenrodyellow: [250, 250, 210],
|
|
14329
|
+
lightgray: [211, 211, 211],
|
|
14330
|
+
lightgreen: [144, 238, 144],
|
|
14331
|
+
lightgrey: [211, 211, 211],
|
|
14332
|
+
lightpink: [255, 182, 193],
|
|
14333
|
+
lightsalmon: [255, 160, 122],
|
|
14334
|
+
lightseagreen: [32, 178, 170],
|
|
14335
|
+
lightskyblue: [135, 206, 250],
|
|
14336
|
+
lightslategray: [119, 136, 153],
|
|
14337
|
+
lightslategrey: [119, 136, 153],
|
|
14338
|
+
lightsteelblue: [176, 196, 222],
|
|
14339
|
+
lightyellow: [255, 255, 224],
|
|
14340
|
+
lime: [0, 255, 0],
|
|
14341
|
+
limegreen: [50, 205, 50],
|
|
14342
|
+
linen: [250, 240, 230],
|
|
14343
|
+
magenta: [255, 0, 255],
|
|
14344
|
+
maroon: [128, 0, 0],
|
|
14345
|
+
mediumaquamarine: [102, 205, 170],
|
|
14346
|
+
mediumblue: [0, 0, 205],
|
|
14347
|
+
mediumorchid: [186, 85, 211],
|
|
14348
|
+
mediumpurple: [147, 112, 219],
|
|
14349
|
+
mediumseagreen: [60, 179, 113],
|
|
14350
|
+
mediumslateblue: [123, 104, 238],
|
|
14351
|
+
mediumspringgreen: [0, 250, 154],
|
|
14352
|
+
mediumturquoise: [72, 209, 204],
|
|
14353
|
+
mediumvioletred: [199, 21, 133],
|
|
14354
|
+
midnightblue: [25, 25, 112],
|
|
14355
|
+
mintcream: [245, 255, 250],
|
|
14356
|
+
mistyrose: [255, 228, 225],
|
|
14357
|
+
moccasin: [255, 228, 181],
|
|
14358
|
+
navajowhite: [255, 222, 173],
|
|
14359
|
+
navy: [0, 0, 128],
|
|
14360
|
+
oldlace: [253, 245, 230],
|
|
14361
|
+
olive: [128, 128, 0],
|
|
14362
|
+
olivedrab: [107, 142, 35],
|
|
14363
|
+
orange: [255, 165, 0],
|
|
14364
|
+
orangered: [255, 69, 0],
|
|
14365
|
+
orchid: [218, 112, 214],
|
|
14366
|
+
palegoldenrod: [238, 232, 170],
|
|
14367
|
+
palegreen: [152, 251, 152],
|
|
14368
|
+
paleturquoise: [175, 238, 238],
|
|
14369
|
+
palevioletred: [219, 112, 147],
|
|
14370
|
+
papayawhip: [255, 239, 213],
|
|
14371
|
+
peachpuff: [255, 218, 185],
|
|
14372
|
+
peru: [205, 133, 63],
|
|
14373
|
+
pink: [255, 192, 203],
|
|
14374
|
+
plum: [221, 160, 221],
|
|
14375
|
+
powderblue: [176, 224, 230],
|
|
14376
|
+
purple: [128, 0, 128],
|
|
14377
|
+
rebeccapurple: [102, 51, 153],
|
|
14378
|
+
red: [255, 0, 0],
|
|
14379
|
+
rosybrown: [188, 143, 143],
|
|
14380
|
+
royalblue: [65, 105, 225],
|
|
14381
|
+
saddlebrown: [139, 69, 19],
|
|
14382
|
+
salmon: [250, 128, 114],
|
|
14383
|
+
sandybrown: [244, 164, 96],
|
|
14384
|
+
seagreen: [46, 139, 87],
|
|
14385
|
+
seashell: [255, 245, 238],
|
|
14386
|
+
sienna: [160, 82, 45],
|
|
14387
|
+
silver: [192, 192, 192],
|
|
14388
|
+
skyblue: [135, 206, 235],
|
|
14389
|
+
slateblue: [106, 90, 205],
|
|
14390
|
+
slategray: [112, 128, 144],
|
|
14391
|
+
slategrey: [112, 128, 144],
|
|
14392
|
+
snow: [255, 250, 250],
|
|
14393
|
+
springgreen: [0, 255, 127],
|
|
14394
|
+
steelblue: [70, 130, 180],
|
|
14395
|
+
tan: [210, 180, 140],
|
|
14396
|
+
teal: [0, 128, 128],
|
|
14397
|
+
thistle: [216, 191, 216],
|
|
14398
|
+
tomato: [255, 99, 71],
|
|
14399
|
+
turquoise: [64, 224, 208],
|
|
14400
|
+
violet: [238, 130, 238],
|
|
14401
|
+
wheat: [245, 222, 179],
|
|
14402
|
+
white: [255, 255, 255],
|
|
14403
|
+
whitesmoke: [245, 245, 245],
|
|
14404
|
+
yellow: [255, 255, 0],
|
|
14405
|
+
yellowgreen: [154, 205, 50]
|
|
14406
|
+
};
|
|
14407
|
+
|
|
14408
|
+
const reverseNames = Object.create(null);
|
|
14409
|
+
|
|
14410
|
+
// Create a list of reverse color names
|
|
14411
|
+
for (const name in cssKeywords) {
|
|
14412
|
+
if (Object.hasOwn(cssKeywords, name)) {
|
|
14413
|
+
reverseNames[cssKeywords[name]] = name;
|
|
14414
|
+
}
|
|
14415
|
+
}
|
|
14416
|
+
const cs = {
|
|
14417
|
+
to: {},
|
|
14418
|
+
get: {}
|
|
14419
|
+
};
|
|
14420
|
+
cs.get = function (string) {
|
|
14421
|
+
const prefix = string.slice(0, 3).toLowerCase();
|
|
14422
|
+
let value;
|
|
14423
|
+
let model;
|
|
14424
|
+
switch (prefix) {
|
|
14425
|
+
case 'hsl':
|
|
14426
|
+
{
|
|
14427
|
+
value = cs.get.hsl(string);
|
|
14428
|
+
model = 'hsl';
|
|
14429
|
+
break;
|
|
14430
|
+
}
|
|
14431
|
+
case 'hwb':
|
|
14432
|
+
{
|
|
14433
|
+
value = cs.get.hwb(string);
|
|
14434
|
+
model = 'hwb';
|
|
14435
|
+
break;
|
|
14436
|
+
}
|
|
14437
|
+
default:
|
|
14438
|
+
{
|
|
14439
|
+
value = cs.get.rgb(string);
|
|
14440
|
+
model = 'rgb';
|
|
14441
|
+
break;
|
|
14442
|
+
}
|
|
14443
|
+
}
|
|
14444
|
+
if (!value) {
|
|
14445
|
+
return null;
|
|
14446
|
+
}
|
|
14447
|
+
return {
|
|
14448
|
+
model,
|
|
14449
|
+
value
|
|
14450
|
+
};
|
|
14451
|
+
};
|
|
14452
|
+
cs.get.rgb = function (string) {
|
|
14453
|
+
if (!string) {
|
|
14454
|
+
return null;
|
|
14455
|
+
}
|
|
14456
|
+
const abbr = /^#([a-f\d]{3,4})$/i;
|
|
14457
|
+
const hex = /^#([a-f\d]{6})([a-f\d]{2})?$/i;
|
|
14458
|
+
const rgba = /^rgba?\(\s*([+-]?(?:\d*\.)?\d+(?:e\d+)?)(?=[\s,])\s*(?:,\s*)?([+-]?(?:\d*\.)?\d+(?:e\d+)?)(?=[\s,])\s*(?:,\s*)?([+-]?(?:\d*\.)?\d+(?:e\d+)?)\s*(?:[\s,|/]\s*([+-]?(?:\d*\.)?\d+(?:e\d+)?)(%?)\s*)?\)$/i;
|
|
14459
|
+
const per = /^rgba?\(\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[\s,|/]\s*([+-]?[\d.]+)(%?)\s*)?\)$/i;
|
|
14460
|
+
const keyword = /^(\w+)$/;
|
|
14461
|
+
let rgb = [0, 0, 0, 1];
|
|
14462
|
+
let match;
|
|
14463
|
+
let i;
|
|
14464
|
+
let hexAlpha;
|
|
14465
|
+
if (match = string.match(hex)) {
|
|
14466
|
+
hexAlpha = match[2];
|
|
14467
|
+
match = match[1];
|
|
14468
|
+
for (i = 0; i < 3; i++) {
|
|
14469
|
+
// https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/19
|
|
14470
|
+
const i2 = i * 2;
|
|
14471
|
+
rgb[i] = Number.parseInt(match.slice(i2, i2 + 2), 16);
|
|
14472
|
+
}
|
|
14473
|
+
if (hexAlpha) {
|
|
14474
|
+
rgb[3] = Number.parseInt(hexAlpha, 16) / 255;
|
|
14475
|
+
}
|
|
14476
|
+
} else if (match = string.match(abbr)) {
|
|
14477
|
+
match = match[1];
|
|
14478
|
+
hexAlpha = match[3];
|
|
14479
|
+
for (i = 0; i < 3; i++) {
|
|
14480
|
+
rgb[i] = Number.parseInt(match[i] + match[i], 16);
|
|
14481
|
+
}
|
|
14482
|
+
if (hexAlpha) {
|
|
14483
|
+
rgb[3] = Number.parseInt(hexAlpha + hexAlpha, 16) / 255;
|
|
14484
|
+
}
|
|
14485
|
+
} else if (match = string.match(rgba)) {
|
|
14486
|
+
for (i = 0; i < 3; i++) {
|
|
14487
|
+
rgb[i] = Number.parseFloat(match[i + 1]);
|
|
14488
|
+
}
|
|
14489
|
+
if (match[4]) {
|
|
14490
|
+
rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]);
|
|
14491
|
+
}
|
|
14492
|
+
} else if (match = string.match(per)) {
|
|
14493
|
+
for (i = 0; i < 3; i++) {
|
|
14494
|
+
rgb[i] = Math.round(Number.parseFloat(match[i + 1]) * 2.55);
|
|
14495
|
+
}
|
|
14496
|
+
if (match[4]) {
|
|
14497
|
+
rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]);
|
|
14498
|
+
}
|
|
14499
|
+
} else if (match = string.toLowerCase().match(keyword)) {
|
|
14500
|
+
if (match[1] === 'transparent') {
|
|
14501
|
+
return [0, 0, 0, 0];
|
|
14502
|
+
}
|
|
14503
|
+
if (!Object.hasOwn(cssKeywords, match[1])) {
|
|
14504
|
+
return null;
|
|
14505
|
+
}
|
|
14506
|
+
|
|
14507
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
14508
|
+
rgb = cssKeywords[match[1]].slice();
|
|
14509
|
+
rgb[3] = 1;
|
|
14510
|
+
return rgb;
|
|
14511
|
+
} else {
|
|
14512
|
+
return null;
|
|
14513
|
+
}
|
|
14514
|
+
for (i = 0; i < 3; i++) {
|
|
14515
|
+
rgb[i] = clamp(rgb[i], 0, 255);
|
|
14516
|
+
}
|
|
14517
|
+
rgb[3] = clamp(rgb[3], 0, 1);
|
|
14518
|
+
return rgb;
|
|
14519
|
+
};
|
|
14520
|
+
cs.get.hsl = function (string) {
|
|
14521
|
+
if (!string) {
|
|
14522
|
+
return null;
|
|
14523
|
+
}
|
|
14524
|
+
const hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[,|/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:e[+-]?\d+)?)\s*)?\)$/i;
|
|
14525
|
+
const match = string.match(hsl);
|
|
14526
|
+
if (match) {
|
|
14527
|
+
const alpha = Number.parseFloat(match[4]);
|
|
14528
|
+
const h = (Number.parseFloat(match[1]) % 360 + 360) % 360;
|
|
14529
|
+
const s = clamp(Number.parseFloat(match[2]), 0, 100);
|
|
14530
|
+
const l = clamp(Number.parseFloat(match[3]), 0, 100);
|
|
14531
|
+
const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1);
|
|
14532
|
+
return [h, s, l, a];
|
|
14533
|
+
}
|
|
14534
|
+
return null;
|
|
14535
|
+
};
|
|
14536
|
+
cs.get.hwb = function (string) {
|
|
14537
|
+
if (!string) {
|
|
14538
|
+
return null;
|
|
14539
|
+
}
|
|
14540
|
+
const hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*[\s,]\s*([+-]?[\d.]+)%\s*[\s,]\s*([+-]?[\d.]+)%\s*(?:[\s,]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:e[+-]?\d+)?)\s*)?\)$/i;
|
|
14541
|
+
const match = string.match(hwb);
|
|
14542
|
+
if (match) {
|
|
14543
|
+
const alpha = Number.parseFloat(match[4]);
|
|
14544
|
+
const h = (Number.parseFloat(match[1]) % 360 + 360) % 360;
|
|
14545
|
+
const w = clamp(Number.parseFloat(match[2]), 0, 100);
|
|
14546
|
+
const b = clamp(Number.parseFloat(match[3]), 0, 100);
|
|
14547
|
+
const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1);
|
|
14548
|
+
return [h, w, b, a];
|
|
14549
|
+
}
|
|
14550
|
+
return null;
|
|
14551
|
+
};
|
|
14552
|
+
cs.to.hex = function (...rgba) {
|
|
14553
|
+
return '#' + hexDouble(rgba[0]) + hexDouble(rgba[1]) + hexDouble(rgba[2]) + (rgba[3] < 1 ? hexDouble(Math.round(rgba[3] * 255)) : '');
|
|
14554
|
+
};
|
|
14555
|
+
cs.to.rgb = function (...rgba) {
|
|
14556
|
+
return rgba.length < 4 || rgba[3] === 1 ? 'rgb(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ')' : 'rgba(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ', ' + rgba[3] + ')';
|
|
14557
|
+
};
|
|
14558
|
+
cs.to.rgb.percent = function (...rgba) {
|
|
14559
|
+
const r = Math.round(rgba[0] / 255 * 100);
|
|
14560
|
+
const g = Math.round(rgba[1] / 255 * 100);
|
|
14561
|
+
const b = Math.round(rgba[2] / 255 * 100);
|
|
14562
|
+
return rgba.length < 4 || rgba[3] === 1 ? 'rgb(' + r + '%, ' + g + '%, ' + b + '%)' : 'rgba(' + r + '%, ' + g + '%, ' + b + '%, ' + rgba[3] + ')';
|
|
14563
|
+
};
|
|
14564
|
+
cs.to.hsl = function (...hsla) {
|
|
14565
|
+
return hsla.length < 4 || hsla[3] === 1 ? 'hsl(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%)' : 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';
|
|
14566
|
+
};
|
|
14567
|
+
|
|
14568
|
+
// Hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
|
|
14569
|
+
// (hwb have alpha optional & 1 is default value)
|
|
14570
|
+
cs.to.hwb = function (...hwba) {
|
|
14571
|
+
let a = '';
|
|
14572
|
+
if (hwba.length >= 4 && hwba[3] !== 1) {
|
|
14573
|
+
a = ', ' + hwba[3];
|
|
14574
|
+
}
|
|
14575
|
+
return 'hwb(' + hwba[0] + ', ' + hwba[1] + '%, ' + hwba[2] + '%' + a + ')';
|
|
14576
|
+
};
|
|
14577
|
+
cs.to.keyword = function (...rgb) {
|
|
14578
|
+
return reverseNames[rgb.slice(0, 3)];
|
|
14579
|
+
};
|
|
14580
|
+
|
|
14581
|
+
// Helpers
|
|
14582
|
+
function clamp(number_, min, max) {
|
|
14583
|
+
return Math.min(Math.max(min, number_), max);
|
|
14584
|
+
}
|
|
14585
|
+
function hexDouble(number_) {
|
|
14586
|
+
const string_ = Math.round(number_).toString(16).toUpperCase();
|
|
14587
|
+
return string_.length < 2 ? '0' + string_ : string_;
|
|
14588
|
+
}
|
|
14589
|
+
|
|
14590
|
+
/* MIT license */
|
|
14591
|
+
/* eslint-disable no-mixed-operators */
|
|
14592
|
+
|
|
14593
|
+
// NOTE: conversions should only return primitive values (i.e. arrays, or
|
|
14594
|
+
// values that give correct `typeof` results).
|
|
14595
|
+
// do not use box values types (i.e. Number(), String(), etc.)
|
|
14596
|
+
|
|
14597
|
+
const reverseKeywords = {};
|
|
14598
|
+
for (const key of Object.keys(cssKeywords)) {
|
|
14599
|
+
reverseKeywords[cssKeywords[key]] = key;
|
|
14600
|
+
}
|
|
14601
|
+
const convert$1 = {
|
|
14602
|
+
rgb: {
|
|
14603
|
+
channels: 3,
|
|
14604
|
+
labels: 'rgb'
|
|
14605
|
+
},
|
|
14606
|
+
hsl: {
|
|
14607
|
+
channels: 3,
|
|
14608
|
+
labels: 'hsl'
|
|
14609
|
+
},
|
|
14610
|
+
hsv: {
|
|
14611
|
+
channels: 3,
|
|
14612
|
+
labels: 'hsv'
|
|
14613
|
+
},
|
|
14614
|
+
hwb: {
|
|
14615
|
+
channels: 3,
|
|
14616
|
+
labels: 'hwb'
|
|
14617
|
+
},
|
|
14618
|
+
cmyk: {
|
|
14619
|
+
channels: 4,
|
|
14620
|
+
labels: 'cmyk'
|
|
14621
|
+
},
|
|
14622
|
+
xyz: {
|
|
14623
|
+
channels: 3,
|
|
14624
|
+
labels: 'xyz'
|
|
14625
|
+
},
|
|
14626
|
+
lab: {
|
|
14627
|
+
channels: 3,
|
|
14628
|
+
labels: 'lab'
|
|
14629
|
+
},
|
|
14630
|
+
oklab: {
|
|
14631
|
+
channels: 3,
|
|
14632
|
+
labels: ['okl', 'oka', 'okb']
|
|
14633
|
+
},
|
|
14634
|
+
lch: {
|
|
14635
|
+
channels: 3,
|
|
14636
|
+
labels: 'lch'
|
|
14637
|
+
},
|
|
14638
|
+
oklch: {
|
|
14639
|
+
channels: 3,
|
|
14640
|
+
labels: ['okl', 'okc', 'okh']
|
|
14641
|
+
},
|
|
14642
|
+
hex: {
|
|
14643
|
+
channels: 1,
|
|
14644
|
+
labels: ['hex']
|
|
14645
|
+
},
|
|
14646
|
+
keyword: {
|
|
14647
|
+
channels: 1,
|
|
14648
|
+
labels: ['keyword']
|
|
14649
|
+
},
|
|
14650
|
+
ansi16: {
|
|
14651
|
+
channels: 1,
|
|
14652
|
+
labels: ['ansi16']
|
|
14653
|
+
},
|
|
14654
|
+
ansi256: {
|
|
14655
|
+
channels: 1,
|
|
14656
|
+
labels: ['ansi256']
|
|
14657
|
+
},
|
|
14658
|
+
hcg: {
|
|
14659
|
+
channels: 3,
|
|
14660
|
+
labels: ['h', 'c', 'g']
|
|
14661
|
+
},
|
|
14662
|
+
apple: {
|
|
14663
|
+
channels: 3,
|
|
14664
|
+
labels: ['r16', 'g16', 'b16']
|
|
14665
|
+
},
|
|
14666
|
+
gray: {
|
|
14667
|
+
channels: 1,
|
|
14668
|
+
labels: ['gray']
|
|
14669
|
+
}
|
|
14670
|
+
};
|
|
14671
|
+
|
|
14672
|
+
// LAB f(t) constant
|
|
14673
|
+
const LAB_FT = (6 / 29) ** 3;
|
|
14674
|
+
|
|
14675
|
+
// SRGB non-linear transform functions
|
|
14676
|
+
function srgbNonlinearTransform(c) {
|
|
14677
|
+
const cc = c > 0.003_130_8 ? 1.055 * c ** (1 / 2.4) - 0.055 : c * 12.92;
|
|
14678
|
+
return Math.min(Math.max(0, cc), 1);
|
|
14679
|
+
}
|
|
14680
|
+
function srgbNonlinearTransformInv(c) {
|
|
14681
|
+
return c > 0.040_45 ? ((c + 0.055) / 1.055) ** 2.4 : c / 12.92;
|
|
14682
|
+
}
|
|
14683
|
+
|
|
14684
|
+
// Hide .channels and .labels properties
|
|
14685
|
+
for (const model of Object.keys(convert$1)) {
|
|
14686
|
+
if (!('channels' in convert$1[model])) {
|
|
14687
|
+
throw new Error('missing channels property: ' + model);
|
|
14688
|
+
}
|
|
14689
|
+
if (!('labels' in convert$1[model])) {
|
|
14690
|
+
throw new Error('missing channel labels property: ' + model);
|
|
14691
|
+
}
|
|
14692
|
+
if (convert$1[model].labels.length !== convert$1[model].channels) {
|
|
14693
|
+
throw new Error('channel and label counts mismatch: ' + model);
|
|
14694
|
+
}
|
|
14695
|
+
const {
|
|
14696
|
+
channels,
|
|
14697
|
+
labels
|
|
14698
|
+
} = convert$1[model];
|
|
14699
|
+
delete convert$1[model].channels;
|
|
14700
|
+
delete convert$1[model].labels;
|
|
14701
|
+
Object.defineProperty(convert$1[model], 'channels', {
|
|
14702
|
+
value: channels
|
|
14703
|
+
});
|
|
14704
|
+
Object.defineProperty(convert$1[model], 'labels', {
|
|
14705
|
+
value: labels
|
|
14706
|
+
});
|
|
14707
|
+
}
|
|
14708
|
+
convert$1.rgb.hsl = function (rgb) {
|
|
14709
|
+
const r = rgb[0] / 255;
|
|
14710
|
+
const g = rgb[1] / 255;
|
|
14711
|
+
const b = rgb[2] / 255;
|
|
14712
|
+
const min = Math.min(r, g, b);
|
|
14713
|
+
const max = Math.max(r, g, b);
|
|
14714
|
+
const delta = max - min;
|
|
14715
|
+
let h;
|
|
14716
|
+
let s;
|
|
14717
|
+
switch (max) {
|
|
14718
|
+
case min:
|
|
14719
|
+
{
|
|
14720
|
+
h = 0;
|
|
14721
|
+
break;
|
|
14722
|
+
}
|
|
14723
|
+
case r:
|
|
14724
|
+
{
|
|
14725
|
+
h = (g - b) / delta;
|
|
14726
|
+
break;
|
|
14727
|
+
}
|
|
14728
|
+
case g:
|
|
14729
|
+
{
|
|
14730
|
+
h = 2 + (b - r) / delta;
|
|
14731
|
+
break;
|
|
14732
|
+
}
|
|
14733
|
+
case b:
|
|
14734
|
+
{
|
|
14735
|
+
h = 4 + (r - g) / delta;
|
|
14736
|
+
break;
|
|
14737
|
+
}
|
|
14738
|
+
// No default
|
|
14739
|
+
}
|
|
14740
|
+
h = Math.min(h * 60, 360);
|
|
14741
|
+
if (h < 0) {
|
|
14742
|
+
h += 360;
|
|
14743
|
+
}
|
|
14744
|
+
const l = (min + max) / 2;
|
|
14745
|
+
if (max === min) {
|
|
14746
|
+
s = 0;
|
|
14747
|
+
} else if (l <= 0.5) {
|
|
14748
|
+
s = delta / (max + min);
|
|
14749
|
+
} else {
|
|
14750
|
+
s = delta / (2 - max - min);
|
|
14751
|
+
}
|
|
14752
|
+
return [h, s * 100, l * 100];
|
|
14753
|
+
};
|
|
14754
|
+
convert$1.rgb.hsv = function (rgb) {
|
|
14755
|
+
let rdif;
|
|
14756
|
+
let gdif;
|
|
14757
|
+
let bdif;
|
|
14758
|
+
let h;
|
|
14759
|
+
let s;
|
|
14760
|
+
const r = rgb[0] / 255;
|
|
14761
|
+
const g = rgb[1] / 255;
|
|
14762
|
+
const b = rgb[2] / 255;
|
|
14763
|
+
const v = Math.max(r, g, b);
|
|
14764
|
+
const diff = v - Math.min(r, g, b);
|
|
14765
|
+
const diffc = function (c) {
|
|
14766
|
+
return (v - c) / 6 / diff + 1 / 2;
|
|
14767
|
+
};
|
|
14768
|
+
if (diff === 0) {
|
|
14769
|
+
h = 0;
|
|
14770
|
+
s = 0;
|
|
14771
|
+
} else {
|
|
14772
|
+
s = diff / v;
|
|
14773
|
+
rdif = diffc(r);
|
|
14774
|
+
gdif = diffc(g);
|
|
14775
|
+
bdif = diffc(b);
|
|
14776
|
+
switch (v) {
|
|
14777
|
+
case r:
|
|
14778
|
+
{
|
|
14779
|
+
h = bdif - gdif;
|
|
14780
|
+
break;
|
|
14781
|
+
}
|
|
14782
|
+
case g:
|
|
14783
|
+
{
|
|
14784
|
+
h = 1 / 3 + rdif - bdif;
|
|
14785
|
+
break;
|
|
14786
|
+
}
|
|
14787
|
+
case b:
|
|
14788
|
+
{
|
|
14789
|
+
h = 2 / 3 + gdif - rdif;
|
|
14790
|
+
break;
|
|
14791
|
+
}
|
|
14792
|
+
// No default
|
|
14793
|
+
}
|
|
14794
|
+
if (h < 0) {
|
|
14795
|
+
h += 1;
|
|
14796
|
+
} else if (h > 1) {
|
|
14797
|
+
h -= 1;
|
|
14798
|
+
}
|
|
14799
|
+
}
|
|
14800
|
+
return [h * 360, s * 100, v * 100];
|
|
14801
|
+
};
|
|
14802
|
+
convert$1.rgb.hwb = function (rgb) {
|
|
14803
|
+
const r = rgb[0];
|
|
14804
|
+
const g = rgb[1];
|
|
14805
|
+
let b = rgb[2];
|
|
14806
|
+
const h = convert$1.rgb.hsl(rgb)[0];
|
|
14807
|
+
const w = 1 / 255 * Math.min(r, Math.min(g, b));
|
|
14808
|
+
b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
|
|
14809
|
+
return [h, w * 100, b * 100];
|
|
14810
|
+
};
|
|
14811
|
+
convert$1.rgb.oklab = function (rgb) {
|
|
14812
|
+
// Assume sRGB
|
|
14813
|
+
const r = srgbNonlinearTransformInv(rgb[0] / 255);
|
|
14814
|
+
const g = srgbNonlinearTransformInv(rgb[1] / 255);
|
|
14815
|
+
const b = srgbNonlinearTransformInv(rgb[2] / 255);
|
|
14816
|
+
const lp = Math.cbrt(0.412_221_470_8 * r + 0.536_332_536_3 * g + 0.051_445_992_9 * b);
|
|
14817
|
+
const mp = Math.cbrt(0.211_903_498_2 * r + 0.680_699_545_1 * g + 0.107_396_956_6 * b);
|
|
14818
|
+
const sp = Math.cbrt(0.088_302_461_9 * r + 0.281_718_837_6 * g + 0.629_978_700_5 * b);
|
|
14819
|
+
const l = 0.210_454_255_3 * lp + 0.793_617_785 * mp - 0.004_072_046_8 * sp;
|
|
14820
|
+
const aa = 1.977_998_495_1 * lp - 2.428_592_205 * mp + 0.450_593_709_9 * sp;
|
|
14821
|
+
const bb = 0.025_904_037_1 * lp + 0.782_771_766_2 * mp - 0.808_675_766 * sp;
|
|
14822
|
+
return [l * 100, aa * 100, bb * 100];
|
|
14823
|
+
};
|
|
14824
|
+
convert$1.rgb.cmyk = function (rgb) {
|
|
14825
|
+
const r = rgb[0] / 255;
|
|
14826
|
+
const g = rgb[1] / 255;
|
|
14827
|
+
const b = rgb[2] / 255;
|
|
14828
|
+
const k = Math.min(1 - r, 1 - g, 1 - b);
|
|
14829
|
+
const c = (1 - r - k) / (1 - k) || 0;
|
|
14830
|
+
const m = (1 - g - k) / (1 - k) || 0;
|
|
14831
|
+
const y = (1 - b - k) / (1 - k) || 0;
|
|
14832
|
+
return [c * 100, m * 100, y * 100, k * 100];
|
|
14833
|
+
};
|
|
14834
|
+
function comparativeDistance(x, y) {
|
|
14835
|
+
/*
|
|
14836
|
+
See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
|
|
14837
|
+
*/
|
|
14838
|
+
return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
|
|
14839
|
+
}
|
|
14840
|
+
convert$1.rgb.keyword = function (rgb) {
|
|
14841
|
+
const reversed = reverseKeywords[rgb];
|
|
14842
|
+
if (reversed) {
|
|
14843
|
+
return reversed;
|
|
14844
|
+
}
|
|
14845
|
+
let currentClosestDistance = Number.POSITIVE_INFINITY;
|
|
14846
|
+
let currentClosestKeyword;
|
|
14847
|
+
for (const keyword of Object.keys(cssKeywords)) {
|
|
14848
|
+
const value = cssKeywords[keyword];
|
|
14849
|
+
|
|
14850
|
+
// Compute comparative distance
|
|
14851
|
+
const distance = comparativeDistance(rgb, value);
|
|
14852
|
+
|
|
14853
|
+
// Check if its less, if so set as closest
|
|
14854
|
+
if (distance < currentClosestDistance) {
|
|
14855
|
+
currentClosestDistance = distance;
|
|
14856
|
+
currentClosestKeyword = keyword;
|
|
14857
|
+
}
|
|
14858
|
+
}
|
|
14859
|
+
return currentClosestKeyword;
|
|
14860
|
+
};
|
|
14861
|
+
convert$1.keyword.rgb = function (keyword) {
|
|
14862
|
+
return [...cssKeywords[keyword]];
|
|
14863
|
+
};
|
|
14864
|
+
convert$1.rgb.xyz = function (rgb) {
|
|
14865
|
+
// Assume sRGB
|
|
14866
|
+
const r = srgbNonlinearTransformInv(rgb[0] / 255);
|
|
14867
|
+
const g = srgbNonlinearTransformInv(rgb[1] / 255);
|
|
14868
|
+
const b = srgbNonlinearTransformInv(rgb[2] / 255);
|
|
14869
|
+
const x = r * 0.412_456_4 + g * 0.357_576_1 + b * 0.180_437_5;
|
|
14870
|
+
const y = r * 0.212_672_9 + g * 0.715_152_2 + b * 0.072_175;
|
|
14871
|
+
const z = r * 0.019_333_9 + g * 0.119_192 + b * 0.950_304_1;
|
|
14872
|
+
return [x * 100, y * 100, z * 100];
|
|
14873
|
+
};
|
|
14874
|
+
convert$1.rgb.lab = function (rgb) {
|
|
14875
|
+
const xyz = convert$1.rgb.xyz(rgb);
|
|
14876
|
+
let x = xyz[0];
|
|
14877
|
+
let y = xyz[1];
|
|
14878
|
+
let z = xyz[2];
|
|
14879
|
+
x /= 95.047;
|
|
14880
|
+
y /= 100;
|
|
14881
|
+
z /= 108.883;
|
|
14882
|
+
x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116;
|
|
14883
|
+
y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116;
|
|
14884
|
+
z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116;
|
|
14885
|
+
const l = 116 * y - 16;
|
|
14886
|
+
const a = 500 * (x - y);
|
|
14887
|
+
const b = 200 * (y - z);
|
|
14888
|
+
return [l, a, b];
|
|
14889
|
+
};
|
|
14890
|
+
convert$1.hsl.rgb = function (hsl) {
|
|
14891
|
+
const h = hsl[0] / 360;
|
|
14892
|
+
const s = hsl[1] / 100;
|
|
14893
|
+
const l = hsl[2] / 100;
|
|
14894
|
+
let t3;
|
|
14895
|
+
let value;
|
|
14896
|
+
if (s === 0) {
|
|
14897
|
+
value = l * 255;
|
|
14898
|
+
return [value, value, value];
|
|
14899
|
+
}
|
|
14900
|
+
const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
14901
|
+
const t1 = 2 * l - t2;
|
|
14902
|
+
const rgb = [0, 0, 0];
|
|
14903
|
+
for (let i = 0; i < 3; i++) {
|
|
14904
|
+
t3 = h + 1 / 3 * -(i - 1);
|
|
14905
|
+
if (t3 < 0) {
|
|
14906
|
+
t3++;
|
|
14907
|
+
}
|
|
14908
|
+
if (t3 > 1) {
|
|
14909
|
+
t3--;
|
|
14910
|
+
}
|
|
14911
|
+
if (6 * t3 < 1) {
|
|
14912
|
+
value = t1 + (t2 - t1) * 6 * t3;
|
|
14913
|
+
} else if (2 * t3 < 1) {
|
|
14914
|
+
value = t2;
|
|
14915
|
+
} else if (3 * t3 < 2) {
|
|
14916
|
+
value = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
|
14917
|
+
} else {
|
|
14918
|
+
value = t1;
|
|
14919
|
+
}
|
|
14920
|
+
rgb[i] = value * 255;
|
|
14921
|
+
}
|
|
14922
|
+
return rgb;
|
|
14923
|
+
};
|
|
14924
|
+
convert$1.hsl.hsv = function (hsl) {
|
|
14925
|
+
const h = hsl[0];
|
|
14926
|
+
let s = hsl[1] / 100;
|
|
14927
|
+
let l = hsl[2] / 100;
|
|
14928
|
+
let smin = s;
|
|
14929
|
+
const lmin = Math.max(l, 0.01);
|
|
14930
|
+
l *= 2;
|
|
14931
|
+
s *= l <= 1 ? l : 2 - l;
|
|
14932
|
+
smin *= lmin <= 1 ? lmin : 2 - lmin;
|
|
14933
|
+
const v = (l + s) / 2;
|
|
14934
|
+
const sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s);
|
|
14935
|
+
return [h, sv * 100, v * 100];
|
|
14936
|
+
};
|
|
14937
|
+
convert$1.hsv.rgb = function (hsv) {
|
|
14938
|
+
const h = hsv[0] / 60;
|
|
14939
|
+
const s = hsv[1] / 100;
|
|
14940
|
+
let v = hsv[2] / 100;
|
|
14941
|
+
const hi = Math.floor(h) % 6;
|
|
14942
|
+
const f = h - Math.floor(h);
|
|
14943
|
+
const p = 255 * v * (1 - s);
|
|
14944
|
+
const q = 255 * v * (1 - s * f);
|
|
14945
|
+
const t = 255 * v * (1 - s * (1 - f));
|
|
14946
|
+
v *= 255;
|
|
14947
|
+
switch (hi) {
|
|
14948
|
+
case 0:
|
|
14949
|
+
{
|
|
14950
|
+
return [v, t, p];
|
|
14951
|
+
}
|
|
14952
|
+
case 1:
|
|
14953
|
+
{
|
|
14954
|
+
return [q, v, p];
|
|
14955
|
+
}
|
|
14956
|
+
case 2:
|
|
14957
|
+
{
|
|
14958
|
+
return [p, v, t];
|
|
14959
|
+
}
|
|
14960
|
+
case 3:
|
|
14961
|
+
{
|
|
14962
|
+
return [p, q, v];
|
|
14963
|
+
}
|
|
14964
|
+
case 4:
|
|
14965
|
+
{
|
|
14966
|
+
return [t, p, v];
|
|
14967
|
+
}
|
|
14968
|
+
case 5:
|
|
14969
|
+
{
|
|
14970
|
+
return [v, p, q];
|
|
14971
|
+
}
|
|
14972
|
+
}
|
|
14973
|
+
};
|
|
14974
|
+
convert$1.hsv.hsl = function (hsv) {
|
|
14975
|
+
const h = hsv[0];
|
|
14976
|
+
const s = hsv[1] / 100;
|
|
14977
|
+
const v = hsv[2] / 100;
|
|
14978
|
+
const vmin = Math.max(v, 0.01);
|
|
14979
|
+
let sl;
|
|
14980
|
+
let l;
|
|
14981
|
+
l = (2 - s) * v;
|
|
14982
|
+
const lmin = (2 - s) * vmin;
|
|
14983
|
+
sl = s * vmin;
|
|
14984
|
+
sl /= lmin <= 1 ? lmin : 2 - lmin;
|
|
14985
|
+
sl = sl || 0;
|
|
14986
|
+
l /= 2;
|
|
14987
|
+
return [h, sl * 100, l * 100];
|
|
14988
|
+
};
|
|
14989
|
+
|
|
14990
|
+
// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
|
|
14991
|
+
convert$1.hwb.rgb = function (hwb) {
|
|
14992
|
+
const h = hwb[0] / 360;
|
|
14993
|
+
let wh = hwb[1] / 100;
|
|
14994
|
+
let bl = hwb[2] / 100;
|
|
14995
|
+
const ratio = wh + bl;
|
|
14996
|
+
let f;
|
|
14997
|
+
|
|
14998
|
+
// Wh + bl cant be > 1
|
|
14999
|
+
if (ratio > 1) {
|
|
15000
|
+
wh /= ratio;
|
|
15001
|
+
bl /= ratio;
|
|
15002
|
+
}
|
|
15003
|
+
const i = Math.floor(6 * h);
|
|
15004
|
+
const v = 1 - bl;
|
|
15005
|
+
f = 6 * h - i;
|
|
15006
|
+
|
|
15007
|
+
// eslint-disable-next-line no-bitwise
|
|
15008
|
+
if ((i & 0x01) !== 0) {
|
|
15009
|
+
f = 1 - f;
|
|
15010
|
+
}
|
|
15011
|
+
const n = wh + f * (v - wh); // Linear interpolation
|
|
15012
|
+
|
|
15013
|
+
let r;
|
|
15014
|
+
let g;
|
|
15015
|
+
let b;
|
|
15016
|
+
/* eslint-disable max-statements-per-line,no-multi-spaces, default-case-last */
|
|
15017
|
+
switch (i) {
|
|
15018
|
+
default:
|
|
15019
|
+
case 6:
|
|
15020
|
+
case 0:
|
|
15021
|
+
{
|
|
15022
|
+
r = v;
|
|
15023
|
+
g = n;
|
|
15024
|
+
b = wh;
|
|
15025
|
+
break;
|
|
15026
|
+
}
|
|
15027
|
+
case 1:
|
|
15028
|
+
{
|
|
15029
|
+
r = n;
|
|
15030
|
+
g = v;
|
|
15031
|
+
b = wh;
|
|
15032
|
+
break;
|
|
15033
|
+
}
|
|
15034
|
+
case 2:
|
|
15035
|
+
{
|
|
15036
|
+
r = wh;
|
|
15037
|
+
g = v;
|
|
15038
|
+
b = n;
|
|
15039
|
+
break;
|
|
15040
|
+
}
|
|
15041
|
+
case 3:
|
|
15042
|
+
{
|
|
15043
|
+
r = wh;
|
|
15044
|
+
g = n;
|
|
15045
|
+
b = v;
|
|
15046
|
+
break;
|
|
15047
|
+
}
|
|
15048
|
+
case 4:
|
|
15049
|
+
{
|
|
15050
|
+
r = n;
|
|
15051
|
+
g = wh;
|
|
15052
|
+
b = v;
|
|
15053
|
+
break;
|
|
15054
|
+
}
|
|
15055
|
+
case 5:
|
|
15056
|
+
{
|
|
15057
|
+
r = v;
|
|
15058
|
+
g = wh;
|
|
15059
|
+
b = n;
|
|
15060
|
+
break;
|
|
15061
|
+
}
|
|
15062
|
+
}
|
|
15063
|
+
/* eslint-enable max-statements-per-line,no-multi-spaces, default-case-last */
|
|
15064
|
+
|
|
15065
|
+
return [r * 255, g * 255, b * 255];
|
|
15066
|
+
};
|
|
15067
|
+
convert$1.cmyk.rgb = function (cmyk) {
|
|
15068
|
+
const c = cmyk[0] / 100;
|
|
15069
|
+
const m = cmyk[1] / 100;
|
|
15070
|
+
const y = cmyk[2] / 100;
|
|
15071
|
+
const k = cmyk[3] / 100;
|
|
15072
|
+
const r = 1 - Math.min(1, c * (1 - k) + k);
|
|
15073
|
+
const g = 1 - Math.min(1, m * (1 - k) + k);
|
|
15074
|
+
const b = 1 - Math.min(1, y * (1 - k) + k);
|
|
15075
|
+
return [r * 255, g * 255, b * 255];
|
|
15076
|
+
};
|
|
15077
|
+
convert$1.xyz.rgb = function (xyz) {
|
|
15078
|
+
const x = xyz[0] / 100;
|
|
15079
|
+
const y = xyz[1] / 100;
|
|
15080
|
+
const z = xyz[2] / 100;
|
|
15081
|
+
let r;
|
|
15082
|
+
let g;
|
|
15083
|
+
let b;
|
|
15084
|
+
r = x * 3.240_454_2 + y * -1.5371385 + z * -0.4985314;
|
|
15085
|
+
g = x * -0.969266 + y * 1.876_010_8 + z * 0.041_556;
|
|
15086
|
+
b = x * 0.055_643_4 + y * -0.2040259 + z * 1.057_225_2;
|
|
15087
|
+
|
|
15088
|
+
// Assume sRGB
|
|
15089
|
+
r = srgbNonlinearTransform(r);
|
|
15090
|
+
g = srgbNonlinearTransform(g);
|
|
15091
|
+
b = srgbNonlinearTransform(b);
|
|
15092
|
+
return [r * 255, g * 255, b * 255];
|
|
15093
|
+
};
|
|
15094
|
+
convert$1.xyz.lab = function (xyz) {
|
|
15095
|
+
let x = xyz[0];
|
|
15096
|
+
let y = xyz[1];
|
|
15097
|
+
let z = xyz[2];
|
|
15098
|
+
x /= 95.047;
|
|
15099
|
+
y /= 100;
|
|
15100
|
+
z /= 108.883;
|
|
15101
|
+
x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116;
|
|
15102
|
+
y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116;
|
|
15103
|
+
z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116;
|
|
15104
|
+
const l = 116 * y - 16;
|
|
15105
|
+
const a = 500 * (x - y);
|
|
15106
|
+
const b = 200 * (y - z);
|
|
15107
|
+
return [l, a, b];
|
|
15108
|
+
};
|
|
15109
|
+
convert$1.xyz.oklab = function (xyz) {
|
|
15110
|
+
const x = xyz[0] / 100;
|
|
15111
|
+
const y = xyz[1] / 100;
|
|
15112
|
+
const z = xyz[2] / 100;
|
|
15113
|
+
const lp = Math.cbrt(0.818_933_010_1 * x + 0.361_866_742_4 * y - 0.128_859_713_7 * z);
|
|
15114
|
+
const mp = Math.cbrt(0.032_984_543_6 * x + 0.929_311_871_5 * y + 0.036_145_638_7 * z);
|
|
15115
|
+
const sp = Math.cbrt(0.048_200_301_8 * x + 0.264_366_269_1 * y + 0.633_851_707 * z);
|
|
15116
|
+
const l = 0.210_454_255_3 * lp + 0.793_617_785 * mp - 0.004_072_046_8 * sp;
|
|
15117
|
+
const a = 1.977_998_495_1 * lp - 2.428_592_205 * mp + 0.450_593_709_9 * sp;
|
|
15118
|
+
const b = 0.025_904_037_1 * lp + 0.782_771_766_2 * mp - 0.808_675_766 * sp;
|
|
15119
|
+
return [l * 100, a * 100, b * 100];
|
|
15120
|
+
};
|
|
15121
|
+
convert$1.oklab.oklch = function (oklab) {
|
|
15122
|
+
return convert$1.lab.lch(oklab);
|
|
15123
|
+
};
|
|
15124
|
+
convert$1.oklab.xyz = function (oklab) {
|
|
15125
|
+
const ll = oklab[0] / 100;
|
|
15126
|
+
const a = oklab[1] / 100;
|
|
15127
|
+
const b = oklab[2] / 100;
|
|
15128
|
+
const l = (0.999_999_998 * ll + 0.396_337_792 * a + 0.215_803_758 * b) ** 3;
|
|
15129
|
+
const m = (1.000_000_008 * ll - 0.105_561_342 * a - 0.063_854_175 * b) ** 3;
|
|
15130
|
+
const s = (1.000_000_055 * ll - 0.089_484_182 * a - 1.291_485_538 * b) ** 3;
|
|
15131
|
+
const x = 1.227_013_851 * l - 0.557_799_98 * m + 0.281_256_149 * s;
|
|
15132
|
+
const y = -0.040580178 * l + 1.112_256_87 * m - 0.071_676_679 * s;
|
|
15133
|
+
const z = -0.076381285 * l - 0.421_481_978 * m + 1.586_163_22 * s;
|
|
15134
|
+
return [x * 100, y * 100, z * 100];
|
|
15135
|
+
};
|
|
15136
|
+
convert$1.oklab.rgb = function (oklab) {
|
|
15137
|
+
const ll = oklab[0] / 100;
|
|
15138
|
+
const aa = oklab[1] / 100;
|
|
15139
|
+
const bb = oklab[2] / 100;
|
|
15140
|
+
const l = (ll + 0.396_337_777_4 * aa + 0.215_803_757_3 * bb) ** 3;
|
|
15141
|
+
const m = (ll - 0.105_561_345_8 * aa - 0.063_854_172_8 * bb) ** 3;
|
|
15142
|
+
const s = (ll - 0.089_484_177_5 * aa - 1.291_485_548 * bb) ** 3;
|
|
15143
|
+
|
|
15144
|
+
// Assume sRGB
|
|
15145
|
+
const r = srgbNonlinearTransform(4.076_741_662_1 * l - 3.307_711_591_3 * m + 0.230_969_929_2 * s);
|
|
15146
|
+
const g = srgbNonlinearTransform(-1.2684380046 * l + 2.609_757_401_1 * m - 0.341_319_396_5 * s);
|
|
15147
|
+
const b = srgbNonlinearTransform(-0.0041960863 * l - 0.703_418_614_7 * m + 1.707_614_701 * s);
|
|
15148
|
+
return [r * 255, g * 255, b * 255];
|
|
15149
|
+
};
|
|
15150
|
+
convert$1.oklch.oklab = function (oklch) {
|
|
15151
|
+
return convert$1.lch.lab(oklch);
|
|
15152
|
+
};
|
|
15153
|
+
convert$1.lab.xyz = function (lab) {
|
|
15154
|
+
const l = lab[0];
|
|
15155
|
+
const a = lab[1];
|
|
15156
|
+
const b = lab[2];
|
|
15157
|
+
let x;
|
|
15158
|
+
let y;
|
|
15159
|
+
let z;
|
|
15160
|
+
y = (l + 16) / 116;
|
|
15161
|
+
x = a / 500 + y;
|
|
15162
|
+
z = y - b / 200;
|
|
15163
|
+
const y2 = y ** 3;
|
|
15164
|
+
const x2 = x ** 3;
|
|
15165
|
+
const z2 = z ** 3;
|
|
15166
|
+
y = y2 > LAB_FT ? y2 : (y - 16 / 116) / 7.787;
|
|
15167
|
+
x = x2 > LAB_FT ? x2 : (x - 16 / 116) / 7.787;
|
|
15168
|
+
z = z2 > LAB_FT ? z2 : (z - 16 / 116) / 7.787;
|
|
15169
|
+
|
|
15170
|
+
// Illuminant D65 XYZ Tristrimulus Values
|
|
15171
|
+
// https://en.wikipedia.org/wiki/CIE_1931_color_space
|
|
15172
|
+
x *= 95.047;
|
|
15173
|
+
y *= 100;
|
|
15174
|
+
z *= 108.883;
|
|
15175
|
+
return [x, y, z];
|
|
15176
|
+
};
|
|
15177
|
+
convert$1.lab.lch = function (lab) {
|
|
15178
|
+
const l = lab[0];
|
|
15179
|
+
const a = lab[1];
|
|
15180
|
+
const b = lab[2];
|
|
15181
|
+
let h;
|
|
15182
|
+
const hr = Math.atan2(b, a);
|
|
15183
|
+
h = hr * 360 / 2 / Math.PI;
|
|
15184
|
+
if (h < 0) {
|
|
15185
|
+
h += 360;
|
|
15186
|
+
}
|
|
15187
|
+
const c = Math.sqrt(a * a + b * b);
|
|
15188
|
+
return [l, c, h];
|
|
15189
|
+
};
|
|
15190
|
+
convert$1.lch.lab = function (lch) {
|
|
15191
|
+
const l = lch[0];
|
|
15192
|
+
const c = lch[1];
|
|
15193
|
+
const h = lch[2];
|
|
15194
|
+
const hr = h / 360 * 2 * Math.PI;
|
|
15195
|
+
const a = c * Math.cos(hr);
|
|
15196
|
+
const b = c * Math.sin(hr);
|
|
15197
|
+
return [l, a, b];
|
|
15198
|
+
};
|
|
15199
|
+
convert$1.rgb.ansi16 = function (args, saturation = null) {
|
|
15200
|
+
const [r, g, b] = args;
|
|
15201
|
+
let value = saturation === null ? convert$1.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization
|
|
15202
|
+
|
|
15203
|
+
value = Math.round(value / 50);
|
|
15204
|
+
if (value === 0) {
|
|
15205
|
+
return 30;
|
|
15206
|
+
}
|
|
15207
|
+
let ansi = 30
|
|
15208
|
+
/* eslint-disable no-bitwise */ + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
|
|
15209
|
+
/* eslint-enable no-bitwise */
|
|
15210
|
+
|
|
15211
|
+
if (value === 2) {
|
|
15212
|
+
ansi += 60;
|
|
15213
|
+
}
|
|
15214
|
+
return ansi;
|
|
15215
|
+
};
|
|
15216
|
+
convert$1.hsv.ansi16 = function (args) {
|
|
15217
|
+
// Optimization here; we already know the value and don't need to get
|
|
15218
|
+
// it converted for us.
|
|
15219
|
+
return convert$1.rgb.ansi16(convert$1.hsv.rgb(args), args[2]);
|
|
15220
|
+
};
|
|
15221
|
+
convert$1.rgb.ansi256 = function (args) {
|
|
15222
|
+
const r = args[0];
|
|
15223
|
+
const g = args[1];
|
|
15224
|
+
const b = args[2];
|
|
15225
|
+
|
|
15226
|
+
// We use the extended greyscale palette here, with the exception of
|
|
15227
|
+
// black and white. normal palette only has 4 greyscale shades.
|
|
15228
|
+
// eslint-disable-next-line no-bitwise
|
|
15229
|
+
if (r >> 4 === g >> 4 && g >> 4 === b >> 4) {
|
|
15230
|
+
if (r < 8) {
|
|
15231
|
+
return 16;
|
|
15232
|
+
}
|
|
15233
|
+
if (r > 248) {
|
|
15234
|
+
return 231;
|
|
15235
|
+
}
|
|
15236
|
+
return Math.round((r - 8) / 247 * 24) + 232;
|
|
15237
|
+
}
|
|
15238
|
+
const ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
|
|
15239
|
+
return ansi;
|
|
15240
|
+
};
|
|
15241
|
+
convert$1.ansi16.rgb = function (args) {
|
|
15242
|
+
args = args[0];
|
|
15243
|
+
let color = args % 10;
|
|
15244
|
+
|
|
15245
|
+
// Handle greyscale
|
|
15246
|
+
if (color === 0 || color === 7) {
|
|
15247
|
+
if (args > 50) {
|
|
15248
|
+
color += 3.5;
|
|
15249
|
+
}
|
|
15250
|
+
color = color / 10.5 * 255;
|
|
15251
|
+
return [color, color, color];
|
|
15252
|
+
}
|
|
15253
|
+
const mult = (Math.trunc(args > 50) + 1) * 0.5;
|
|
15254
|
+
/* eslint-disable no-bitwise */
|
|
15255
|
+
const r = (color & 1) * mult * 255;
|
|
15256
|
+
const g = (color >> 1 & 1) * mult * 255;
|
|
15257
|
+
const b = (color >> 2 & 1) * mult * 255;
|
|
15258
|
+
/* eslint-enable no-bitwise */
|
|
15259
|
+
|
|
15260
|
+
return [r, g, b];
|
|
15261
|
+
};
|
|
15262
|
+
convert$1.ansi256.rgb = function (args) {
|
|
15263
|
+
args = args[0];
|
|
15264
|
+
|
|
15265
|
+
// Handle greyscale
|
|
15266
|
+
if (args >= 232) {
|
|
15267
|
+
const c = (args - 232) * 10 + 8;
|
|
15268
|
+
return [c, c, c];
|
|
15269
|
+
}
|
|
15270
|
+
args -= 16;
|
|
15271
|
+
let rem;
|
|
15272
|
+
const r = Math.floor(args / 36) / 5 * 255;
|
|
15273
|
+
const g = Math.floor((rem = args % 36) / 6) / 5 * 255;
|
|
15274
|
+
const b = rem % 6 / 5 * 255;
|
|
15275
|
+
return [r, g, b];
|
|
15276
|
+
};
|
|
15277
|
+
convert$1.rgb.hex = function (args) {
|
|
15278
|
+
/* eslint-disable no-bitwise */
|
|
15279
|
+
const integer = ((Math.round(args[0]) & 0xFF) << 16) + ((Math.round(args[1]) & 0xFF) << 8) + (Math.round(args[2]) & 0xFF);
|
|
15280
|
+
/* eslint-enable no-bitwise */
|
|
15281
|
+
|
|
15282
|
+
const string = integer.toString(16).toUpperCase();
|
|
15283
|
+
return '000000'.slice(string.length) + string;
|
|
15284
|
+
};
|
|
15285
|
+
convert$1.hex.rgb = function (args) {
|
|
15286
|
+
const match = args.toString(16).match(/[a-f\d]{6}|[a-f\d]{3}/i);
|
|
15287
|
+
if (!match) {
|
|
15288
|
+
return [0, 0, 0];
|
|
15289
|
+
}
|
|
15290
|
+
let colorString = match[0];
|
|
15291
|
+
if (match[0].length === 3) {
|
|
15292
|
+
colorString = [...colorString].map(char => char + char).join('');
|
|
15293
|
+
}
|
|
15294
|
+
const integer = Number.parseInt(colorString, 16);
|
|
15295
|
+
/* eslint-disable no-bitwise */
|
|
15296
|
+
const r = integer >> 16 & 0xFF;
|
|
15297
|
+
const g = integer >> 8 & 0xFF;
|
|
15298
|
+
const b = integer & 0xFF;
|
|
15299
|
+
/* eslint-enable no-bitwise */
|
|
15300
|
+
|
|
15301
|
+
return [r, g, b];
|
|
15302
|
+
};
|
|
15303
|
+
convert$1.rgb.hcg = function (rgb) {
|
|
15304
|
+
const r = rgb[0] / 255;
|
|
15305
|
+
const g = rgb[1] / 255;
|
|
15306
|
+
const b = rgb[2] / 255;
|
|
15307
|
+
const max = Math.max(Math.max(r, g), b);
|
|
15308
|
+
const min = Math.min(Math.min(r, g), b);
|
|
15309
|
+
const chroma = max - min;
|
|
15310
|
+
let hue;
|
|
15311
|
+
const grayscale = chroma < 1 ? min / (1 - chroma) : 0;
|
|
15312
|
+
if (chroma <= 0) {
|
|
15313
|
+
hue = 0;
|
|
15314
|
+
} else if (max === r) {
|
|
15315
|
+
hue = (g - b) / chroma % 6;
|
|
15316
|
+
} else if (max === g) {
|
|
15317
|
+
hue = 2 + (b - r) / chroma;
|
|
15318
|
+
} else {
|
|
15319
|
+
hue = 4 + (r - g) / chroma;
|
|
15320
|
+
}
|
|
15321
|
+
hue /= 6;
|
|
15322
|
+
hue %= 1;
|
|
15323
|
+
return [hue * 360, chroma * 100, grayscale * 100];
|
|
15324
|
+
};
|
|
15325
|
+
convert$1.hsl.hcg = function (hsl) {
|
|
15326
|
+
const s = hsl[1] / 100;
|
|
15327
|
+
const l = hsl[2] / 100;
|
|
15328
|
+
const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
|
|
15329
|
+
let f = 0;
|
|
15330
|
+
if (c < 1) {
|
|
15331
|
+
f = (l - 0.5 * c) / (1 - c);
|
|
15332
|
+
}
|
|
15333
|
+
return [hsl[0], c * 100, f * 100];
|
|
15334
|
+
};
|
|
15335
|
+
convert$1.hsv.hcg = function (hsv) {
|
|
15336
|
+
const s = hsv[1] / 100;
|
|
15337
|
+
const v = hsv[2] / 100;
|
|
15338
|
+
const c = s * v;
|
|
15339
|
+
let f = 0;
|
|
15340
|
+
if (c < 1) {
|
|
15341
|
+
f = (v - c) / (1 - c);
|
|
15342
|
+
}
|
|
15343
|
+
return [hsv[0], c * 100, f * 100];
|
|
15344
|
+
};
|
|
15345
|
+
convert$1.hcg.rgb = function (hcg) {
|
|
15346
|
+
const h = hcg[0] / 360;
|
|
15347
|
+
const c = hcg[1] / 100;
|
|
15348
|
+
const g = hcg[2] / 100;
|
|
15349
|
+
if (c === 0) {
|
|
15350
|
+
return [g * 255, g * 255, g * 255];
|
|
15351
|
+
}
|
|
15352
|
+
const pure = [0, 0, 0];
|
|
15353
|
+
const hi = h % 1 * 6;
|
|
15354
|
+
const v = hi % 1;
|
|
15355
|
+
const w = 1 - v;
|
|
15356
|
+
let mg = 0;
|
|
15357
|
+
|
|
15358
|
+
/* eslint-disable max-statements-per-line */
|
|
15359
|
+
switch (Math.floor(hi)) {
|
|
15360
|
+
case 0:
|
|
15361
|
+
{
|
|
15362
|
+
pure[0] = 1;
|
|
15363
|
+
pure[1] = v;
|
|
15364
|
+
pure[2] = 0;
|
|
15365
|
+
break;
|
|
15366
|
+
}
|
|
15367
|
+
case 1:
|
|
15368
|
+
{
|
|
15369
|
+
pure[0] = w;
|
|
15370
|
+
pure[1] = 1;
|
|
15371
|
+
pure[2] = 0;
|
|
15372
|
+
break;
|
|
15373
|
+
}
|
|
15374
|
+
case 2:
|
|
15375
|
+
{
|
|
15376
|
+
pure[0] = 0;
|
|
15377
|
+
pure[1] = 1;
|
|
15378
|
+
pure[2] = v;
|
|
15379
|
+
break;
|
|
15380
|
+
}
|
|
15381
|
+
case 3:
|
|
15382
|
+
{
|
|
15383
|
+
pure[0] = 0;
|
|
15384
|
+
pure[1] = w;
|
|
15385
|
+
pure[2] = 1;
|
|
15386
|
+
break;
|
|
15387
|
+
}
|
|
15388
|
+
case 4:
|
|
15389
|
+
{
|
|
15390
|
+
pure[0] = v;
|
|
15391
|
+
pure[1] = 0;
|
|
15392
|
+
pure[2] = 1;
|
|
15393
|
+
break;
|
|
15394
|
+
}
|
|
15395
|
+
default:
|
|
15396
|
+
{
|
|
15397
|
+
pure[0] = 1;
|
|
15398
|
+
pure[1] = 0;
|
|
15399
|
+
pure[2] = w;
|
|
15400
|
+
}
|
|
15401
|
+
}
|
|
15402
|
+
/* eslint-enable max-statements-per-line */
|
|
15403
|
+
|
|
15404
|
+
mg = (1 - c) * g;
|
|
15405
|
+
return [(c * pure[0] + mg) * 255, (c * pure[1] + mg) * 255, (c * pure[2] + mg) * 255];
|
|
15406
|
+
};
|
|
15407
|
+
convert$1.hcg.hsv = function (hcg) {
|
|
15408
|
+
const c = hcg[1] / 100;
|
|
15409
|
+
const g = hcg[2] / 100;
|
|
15410
|
+
const v = c + g * (1 - c);
|
|
15411
|
+
let f = 0;
|
|
15412
|
+
if (v > 0) {
|
|
15413
|
+
f = c / v;
|
|
15414
|
+
}
|
|
15415
|
+
return [hcg[0], f * 100, v * 100];
|
|
15416
|
+
};
|
|
15417
|
+
convert$1.hcg.hsl = function (hcg) {
|
|
15418
|
+
const c = hcg[1] / 100;
|
|
15419
|
+
const g = hcg[2] / 100;
|
|
15420
|
+
const l = g * (1 - c) + 0.5 * c;
|
|
15421
|
+
let s = 0;
|
|
15422
|
+
if (l > 0 && l < 0.5) {
|
|
15423
|
+
s = c / (2 * l);
|
|
15424
|
+
} else if (l >= 0.5 && l < 1) {
|
|
15425
|
+
s = c / (2 * (1 - l));
|
|
15426
|
+
}
|
|
15427
|
+
return [hcg[0], s * 100, l * 100];
|
|
15428
|
+
};
|
|
15429
|
+
convert$1.hcg.hwb = function (hcg) {
|
|
15430
|
+
const c = hcg[1] / 100;
|
|
15431
|
+
const g = hcg[2] / 100;
|
|
15432
|
+
const v = c + g * (1 - c);
|
|
15433
|
+
return [hcg[0], (v - c) * 100, (1 - v) * 100];
|
|
15434
|
+
};
|
|
15435
|
+
convert$1.hwb.hcg = function (hwb) {
|
|
15436
|
+
const w = hwb[1] / 100;
|
|
15437
|
+
const b = hwb[2] / 100;
|
|
15438
|
+
const v = 1 - b;
|
|
15439
|
+
const c = v - w;
|
|
15440
|
+
let g = 0;
|
|
15441
|
+
if (c < 1) {
|
|
15442
|
+
g = (v - c) / (1 - c);
|
|
15443
|
+
}
|
|
15444
|
+
return [hwb[0], c * 100, g * 100];
|
|
15445
|
+
};
|
|
15446
|
+
convert$1.apple.rgb = function (apple) {
|
|
15447
|
+
return [apple[0] / 65_535 * 255, apple[1] / 65_535 * 255, apple[2] / 65_535 * 255];
|
|
15448
|
+
};
|
|
15449
|
+
convert$1.rgb.apple = function (rgb) {
|
|
15450
|
+
return [rgb[0] / 255 * 65_535, rgb[1] / 255 * 65_535, rgb[2] / 255 * 65_535];
|
|
15451
|
+
};
|
|
15452
|
+
convert$1.gray.rgb = function (args) {
|
|
15453
|
+
return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
|
|
15454
|
+
};
|
|
15455
|
+
convert$1.gray.hsl = function (args) {
|
|
15456
|
+
return [0, 0, args[0]];
|
|
15457
|
+
};
|
|
15458
|
+
convert$1.gray.hsv = convert$1.gray.hsl;
|
|
15459
|
+
convert$1.gray.hwb = function (gray) {
|
|
15460
|
+
return [0, 100, gray[0]];
|
|
15461
|
+
};
|
|
15462
|
+
convert$1.gray.cmyk = function (gray) {
|
|
15463
|
+
return [0, 0, 0, gray[0]];
|
|
15464
|
+
};
|
|
15465
|
+
convert$1.gray.lab = function (gray) {
|
|
15466
|
+
return [gray[0], 0, 0];
|
|
15467
|
+
};
|
|
15468
|
+
convert$1.gray.hex = function (gray) {
|
|
15469
|
+
/* eslint-disable no-bitwise */
|
|
15470
|
+
const value = Math.round(gray[0] / 100 * 255) & 0xFF;
|
|
15471
|
+
const integer = (value << 16) + (value << 8) + value;
|
|
15472
|
+
/* eslint-enable no-bitwise */
|
|
15473
|
+
|
|
15474
|
+
const string = integer.toString(16).toUpperCase();
|
|
15475
|
+
return '000000'.slice(string.length) + string;
|
|
15476
|
+
};
|
|
15477
|
+
convert$1.rgb.gray = function (rgb) {
|
|
15478
|
+
const value = (rgb[0] + rgb[1] + rgb[2]) / 3;
|
|
15479
|
+
return [value / 255 * 100];
|
|
15480
|
+
};
|
|
15481
|
+
|
|
15482
|
+
/*
|
|
15483
|
+
This function routes a model to all other models.
|
|
15484
|
+
|
|
15485
|
+
all functions that are routed have a property `.conversion` attached
|
|
15486
|
+
to the returned synthetic function. This property is an array
|
|
15487
|
+
of strings, each with the steps in between the 'from' and 'to'
|
|
15488
|
+
color models (inclusive).
|
|
15489
|
+
|
|
15490
|
+
conversions that are not possible simply are not included.
|
|
15491
|
+
*/
|
|
15492
|
+
|
|
15493
|
+
function buildGraph() {
|
|
15494
|
+
const graph = {};
|
|
15495
|
+
// https://jsperf.com/object-keys-vs-for-in-with-closure/3
|
|
15496
|
+
const models = Object.keys(convert$1);
|
|
15497
|
+
for (let {
|
|
15498
|
+
length
|
|
15499
|
+
} = models, i = 0; i < length; i++) {
|
|
15500
|
+
graph[models[i]] = {
|
|
15501
|
+
// http://jsperf.com/1-vs-infinity
|
|
15502
|
+
// micro-opt, but this is simple.
|
|
15503
|
+
distance: -1,
|
|
15504
|
+
parent: null
|
|
15505
|
+
};
|
|
15506
|
+
}
|
|
15507
|
+
return graph;
|
|
15508
|
+
}
|
|
15509
|
+
|
|
15510
|
+
// https://en.wikipedia.org/wiki/Breadth-first_search
|
|
15511
|
+
function deriveBFS(fromModel) {
|
|
15512
|
+
const graph = buildGraph();
|
|
15513
|
+
const queue = [fromModel]; // Unshift -> queue -> pop
|
|
15514
|
+
|
|
15515
|
+
graph[fromModel].distance = 0;
|
|
15516
|
+
while (queue.length > 0) {
|
|
15517
|
+
const current = queue.pop();
|
|
15518
|
+
const adjacents = Object.keys(convert$1[current]);
|
|
15519
|
+
for (let {
|
|
15520
|
+
length
|
|
15521
|
+
} = adjacents, i = 0; i < length; i++) {
|
|
15522
|
+
const adjacent = adjacents[i];
|
|
15523
|
+
const node = graph[adjacent];
|
|
15524
|
+
if (node.distance === -1) {
|
|
15525
|
+
node.distance = graph[current].distance + 1;
|
|
15526
|
+
node.parent = current;
|
|
15527
|
+
queue.unshift(adjacent);
|
|
15528
|
+
}
|
|
15529
|
+
}
|
|
15530
|
+
}
|
|
15531
|
+
return graph;
|
|
15532
|
+
}
|
|
15533
|
+
function link(from, to) {
|
|
15534
|
+
return function (args) {
|
|
15535
|
+
return to(from(args));
|
|
15536
|
+
};
|
|
15537
|
+
}
|
|
15538
|
+
function wrapConversion(toModel, graph) {
|
|
15539
|
+
const path = [graph[toModel].parent, toModel];
|
|
15540
|
+
let fn = convert$1[graph[toModel].parent][toModel];
|
|
15541
|
+
let cur = graph[toModel].parent;
|
|
15542
|
+
while (graph[cur].parent) {
|
|
15543
|
+
path.unshift(graph[cur].parent);
|
|
15544
|
+
fn = link(convert$1[graph[cur].parent][cur], fn);
|
|
15545
|
+
cur = graph[cur].parent;
|
|
15546
|
+
}
|
|
15547
|
+
fn.conversion = path;
|
|
15548
|
+
return fn;
|
|
15549
|
+
}
|
|
15550
|
+
function route(fromModel) {
|
|
15551
|
+
const graph = deriveBFS(fromModel);
|
|
15552
|
+
const conversion = {};
|
|
15553
|
+
const models = Object.keys(graph);
|
|
15554
|
+
for (let {
|
|
15555
|
+
length
|
|
15556
|
+
} = models, i = 0; i < length; i++) {
|
|
15557
|
+
const toModel = models[i];
|
|
15558
|
+
const node = graph[toModel];
|
|
15559
|
+
if (node.parent === null) {
|
|
15560
|
+
// No possible conversion, or this node is the source model.
|
|
15561
|
+
continue;
|
|
15562
|
+
}
|
|
15563
|
+
conversion[toModel] = wrapConversion(toModel, graph);
|
|
15564
|
+
}
|
|
15565
|
+
return conversion;
|
|
15566
|
+
}
|
|
15567
|
+
|
|
15568
|
+
const convert = {};
|
|
15569
|
+
const models = Object.keys(convert$1);
|
|
15570
|
+
function wrapRaw(fn) {
|
|
15571
|
+
const wrappedFn = function (...args) {
|
|
15572
|
+
const arg0 = args[0];
|
|
15573
|
+
if (arg0 === undefined || arg0 === null) {
|
|
15574
|
+
return arg0;
|
|
15575
|
+
}
|
|
15576
|
+
if (arg0.length > 1) {
|
|
15577
|
+
args = arg0;
|
|
15578
|
+
}
|
|
15579
|
+
return fn(args);
|
|
15580
|
+
};
|
|
15581
|
+
|
|
15582
|
+
// Preserve .conversion property if there is one
|
|
15583
|
+
if ('conversion' in fn) {
|
|
15584
|
+
wrappedFn.conversion = fn.conversion;
|
|
15585
|
+
}
|
|
15586
|
+
return wrappedFn;
|
|
15587
|
+
}
|
|
15588
|
+
function wrapRounded(fn) {
|
|
15589
|
+
const wrappedFn = function (...args) {
|
|
15590
|
+
const arg0 = args[0];
|
|
15591
|
+
if (arg0 === undefined || arg0 === null) {
|
|
15592
|
+
return arg0;
|
|
15593
|
+
}
|
|
15594
|
+
if (arg0.length > 1) {
|
|
15595
|
+
args = arg0;
|
|
15596
|
+
}
|
|
15597
|
+
const result = fn(args);
|
|
15598
|
+
|
|
15599
|
+
// We're assuming the result is an array here.
|
|
15600
|
+
// see notice in conversions.js; don't use box types
|
|
15601
|
+
// in conversion functions.
|
|
15602
|
+
if (typeof result === 'object') {
|
|
15603
|
+
for (let {
|
|
15604
|
+
length
|
|
15605
|
+
} = result, i = 0; i < length; i++) {
|
|
15606
|
+
result[i] = Math.round(result[i]);
|
|
15607
|
+
}
|
|
15608
|
+
}
|
|
15609
|
+
return result;
|
|
15610
|
+
};
|
|
15611
|
+
|
|
15612
|
+
// Preserve .conversion property if there is one
|
|
15613
|
+
if ('conversion' in fn) {
|
|
15614
|
+
wrappedFn.conversion = fn.conversion;
|
|
15615
|
+
}
|
|
15616
|
+
return wrappedFn;
|
|
15617
|
+
}
|
|
15618
|
+
for (const fromModel of models) {
|
|
15619
|
+
convert[fromModel] = {};
|
|
15620
|
+
Object.defineProperty(convert[fromModel], 'channels', {
|
|
15621
|
+
value: convert$1[fromModel].channels
|
|
15622
|
+
});
|
|
15623
|
+
Object.defineProperty(convert[fromModel], 'labels', {
|
|
15624
|
+
value: convert$1[fromModel].labels
|
|
15625
|
+
});
|
|
15626
|
+
const routes = route(fromModel);
|
|
15627
|
+
const routeModels = Object.keys(routes);
|
|
15628
|
+
for (const toModel of routeModels) {
|
|
15629
|
+
const fn = routes[toModel];
|
|
15630
|
+
convert[fromModel][toModel] = wrapRounded(fn);
|
|
15631
|
+
convert[fromModel][toModel].raw = wrapRaw(fn);
|
|
15632
|
+
}
|
|
15633
|
+
}
|
|
15634
|
+
|
|
15635
|
+
const skippedModels = [
|
|
15636
|
+
// To be honest, I don't really feel like keyword belongs in color convert, but eh.
|
|
15637
|
+
'keyword',
|
|
15638
|
+
// Gray conflicts with some method names, and has its own method defined.
|
|
15639
|
+
'gray',
|
|
15640
|
+
// Shouldn't really be in color-convert either...
|
|
15641
|
+
'hex'];
|
|
15642
|
+
const hashedModelKeys = {};
|
|
15643
|
+
for (const model of Object.keys(convert)) {
|
|
15644
|
+
hashedModelKeys[[...convert[model].labels].sort().join('')] = model;
|
|
15645
|
+
}
|
|
15646
|
+
const limiters = {};
|
|
15647
|
+
function Color(object, model) {
|
|
15648
|
+
if (!(this instanceof Color)) {
|
|
15649
|
+
return new Color(object, model);
|
|
15650
|
+
}
|
|
15651
|
+
if (model && model in skippedModels) {
|
|
15652
|
+
model = null;
|
|
15653
|
+
}
|
|
15654
|
+
if (model && !(model in convert)) {
|
|
15655
|
+
throw new Error('Unknown model: ' + model);
|
|
15656
|
+
}
|
|
15657
|
+
let i;
|
|
15658
|
+
let channels;
|
|
15659
|
+
if (object == null) {
|
|
15660
|
+
// eslint-disable-line no-eq-null,eqeqeq
|
|
15661
|
+
this.model = 'rgb';
|
|
15662
|
+
this.color = [0, 0, 0];
|
|
15663
|
+
this.valpha = 1;
|
|
15664
|
+
} else if (object instanceof Color) {
|
|
15665
|
+
this.model = object.model;
|
|
15666
|
+
this.color = [...object.color];
|
|
15667
|
+
this.valpha = object.valpha;
|
|
15668
|
+
} else if (typeof object === 'string') {
|
|
15669
|
+
const result = cs.get(object);
|
|
15670
|
+
if (result === null) {
|
|
15671
|
+
throw new Error('Unable to parse color from string: ' + object);
|
|
15672
|
+
}
|
|
15673
|
+
this.model = result.model;
|
|
15674
|
+
channels = convert[this.model].channels;
|
|
15675
|
+
this.color = result.value.slice(0, channels);
|
|
15676
|
+
this.valpha = typeof result.value[channels] === 'number' ? result.value[channels] : 1;
|
|
15677
|
+
} else if (object.length > 0) {
|
|
15678
|
+
this.model = model || 'rgb';
|
|
15679
|
+
channels = convert[this.model].channels;
|
|
15680
|
+
const newArray = Array.prototype.slice.call(object, 0, channels);
|
|
15681
|
+
this.color = zeroArray(newArray, channels);
|
|
15682
|
+
this.valpha = typeof object[channels] === 'number' ? object[channels] : 1;
|
|
15683
|
+
} else if (typeof object === 'number') {
|
|
15684
|
+
// This is always RGB - can be converted later on.
|
|
15685
|
+
this.model = 'rgb';
|
|
15686
|
+
this.color = [object >> 16 & 0xFF, object >> 8 & 0xFF, object & 0xFF];
|
|
15687
|
+
this.valpha = 1;
|
|
15688
|
+
} else {
|
|
15689
|
+
this.valpha = 1;
|
|
15690
|
+
const keys = Object.keys(object);
|
|
15691
|
+
if ('alpha' in object) {
|
|
15692
|
+
keys.splice(keys.indexOf('alpha'), 1);
|
|
15693
|
+
this.valpha = typeof object.alpha === 'number' ? object.alpha : 0;
|
|
15694
|
+
}
|
|
15695
|
+
const hashedKeys = keys.sort().join('');
|
|
15696
|
+
if (!(hashedKeys in hashedModelKeys)) {
|
|
15697
|
+
throw new Error('Unable to parse color from object: ' + JSON.stringify(object));
|
|
15698
|
+
}
|
|
15699
|
+
this.model = hashedModelKeys[hashedKeys];
|
|
15700
|
+
const {
|
|
15701
|
+
labels
|
|
15702
|
+
} = convert[this.model];
|
|
15703
|
+
const color = [];
|
|
15704
|
+
for (i = 0; i < labels.length; i++) {
|
|
15705
|
+
color.push(object[labels[i]]);
|
|
15706
|
+
}
|
|
15707
|
+
this.color = zeroArray(color);
|
|
15708
|
+
}
|
|
15709
|
+
|
|
15710
|
+
// Perform limitations (clamping, etc.)
|
|
15711
|
+
if (limiters[this.model]) {
|
|
15712
|
+
channels = convert[this.model].channels;
|
|
15713
|
+
for (i = 0; i < channels; i++) {
|
|
15714
|
+
const limit = limiters[this.model][i];
|
|
15715
|
+
if (limit) {
|
|
15716
|
+
this.color[i] = limit(this.color[i]);
|
|
15717
|
+
}
|
|
15718
|
+
}
|
|
15719
|
+
}
|
|
15720
|
+
this.valpha = Math.max(0, Math.min(1, this.valpha));
|
|
15721
|
+
if (Object.freeze) {
|
|
15722
|
+
Object.freeze(this);
|
|
15723
|
+
}
|
|
15724
|
+
}
|
|
15725
|
+
Color.prototype = {
|
|
15726
|
+
toString() {
|
|
15727
|
+
return this.string();
|
|
15728
|
+
},
|
|
15729
|
+
toJSON() {
|
|
15730
|
+
return this[this.model]();
|
|
15731
|
+
},
|
|
15732
|
+
string(places) {
|
|
15733
|
+
let self = this.model in cs.to ? this : this.rgb();
|
|
15734
|
+
self = self.round(typeof places === 'number' ? places : 1);
|
|
15735
|
+
const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha];
|
|
15736
|
+
return cs.to[self.model](...arguments_);
|
|
15737
|
+
},
|
|
15738
|
+
percentString(places) {
|
|
15739
|
+
const self = this.rgb().round(typeof places === 'number' ? places : 1);
|
|
15740
|
+
const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha];
|
|
15741
|
+
return cs.to.rgb.percent(...arguments_);
|
|
15742
|
+
},
|
|
15743
|
+
array() {
|
|
15744
|
+
return this.valpha === 1 ? [...this.color] : [...this.color, this.valpha];
|
|
15745
|
+
},
|
|
15746
|
+
object() {
|
|
15747
|
+
const result = {};
|
|
15748
|
+
const {
|
|
15749
|
+
channels
|
|
15750
|
+
} = convert[this.model];
|
|
15751
|
+
const {
|
|
15752
|
+
labels
|
|
15753
|
+
} = convert[this.model];
|
|
15754
|
+
for (let i = 0; i < channels; i++) {
|
|
15755
|
+
result[labels[i]] = this.color[i];
|
|
15756
|
+
}
|
|
15757
|
+
if (this.valpha !== 1) {
|
|
15758
|
+
result.alpha = this.valpha;
|
|
15759
|
+
}
|
|
15760
|
+
return result;
|
|
15761
|
+
},
|
|
15762
|
+
unitArray() {
|
|
15763
|
+
const rgb = this.rgb().color;
|
|
15764
|
+
rgb[0] /= 255;
|
|
15765
|
+
rgb[1] /= 255;
|
|
15766
|
+
rgb[2] /= 255;
|
|
15767
|
+
if (this.valpha !== 1) {
|
|
15768
|
+
rgb.push(this.valpha);
|
|
15769
|
+
}
|
|
15770
|
+
return rgb;
|
|
15771
|
+
},
|
|
15772
|
+
unitObject() {
|
|
15773
|
+
const rgb = this.rgb().object();
|
|
15774
|
+
rgb.r /= 255;
|
|
15775
|
+
rgb.g /= 255;
|
|
15776
|
+
rgb.b /= 255;
|
|
15777
|
+
if (this.valpha !== 1) {
|
|
15778
|
+
rgb.alpha = this.valpha;
|
|
15779
|
+
}
|
|
15780
|
+
return rgb;
|
|
15781
|
+
},
|
|
15782
|
+
round(places) {
|
|
15783
|
+
places = Math.max(places || 0, 0);
|
|
15784
|
+
return new Color([...this.color.map(roundToPlace(places)), this.valpha], this.model);
|
|
15785
|
+
},
|
|
15786
|
+
alpha(value) {
|
|
15787
|
+
if (value !== undefined) {
|
|
15788
|
+
return new Color([...this.color, Math.max(0, Math.min(1, value))], this.model);
|
|
15789
|
+
}
|
|
15790
|
+
return this.valpha;
|
|
15791
|
+
},
|
|
15792
|
+
// Rgb
|
|
15793
|
+
red: getset('rgb', 0, maxfn(255)),
|
|
15794
|
+
green: getset('rgb', 1, maxfn(255)),
|
|
15795
|
+
blue: getset('rgb', 2, maxfn(255)),
|
|
15796
|
+
hue: getset(['hsl', 'hsv', 'hsl', 'hwb', 'hcg'], 0, value => (value % 360 + 360) % 360),
|
|
15797
|
+
saturationl: getset('hsl', 1, maxfn(100)),
|
|
15798
|
+
lightness: getset('hsl', 2, maxfn(100)),
|
|
15799
|
+
saturationv: getset('hsv', 1, maxfn(100)),
|
|
15800
|
+
value: getset('hsv', 2, maxfn(100)),
|
|
15801
|
+
chroma: getset('hcg', 1, maxfn(100)),
|
|
15802
|
+
gray: getset('hcg', 2, maxfn(100)),
|
|
15803
|
+
white: getset('hwb', 1, maxfn(100)),
|
|
15804
|
+
wblack: getset('hwb', 2, maxfn(100)),
|
|
15805
|
+
cyan: getset('cmyk', 0, maxfn(100)),
|
|
15806
|
+
magenta: getset('cmyk', 1, maxfn(100)),
|
|
15807
|
+
yellow: getset('cmyk', 2, maxfn(100)),
|
|
15808
|
+
black: getset('cmyk', 3, maxfn(100)),
|
|
15809
|
+
x: getset('xyz', 0, maxfn(95.047)),
|
|
15810
|
+
y: getset('xyz', 1, maxfn(100)),
|
|
15811
|
+
z: getset('xyz', 2, maxfn(108.833)),
|
|
15812
|
+
l: getset('lab', 0, maxfn(100)),
|
|
15813
|
+
a: getset('lab', 1),
|
|
15814
|
+
b: getset('lab', 2),
|
|
15815
|
+
keyword(value) {
|
|
15816
|
+
if (value !== undefined) {
|
|
15817
|
+
return new Color(value);
|
|
15818
|
+
}
|
|
15819
|
+
return convert[this.model].keyword(this.color);
|
|
15820
|
+
},
|
|
15821
|
+
hex(value) {
|
|
15822
|
+
if (value !== undefined) {
|
|
15823
|
+
return new Color(value);
|
|
15824
|
+
}
|
|
15825
|
+
return cs.to.hex(...this.rgb().round().color);
|
|
15826
|
+
},
|
|
15827
|
+
hexa(value) {
|
|
15828
|
+
if (value !== undefined) {
|
|
15829
|
+
return new Color(value);
|
|
15830
|
+
}
|
|
15831
|
+
const rgbArray = this.rgb().round().color;
|
|
15832
|
+
let alphaHex = Math.round(this.valpha * 255).toString(16).toUpperCase();
|
|
15833
|
+
if (alphaHex.length === 1) {
|
|
15834
|
+
alphaHex = '0' + alphaHex;
|
|
15835
|
+
}
|
|
15836
|
+
return cs.to.hex(...rgbArray) + alphaHex;
|
|
15837
|
+
},
|
|
15838
|
+
rgbNumber() {
|
|
15839
|
+
const rgb = this.rgb().color;
|
|
15840
|
+
return (rgb[0] & 0xFF) << 16 | (rgb[1] & 0xFF) << 8 | rgb[2] & 0xFF;
|
|
15841
|
+
},
|
|
15842
|
+
luminosity() {
|
|
15843
|
+
// http://www.w3.org/TR/WCAG20/#relativeluminancedef
|
|
15844
|
+
const rgb = this.rgb().color;
|
|
15845
|
+
const lum = [];
|
|
15846
|
+
for (const [i, element] of rgb.entries()) {
|
|
15847
|
+
const chan = element / 255;
|
|
15848
|
+
lum[i] = chan <= 0.04045 ? chan / 12.92 : ((chan + 0.055) / 1.055) ** 2.4;
|
|
15849
|
+
}
|
|
15850
|
+
return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
|
|
15851
|
+
},
|
|
15852
|
+
contrast(color2) {
|
|
15853
|
+
// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
|
15854
|
+
const lum1 = this.luminosity();
|
|
15855
|
+
const lum2 = color2.luminosity();
|
|
15856
|
+
if (lum1 > lum2) {
|
|
15857
|
+
return (lum1 + 0.05) / (lum2 + 0.05);
|
|
15858
|
+
}
|
|
15859
|
+
return (lum2 + 0.05) / (lum1 + 0.05);
|
|
15860
|
+
},
|
|
15861
|
+
level(color2) {
|
|
15862
|
+
// https://www.w3.org/TR/WCAG/#contrast-enhanced
|
|
15863
|
+
const contrastRatio = this.contrast(color2);
|
|
15864
|
+
if (contrastRatio >= 7) {
|
|
15865
|
+
return 'AAA';
|
|
15866
|
+
}
|
|
15867
|
+
return contrastRatio >= 4.5 ? 'AA' : '';
|
|
15868
|
+
},
|
|
15869
|
+
isDark() {
|
|
15870
|
+
// YIQ equation from http://24ways.org/2010/calculating-color-contrast
|
|
15871
|
+
const rgb = this.rgb().color;
|
|
15872
|
+
const yiq = (rgb[0] * 2126 + rgb[1] * 7152 + rgb[2] * 722) / 10000;
|
|
15873
|
+
return yiq < 128;
|
|
15874
|
+
},
|
|
15875
|
+
isLight() {
|
|
15876
|
+
return !this.isDark();
|
|
15877
|
+
},
|
|
15878
|
+
negate() {
|
|
15879
|
+
const rgb = this.rgb();
|
|
15880
|
+
for (let i = 0; i < 3; i++) {
|
|
15881
|
+
rgb.color[i] = 255 - rgb.color[i];
|
|
15882
|
+
}
|
|
15883
|
+
return rgb;
|
|
15884
|
+
},
|
|
15885
|
+
lighten(ratio) {
|
|
15886
|
+
const hsl = this.hsl();
|
|
15887
|
+
hsl.color[2] += hsl.color[2] * ratio;
|
|
15888
|
+
return hsl;
|
|
15889
|
+
},
|
|
15890
|
+
darken(ratio) {
|
|
15891
|
+
const hsl = this.hsl();
|
|
15892
|
+
hsl.color[2] -= hsl.color[2] * ratio;
|
|
15893
|
+
return hsl;
|
|
15894
|
+
},
|
|
15895
|
+
saturate(ratio) {
|
|
15896
|
+
const hsl = this.hsl();
|
|
15897
|
+
hsl.color[1] += hsl.color[1] * ratio;
|
|
15898
|
+
return hsl;
|
|
15899
|
+
},
|
|
15900
|
+
desaturate(ratio) {
|
|
15901
|
+
const hsl = this.hsl();
|
|
15902
|
+
hsl.color[1] -= hsl.color[1] * ratio;
|
|
15903
|
+
return hsl;
|
|
15904
|
+
},
|
|
15905
|
+
whiten(ratio) {
|
|
15906
|
+
const hwb = this.hwb();
|
|
15907
|
+
hwb.color[1] += hwb.color[1] * ratio;
|
|
15908
|
+
return hwb;
|
|
15909
|
+
},
|
|
15910
|
+
blacken(ratio) {
|
|
15911
|
+
const hwb = this.hwb();
|
|
15912
|
+
hwb.color[2] += hwb.color[2] * ratio;
|
|
15913
|
+
return hwb;
|
|
15914
|
+
},
|
|
15915
|
+
grayscale() {
|
|
15916
|
+
// http://en.wikipedia.org/wiki/Grayscale#Converting_colour_to_grayscale
|
|
15917
|
+
const rgb = this.rgb().color;
|
|
15918
|
+
const value = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
|
|
15919
|
+
return Color.rgb(value, value, value);
|
|
15920
|
+
},
|
|
15921
|
+
fade(ratio) {
|
|
15922
|
+
return this.alpha(this.valpha - this.valpha * ratio);
|
|
15923
|
+
},
|
|
15924
|
+
opaquer(ratio) {
|
|
15925
|
+
return this.alpha(this.valpha + this.valpha * ratio);
|
|
15926
|
+
},
|
|
15927
|
+
rotate(degrees) {
|
|
15928
|
+
const hsl = this.hsl();
|
|
15929
|
+
let hue = hsl.color[0];
|
|
15930
|
+
hue = (hue + degrees) % 360;
|
|
15931
|
+
hue = hue < 0 ? 360 + hue : hue;
|
|
15932
|
+
hsl.color[0] = hue;
|
|
15933
|
+
return hsl;
|
|
15934
|
+
},
|
|
15935
|
+
mix(mixinColor, weight) {
|
|
15936
|
+
// Ported from sass implementation in C
|
|
15937
|
+
// https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
|
|
15938
|
+
if (!mixinColor || !mixinColor.rgb) {
|
|
15939
|
+
throw new Error('Argument to "mix" was not a Color instance, but rather an instance of ' + typeof mixinColor);
|
|
15940
|
+
}
|
|
15941
|
+
const color1 = mixinColor.rgb();
|
|
15942
|
+
const color2 = this.rgb();
|
|
15943
|
+
const p = weight === undefined ? 0.5 : weight;
|
|
15944
|
+
const w = 2 * p - 1;
|
|
15945
|
+
const a = color1.alpha() - color2.alpha();
|
|
15946
|
+
const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2;
|
|
15947
|
+
const w2 = 1 - w1;
|
|
15948
|
+
return Color.rgb(w1 * color1.red() + w2 * color2.red(), w1 * color1.green() + w2 * color2.green(), w1 * color1.blue() + w2 * color2.blue(), color1.alpha() * p + color2.alpha() * (1 - p));
|
|
15949
|
+
}
|
|
15950
|
+
};
|
|
15951
|
+
|
|
15952
|
+
// Model conversion methods and static constructors
|
|
15953
|
+
for (const model of Object.keys(convert)) {
|
|
15954
|
+
if (skippedModels.includes(model)) {
|
|
15955
|
+
continue;
|
|
15956
|
+
}
|
|
15957
|
+
const {
|
|
15958
|
+
channels
|
|
15959
|
+
} = convert[model];
|
|
15960
|
+
|
|
15961
|
+
// Conversion methods
|
|
15962
|
+
Color.prototype[model] = function (...arguments_) {
|
|
15963
|
+
if (this.model === model) {
|
|
15964
|
+
return new Color(this);
|
|
15965
|
+
}
|
|
15966
|
+
if (arguments_.length > 0) {
|
|
15967
|
+
return new Color(arguments_, model);
|
|
15968
|
+
}
|
|
15969
|
+
return new Color([...assertArray(convert[this.model][model].raw(this.color)), this.valpha], model);
|
|
15970
|
+
};
|
|
15971
|
+
|
|
15972
|
+
// 'static' construction methods
|
|
15973
|
+
Color[model] = function (...arguments_) {
|
|
15974
|
+
let color = arguments_[0];
|
|
15975
|
+
if (typeof color === 'number') {
|
|
15976
|
+
color = zeroArray(arguments_, channels);
|
|
15977
|
+
}
|
|
15978
|
+
return new Color(color, model);
|
|
15979
|
+
};
|
|
15980
|
+
}
|
|
15981
|
+
function roundTo(number, places) {
|
|
15982
|
+
return Number(number.toFixed(places));
|
|
15983
|
+
}
|
|
15984
|
+
function roundToPlace(places) {
|
|
15985
|
+
return function (number) {
|
|
15986
|
+
return roundTo(number, places);
|
|
15987
|
+
};
|
|
15988
|
+
}
|
|
15989
|
+
function getset(model, channel, modifier) {
|
|
15990
|
+
model = Array.isArray(model) ? model : [model];
|
|
15991
|
+
for (const m of model) {
|
|
15992
|
+
(limiters[m] ||= [])[channel] = modifier;
|
|
15993
|
+
}
|
|
15994
|
+
model = model[0];
|
|
15995
|
+
return function (value) {
|
|
15996
|
+
let result;
|
|
15997
|
+
if (value !== undefined) {
|
|
15998
|
+
if (modifier) {
|
|
15999
|
+
value = modifier(value);
|
|
16000
|
+
}
|
|
16001
|
+
result = this[model]();
|
|
16002
|
+
result.color[channel] = value;
|
|
16003
|
+
return result;
|
|
16004
|
+
}
|
|
16005
|
+
result = this[model]().color[channel];
|
|
16006
|
+
if (modifier) {
|
|
16007
|
+
result = modifier(result);
|
|
16008
|
+
}
|
|
16009
|
+
return result;
|
|
16010
|
+
};
|
|
16011
|
+
}
|
|
16012
|
+
function maxfn(max) {
|
|
16013
|
+
return function (v) {
|
|
16014
|
+
return Math.max(0, Math.min(max, v));
|
|
16015
|
+
};
|
|
16016
|
+
}
|
|
16017
|
+
function assertArray(value) {
|
|
16018
|
+
return Array.isArray(value) ? value : [value];
|
|
16019
|
+
}
|
|
16020
|
+
function zeroArray(array, length) {
|
|
16021
|
+
for (let i = 0; i < length; i++) {
|
|
16022
|
+
if (typeof array[i] !== 'number') {
|
|
16023
|
+
array[i] = 0;
|
|
16024
|
+
}
|
|
16025
|
+
}
|
|
16026
|
+
return array;
|
|
16027
|
+
}
|
|
16028
|
+
|
|
16029
|
+
/*
|
|
16030
|
+
ROCSpace element
|
|
16031
|
+
<roc-space>
|
|
16032
|
+
|
|
16033
|
+
Attributes:
|
|
16034
|
+
FAR; HR;
|
|
16035
|
+
d'; C; zFAR; zHR
|
|
16036
|
+
|
|
16037
|
+
draggable: yes/no
|
|
16038
|
+
|
|
16039
|
+
scale: FAR/HR; zFAR/zHR; d'/C
|
|
16040
|
+
grid: FAR/HR; zFAR/zHR; d'/C
|
|
16041
|
+
isos: d'; C; FAR; HR
|
|
16042
|
+
|
|
16043
|
+
Styles:
|
|
16044
|
+
??
|
|
16045
|
+
*/
|
|
16046
|
+
class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
|
|
16047
|
+
static get properties() {
|
|
16048
|
+
return {
|
|
16049
|
+
contour: {
|
|
16050
|
+
attribute: 'contour',
|
|
16051
|
+
type: String,
|
|
16052
|
+
reflect: true
|
|
16053
|
+
},
|
|
16054
|
+
point: {
|
|
16055
|
+
attribute: 'point',
|
|
16056
|
+
type: String,
|
|
16057
|
+
reflect: true
|
|
16058
|
+
},
|
|
16059
|
+
isoD: {
|
|
16060
|
+
attribute: 'iso-d',
|
|
16061
|
+
type: String,
|
|
16062
|
+
reflect: true
|
|
16063
|
+
},
|
|
16064
|
+
isoC: {
|
|
16065
|
+
attribute: 'iso-c',
|
|
16066
|
+
type: String,
|
|
16067
|
+
reflect: true
|
|
16068
|
+
},
|
|
16069
|
+
zRoc: {
|
|
16070
|
+
attribute: 'z-roc',
|
|
16071
|
+
type: Boolean,
|
|
16072
|
+
reflect: true
|
|
16073
|
+
},
|
|
16074
|
+
far: {
|
|
16075
|
+
attribute: 'far',
|
|
16076
|
+
type: Number,
|
|
16077
|
+
reflect: true
|
|
16078
|
+
},
|
|
16079
|
+
hr: {
|
|
16080
|
+
attribute: 'hr',
|
|
16081
|
+
type: Number,
|
|
16082
|
+
reflect: true
|
|
16083
|
+
},
|
|
16084
|
+
d: {
|
|
16085
|
+
attribute: false,
|
|
16086
|
+
type: Number,
|
|
16087
|
+
reflect: false
|
|
16088
|
+
},
|
|
16089
|
+
c: {
|
|
16090
|
+
attribute: false,
|
|
16091
|
+
type: Number,
|
|
16092
|
+
reflect: false
|
|
16093
|
+
},
|
|
16094
|
+
s: {
|
|
16095
|
+
attribute: false,
|
|
16096
|
+
type: Number,
|
|
16097
|
+
reflect: false
|
|
16098
|
+
}
|
|
16099
|
+
};
|
|
16100
|
+
}
|
|
16101
|
+
constructor() {
|
|
16102
|
+
super();
|
|
16103
|
+
this.firstUpdate = true;
|
|
16104
|
+
this.drag = false;
|
|
16105
|
+
this.sdt = false;
|
|
16106
|
+
this.contours = ['sensitivity', 'bias', 'accuracy'];
|
|
16107
|
+
this.contour = undefined;
|
|
16108
|
+
this.points = ['all', 'first', 'rest', 'none'];
|
|
16109
|
+
this.point = 'all';
|
|
16110
|
+
this.isoDs = ['all', 'first', 'rest', 'none'];
|
|
16111
|
+
this.isoD = 'first';
|
|
16112
|
+
this.isoCs = ['all', 'first', 'rest', 'none'];
|
|
16113
|
+
this.isoC = 'first';
|
|
16114
|
+
this.zRoc = false;
|
|
16115
|
+
this.far = 0.25;
|
|
16116
|
+
this.hr = 0.75;
|
|
16117
|
+
this.s = SDTMath.s.DEFAULT;
|
|
16118
|
+
this.label = '';
|
|
16119
|
+
this.locations = [{
|
|
16120
|
+
name: 'default',
|
|
16121
|
+
far: this.far,
|
|
16122
|
+
hr: this.hr,
|
|
16123
|
+
s: this.s,
|
|
16124
|
+
label: ''
|
|
16125
|
+
}];
|
|
16126
|
+
this.pointArray = [];
|
|
16127
|
+
this.isoDArray = [];
|
|
16128
|
+
this.isoCArray = [];
|
|
16129
|
+
this.alignState();
|
|
16130
|
+
}
|
|
16131
|
+
alignState() {
|
|
16132
|
+
this.locations[0].hr = this.hr;
|
|
16133
|
+
this.locations[0].far = this.far;
|
|
16134
|
+
this.locations[0].s = this.s;
|
|
16135
|
+
this.locations[0].label = this.label;
|
|
16136
|
+
this.d = SDTMath.hrFar2D(this.hr, this.far, this.s);
|
|
16137
|
+
this.c = SDTMath.hrFar2C(this.hr, this.far, this.s);
|
|
16138
|
+
this.pointArray = [];
|
|
16139
|
+
this.isoDArray = [];
|
|
16140
|
+
this.isoCArray = [];
|
|
16141
|
+
this.locations.forEach((item, index) => {
|
|
16142
|
+
item.d = SDTMath.hrFar2D(item.hr, item.far, item.s);
|
|
16143
|
+
item.c = SDTMath.hrFar2C(item.hr, item.far, item.s);
|
|
16144
|
+
if (index === 0 && (this.point === 'first' || this.point === 'all')) {
|
|
16145
|
+
this.pointArray.push(item);
|
|
16146
|
+
} else if (index > 0 && (this.point === 'rest' || this.point === 'all')) {
|
|
16147
|
+
this.pointArray.push(item);
|
|
16148
|
+
}
|
|
16149
|
+
if (index === 0 && (this.isoD === 'first' || this.isoD === 'all')) {
|
|
16150
|
+
this.isoDArray.push(item);
|
|
16151
|
+
} else if (index > 0 && (this.isoD === 'rest' || this.isoD === 'all')) {
|
|
16152
|
+
this.isoDArray.push(item);
|
|
16153
|
+
}
|
|
16154
|
+
if (index === 0 && (this.isoC === 'first' || this.isoC === 'all')) {
|
|
16155
|
+
this.isoCArray.push(item);
|
|
16156
|
+
} else if (index > 0 && (this.isoC === 'rest' || this.isoC === 'all')) {
|
|
16157
|
+
this.isoCArray.push(item);
|
|
16158
|
+
}
|
|
16159
|
+
});
|
|
16160
|
+
}
|
|
16161
|
+
set(hr, far, name = 'default', label = '', s = 1) {
|
|
16162
|
+
if (name === 'default') {
|
|
16163
|
+
this.hr = hr;
|
|
16164
|
+
this.far = far;
|
|
16165
|
+
this.s = s;
|
|
16166
|
+
this.label = label;
|
|
16167
|
+
}
|
|
16168
|
+
const location = this.locations.find(item => {
|
|
16169
|
+
return item.name === name;
|
|
16170
|
+
});
|
|
16171
|
+
if (location === undefined) {
|
|
16172
|
+
this.locations.push({
|
|
16173
|
+
name: name,
|
|
16174
|
+
far: far,
|
|
16175
|
+
hr: hr,
|
|
16176
|
+
s: s,
|
|
16177
|
+
label: label
|
|
16178
|
+
});
|
|
16179
|
+
} else {
|
|
16180
|
+
location.hr = hr;
|
|
16181
|
+
location.far = far;
|
|
16182
|
+
location.s = s;
|
|
16183
|
+
location.label = label;
|
|
16184
|
+
}
|
|
16185
|
+
this.requestUpdate();
|
|
16186
|
+
}
|
|
16187
|
+
setWithSDT(d, c, name = 'default', label = '', s = 1) {
|
|
16188
|
+
if (name === 'default') {
|
|
16189
|
+
this.hr = SDTMath.dC2Hr(d, c, s);
|
|
16190
|
+
this.far = SDTMath.dC2Far(d, c, s);
|
|
16191
|
+
this.s = s;
|
|
16192
|
+
this.label = label;
|
|
16193
|
+
}
|
|
16194
|
+
const location = this.locations.find(item => {
|
|
16195
|
+
return item.name === name;
|
|
16196
|
+
});
|
|
16197
|
+
if (location === undefined) {
|
|
16198
|
+
this.locations.push({
|
|
16199
|
+
name: name,
|
|
16200
|
+
far: SDTMath.dC2Far(d, c, s),
|
|
16201
|
+
hr: SDTMath.dC2Hr(d, c, s),
|
|
16202
|
+
s: s,
|
|
16203
|
+
label: label
|
|
16204
|
+
});
|
|
16205
|
+
} else {
|
|
16206
|
+
location.hr = SDTMath.dC2Hr(d, c, s);
|
|
16207
|
+
location.far = SDTMath.dC2Far(d, c, s);
|
|
16208
|
+
location.s = s;
|
|
16209
|
+
location.label = label;
|
|
16210
|
+
}
|
|
16211
|
+
this.sdt = true;
|
|
16212
|
+
this.requestUpdate();
|
|
16213
|
+
}
|
|
16214
|
+
static get styles() {
|
|
16215
|
+
return [super.styles, i$3`
|
|
16216
|
+
:host {
|
|
16217
|
+
display: inline-block;
|
|
13808
16218
|
|
|
13809
16219
|
width: 20rem;
|
|
13810
16220
|
height: 20rem;
|
|
@@ -13942,9 +16352,7 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
13942
16352
|
}
|
|
13943
16353
|
render() {
|
|
13944
16354
|
/* eslint-disable-line class-methods-use-this */
|
|
13945
|
-
return x$1
|
|
13946
|
-
${DetectableElement.svgFilters}
|
|
13947
|
-
`;
|
|
16355
|
+
return x$1``;
|
|
13948
16356
|
}
|
|
13949
16357
|
willUpdate() {
|
|
13950
16358
|
this.alignState();
|
|
@@ -14034,7 +16442,10 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
14034
16442
|
rem: this.rem
|
|
14035
16443
|
}]);
|
|
14036
16444
|
// ENTER
|
|
14037
|
-
const svgEnter = svgUpdate.enter().append('svg').classed('main', true)
|
|
16445
|
+
const svgEnter = svgUpdate.enter().append('svg').classed('main', true).each((datum, index, nodes) => {
|
|
16446
|
+
// Filters for shadows
|
|
16447
|
+
B(DetectableElement.svgFilters, nodes[index]);
|
|
16448
|
+
});
|
|
14038
16449
|
// MERGE
|
|
14039
16450
|
const svgMerge = svgEnter.merge(svgUpdate).attr('viewBox', `0 0 ${elementSize} ${elementSize}`);
|
|
14040
16451
|
|
|
@@ -14081,7 +16492,7 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
14081
16492
|
const contourColorStart = this.getComputedStyleValue(this.contour === 'bias' ? '---color-element-background' : this.contour === 'sensitivity' ? '---color-d' : this.contour === 'accuracy' ? '---color-acc-dark' : null);
|
|
14082
16493
|
const contourColorEnd = this.getComputedStyleValue(this.contour === 'bias' ? '---color-c' : this.contour === 'sensitivity' ? '---color-element-background' : this.contour === 'accuracy' ? '---color-element-background' : null);
|
|
14083
16494
|
const contourColor = linear().domain(extent(contourThresholds)).interpolate(() => {
|
|
14084
|
-
return interpolateRgb(contourColorStart, contourColorEnd);
|
|
16495
|
+
return interpolateRgb(Color(contourColorStart).hex(), Color(contourColorEnd).hex());
|
|
14085
16496
|
});
|
|
14086
16497
|
// DATA-JOIN
|
|
14087
16498
|
const contourPlotUpdate = underlayerMerge.selectAll('.plot-contour').data([this.contour]);
|
|
@@ -14097,10 +16508,17 @@ class ROCSpace extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
14097
16508
|
const contoursEnter = contoursUpdate.enter().append('path').classed('contour', true);
|
|
14098
16509
|
// MERGE
|
|
14099
16510
|
contoursEnter.merge(contoursUpdate).transition().duration(transitionDuration * 2) // Extra long transition!
|
|
14100
|
-
.ease(cubicOut)
|
|
14101
|
-
.attr('
|
|
16511
|
+
.ease(cubicOut)
|
|
16512
|
+
// .attr('d', d3.geoPath(d3.geoIdentity().scale(width / n))) // ????
|
|
16513
|
+
.attrTween('d', (datum, index$1, elements) => {
|
|
16514
|
+
const element = elements[index$1];
|
|
16515
|
+
const previous = select(element).attr('d');
|
|
16516
|
+
const current = index(identity$1().scale(width / n))(datum);
|
|
16517
|
+
return interpolatePath(previous, current);
|
|
16518
|
+
}).attr('fill', datum => {
|
|
14102
16519
|
return contourColor(datum.value);
|
|
14103
16520
|
});
|
|
16521
|
+
|
|
14104
16522
|
// EXIT
|
|
14105
16523
|
contoursUpdate.exit().remove();
|
|
14106
16524
|
|
|
@@ -14710,6 +17128,7 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
14710
17128
|
filter: url("#shadow-4");
|
|
14711
17129
|
|
|
14712
17130
|
/* HACK: This gets Safari to correctly apply the filter! */
|
|
17131
|
+
/* https://github.com/emilbjorklund/svg-weirdness/issues/27 */
|
|
14713
17132
|
transform: translateX(0);
|
|
14714
17133
|
}
|
|
14715
17134
|
|
|
@@ -14899,9 +17318,7 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
14899
17318
|
}
|
|
14900
17319
|
render() {
|
|
14901
17320
|
/* eslint-disable-line class-methods-use-this */
|
|
14902
|
-
return x$1
|
|
14903
|
-
${DetectableElement.svgFilters}
|
|
14904
|
-
`;
|
|
17321
|
+
return x$1``;
|
|
14905
17322
|
}
|
|
14906
17323
|
sendEvent() {
|
|
14907
17324
|
this.dispatchEvent(new CustomEvent('sdt-model-change', {
|
|
@@ -15071,7 +17488,10 @@ class SDTModel extends DecidablesMixinResizeable(DetectableElement) {
|
|
|
15071
17488
|
rem: this.rem
|
|
15072
17489
|
}]);
|
|
15073
17490
|
// ENTER
|
|
15074
|
-
const svgEnter = svgUpdate.enter().append('svg').classed('main', true)
|
|
17491
|
+
const svgEnter = svgUpdate.enter().append('svg').classed('main', true).each((datum, index, nodes) => {
|
|
17492
|
+
// Filters for shadows
|
|
17493
|
+
B(DetectableElement.svgFilters, nodes[index]);
|
|
17494
|
+
});
|
|
15075
17495
|
// MERGE
|
|
15076
17496
|
const svgMerge = svgEnter.merge(svgUpdate).attr('viewBox', `0 0 ${elementWidth} ${elementHeight}`);
|
|
15077
17497
|
|