@zumer/orbit 2.0.1 → 2.1.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/README.md +20 -12
- package/dist/custom-elements.json +30 -3
- package/dist/orbit.css +42 -0
- package/dist/orbit.d.ts +11 -3
- package/dist/orbit.js +83 -16
- package/dist/orbit.min.css +1 -1
- package/dist/orbit.min.js +27 -4
- package/dist/orbit.mjs +83 -16
- package/dist/vscode.html-custom-data.json +6 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Orbit puts HTML on circles. Gauges, dials, knobs, radial menus, donut charts, wa
|
|
|
11
11
|
|
|
12
12
|
You write plain HTML with a few classes. CSS does the geometry and the look; a small runtime keeps numbering, spacing and SVG arcs right as things change. It works the same in plain HTML, React, Vue, Svelte or anything else that renders the DOM.
|
|
13
13
|
|
|
14
|
-
[Documentation and examples](https://zumerlab.com/orbit/) · [npm](https://www.npmjs.com/package/@zumer/orbit)
|
|
14
|
+
[Documentation and examples](https://zumerlab.com/orbit/) · [npm](https://www.npmjs.com/package/@zumer/orbit)
|
|
15
15
|
|
|
16
16
|
## Install
|
|
17
17
|
|
|
@@ -156,16 +156,12 @@ Values cascade, so set them once on the `.gravity-spot` for the whole system or
|
|
|
156
156
|
|
|
157
157
|
### Which way is out
|
|
158
158
|
|
|
159
|
-
Each satellite tells its content where it sits: `--o-dir-x` and `--o-dir-y` are the direction from the center, from `-1` to `1` (`y` grows down, and both are `0` on the center satellite).
|
|
159
|
+
Each satellite tells its content where it sits: `--o-dir-x` and `--o-dir-y` are the direction from the center, from `-1` to `1` (`y` grows down, and both are `0` on the center satellite). Two classes use them for labels. On a capsule or inside one, `.outward` sets a label just outside its satellite along that direction, and `.outward-y` only above or below: above the satellites of the upper half, below the rest. `--o-outward-gap` (4px) is the space between them.
|
|
160
160
|
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
position: absolute; left: 50%;
|
|
166
|
-
top: calc(50% + var(--side) * (50% + 4px));
|
|
167
|
-
translate: -50% calc((var(--side) - 1) * 50%);
|
|
168
|
-
}
|
|
161
|
+
```html
|
|
162
|
+
<div class="satellite">
|
|
163
|
+
<div class="capsule"><span class="dot"></span><span class="outward-y">Mars</span></div>
|
|
164
|
+
</div>
|
|
169
165
|
```
|
|
170
166
|
|
|
171
167
|
## Arcs and progress
|
|
@@ -190,7 +186,19 @@ Text inside an arc is drawn along it. With `range="auto"` the arc is as long as
|
|
|
190
186
|
</div>
|
|
191
187
|
```
|
|
192
188
|
|
|
193
|
-
|
|
189
|
+
`start` places an arc at a point of its ring, on the same scale as `value`. A placed arc takes no slot and moves no other arc, so labels and segments can go over a ring that already has arcs. `--o-max` on a ring or system sets the scale for everything below it, so values stay in their own units, hours for example:
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<div class="orbit-9" style="--o-max: 12; --o-from: 40deg; --o-range: 320deg">
|
|
193
|
+
<o-arc value="12" style="--o-fill: #222a33"></o-arc>
|
|
194
|
+
<o-arc start="1" value="2.5" style="--o-fill: #4fd1c5"></o-arc>
|
|
195
|
+
<o-arc range="auto" start="0" text-anchor="end" style="--o-fill: transparent">Lights</o-arc>
|
|
196
|
+
</div>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`class="ripple"` sends waves out of an arc to call for attention; `--o-ripple-color`, `--o-ripple-duration` and `--o-ripple-scale` tune them.
|
|
200
|
+
|
|
201
|
+
Progress rings draw filled bands. For a thin gauge line, use `variant="stroke"`: a 2px line over a gray track, colored with `--o-stroke` and `--o-back-stroke`. A `.satellite.at-value` in the same ring sits on the value of the progress and follows it, like the knob of a dial.
|
|
194
202
|
|
|
195
203
|
Arcs and progress are decorative until you say otherwise. `interactive` makes the whole band clickable, transparent or not, and `hit-width="12"` adds 12px of touch area on each side:
|
|
196
204
|
|
|
@@ -294,7 +302,7 @@ Version 2 changes where size comes from. In 1.x every system was 500px across, w
|
|
|
294
302
|
- `<o-arc>` and `<o-progress>` are placed with `rotate` instead of `transform`, and endings scale with the band. `interactive` makes the whole band clickable.
|
|
295
303
|
- `variant="stroke"` on `<o-progress>` draws a 2px line over a gray track by default.
|
|
296
304
|
|
|
297
|
-
The
|
|
305
|
+
The 1.x source and README stay on GitHub, at the [v1.6.0 tag](https://github.com/zumerlab/orbit/tree/v1.6.0#readme).
|
|
298
306
|
|
|
299
307
|
## Demos
|
|
300
308
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"name": "max",
|
|
28
|
-
"description": "Value that fills the ring's range. Must be positive.",
|
|
28
|
+
"description": "Value that fills the ring's range. Must be positive. Without it, --o-max of the ring or system.",
|
|
29
29
|
"type": {
|
|
30
30
|
"text": "number"
|
|
31
31
|
},
|
|
@@ -54,6 +54,13 @@
|
|
|
54
54
|
},
|
|
55
55
|
"default": "0"
|
|
56
56
|
},
|
|
57
|
+
{
|
|
58
|
+
"name": "start",
|
|
59
|
+
"description": "Where the arc begins, on the same scale as value. A placed arc takes no slot and moves no other arc: text over a ring that already has arcs, or segments on a timeline.",
|
|
60
|
+
"type": {
|
|
61
|
+
"text": "number"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
57
64
|
{
|
|
58
65
|
"name": "text-anchor",
|
|
59
66
|
"description": "Where curved text sits on the arc. With range=\"auto\", an explicit value anchors the arc at its angle: middle centers it, end ends it there.",
|
|
@@ -104,6 +111,22 @@
|
|
|
104
111
|
{
|
|
105
112
|
"name": "--o-gap",
|
|
106
113
|
"description": "Space between sibling arcs. Default 1; cascades from the ring or system."
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "--o-max",
|
|
117
|
+
"description": "Value that fills the range when there is no max attribute. Default 100; cascades from the ring or system."
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "--o-ripple-color",
|
|
121
|
+
"description": "Color of the .ripple wave. Default --o-fill."
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "--o-ripple-duration",
|
|
125
|
+
"description": "One wave of .ripple. Default 1.6s."
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "--o-ripple-scale",
|
|
129
|
+
"description": "How far a .ripple wave grows, from the center of the ring. Default 1.14."
|
|
107
130
|
}
|
|
108
131
|
],
|
|
109
132
|
"events": [
|
|
@@ -132,7 +155,7 @@
|
|
|
132
155
|
},
|
|
133
156
|
{
|
|
134
157
|
"name": "max",
|
|
135
|
-
"description": "Value that fills the ring's range. Must be positive.",
|
|
158
|
+
"description": "Value that fills the ring's range. Must be positive. Without it, --o-max of the ring or system.",
|
|
136
159
|
"type": {
|
|
137
160
|
"text": "number"
|
|
138
161
|
},
|
|
@@ -197,6 +220,10 @@
|
|
|
197
220
|
{
|
|
198
221
|
"name": "--o-progress",
|
|
199
222
|
"description": "Progress value; overrides the value attribute."
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"name": "--o-max",
|
|
226
|
+
"description": "Value that fills the range when there is no max attribute. Default 100; cascades from the ring or system."
|
|
200
227
|
}
|
|
201
228
|
],
|
|
202
229
|
"events": [
|
|
@@ -245,6 +272,6 @@
|
|
|
245
272
|
],
|
|
246
273
|
"package": {
|
|
247
274
|
"name": "@zumer/orbit",
|
|
248
|
-
"version": "2.0
|
|
275
|
+
"version": "2.1.0"
|
|
249
276
|
}
|
|
250
277
|
}
|
package/dist/orbit.css
CHANGED
|
@@ -1148,6 +1148,8 @@
|
|
|
1148
1148
|
--o-gap: 1;
|
|
1149
1149
|
--o-initial-orbit: 0;
|
|
1150
1150
|
--o-angle: 0;
|
|
1151
|
+
/* The value that fills a ring's range, for arcs and progress without a max attribute. */
|
|
1152
|
+
--o-max: 100;
|
|
1151
1153
|
width: 0;
|
|
1152
1154
|
aspect-ratio: 1;
|
|
1153
1155
|
position: relative;
|
|
@@ -1214,12 +1216,25 @@
|
|
|
1214
1216
|
pointer-events: all;
|
|
1215
1217
|
}
|
|
1216
1218
|
|
|
1219
|
+
/* The angle of the value of the <o-progress> in a ring, from the start of its
|
|
1220
|
+
range. The progress writes it on its ring. */
|
|
1221
|
+
@property --o-value-angle {
|
|
1222
|
+
syntax: "<angle>";
|
|
1223
|
+
inherits: true;
|
|
1224
|
+
initial-value: 0deg;
|
|
1225
|
+
}
|
|
1217
1226
|
.satellite.at-center {
|
|
1218
1227
|
--o-transform: rotate(0deg);
|
|
1219
1228
|
--o-dir-x: 0;
|
|
1220
1229
|
--o-dir-y: 0;
|
|
1221
1230
|
}
|
|
1222
1231
|
|
|
1232
|
+
/* Sits on the value of the <o-progress> in the same ring, like the knob of a
|
|
1233
|
+
dial. Progress always fills clockwise, so this ignores .ccw. */
|
|
1234
|
+
.satellite.at-value {
|
|
1235
|
+
--o-angle-composite: calc(var(--o-value-angle) + 270deg);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1223
1238
|
.satellite.circle {
|
|
1224
1239
|
border-radius: 50%;
|
|
1225
1240
|
}
|
|
@@ -9638,6 +9653,33 @@ Can be used in parent elements or in each orbiter class
|
|
|
9638
9653
|
margin-top: unset;
|
|
9639
9654
|
}
|
|
9640
9655
|
|
|
9656
|
+
/*
|
|
9657
|
+
Labels outside their satellite, away from the center (--o-dir-x/-y). Put
|
|
9658
|
+
the class on a capsule or on an element inside one. 50cqw and 50cqh are half
|
|
9659
|
+
the satellite; --o-outward-gap is the space between it and the label.
|
|
9660
|
+
*/
|
|
9661
|
+
.outward, .outward-y {
|
|
9662
|
+
position: absolute;
|
|
9663
|
+
width: max-content;
|
|
9664
|
+
}
|
|
9665
|
+
|
|
9666
|
+
/* Along the direction. The translate scales the direction so its larger
|
|
9667
|
+
component is 1: the label's nearest edge or corner touches the circle. */
|
|
9668
|
+
.outward {
|
|
9669
|
+
--o-out: max(var(--o-dir-x), -1 * var(--o-dir-x), var(--o-dir-y), -1 * var(--o-dir-y), .001);
|
|
9670
|
+
left: calc(50% + var(--o-dir-x) * (50cqw + var(--o-outward-gap, 4px)));
|
|
9671
|
+
top: calc(50% + var(--o-dir-y) * (50cqh + var(--o-outward-gap, 4px)));
|
|
9672
|
+
translate: calc(-50% + 50% * var(--o-dir-x) / var(--o-out)) calc(-50% + 50% * var(--o-dir-y) / var(--o-out));
|
|
9673
|
+
}
|
|
9674
|
+
|
|
9675
|
+
/* Only up or down: above the satellites of the upper half, below the rest. */
|
|
9676
|
+
.outward-y {
|
|
9677
|
+
--o-out: clamp(-1, (var(--o-dir-y) + .01) * 1000, 1);
|
|
9678
|
+
left: 50%;
|
|
9679
|
+
top: calc(50% + var(--o-out) * (50cqh + var(--o-outward-gap, 4px)));
|
|
9680
|
+
translate: -50% calc((var(--o-out) - 1) * 50%);
|
|
9681
|
+
}
|
|
9682
|
+
|
|
9641
9683
|
/* Satellite gyro */
|
|
9642
9684
|
.satellite.spin-lock {
|
|
9643
9685
|
transform: var(--o-transform) rotate(calc(var(--o-angle-composite)));
|
package/dist/orbit.d.ts
CHANGED
|
@@ -18,8 +18,13 @@ type BooleanAttribute = boolean | '' | undefined;
|
|
|
18
18
|
export interface OrbitArcAttributes {
|
|
19
19
|
/** Share of the ring's range, relative to `max`. Without it, sibling arcs split the range equally. */
|
|
20
20
|
value?: Numeric;
|
|
21
|
-
/** Value that fills the whole range. Default `100`. */
|
|
21
|
+
/** Value that fills the whole range. Default `--o-max` of the ring or system, else `100`. */
|
|
22
22
|
max?: Numeric;
|
|
23
|
+
/**
|
|
24
|
+
* Where the arc begins, on the same scale as `value` (0 is the start of the range).
|
|
25
|
+
* A placed arc takes no slot and moves no other arc, so it can sit over a ring that already has arcs.
|
|
26
|
+
*/
|
|
27
|
+
start?: Numeric;
|
|
23
28
|
shape?: OrbitShape;
|
|
24
29
|
/**
|
|
25
30
|
* Where curved text sits on the arc. Default `middle`.
|
|
@@ -43,7 +48,7 @@ export interface OrbitArcAttributes {
|
|
|
43
48
|
export interface OrbitProgressAttributes {
|
|
44
49
|
/** Progress relative to `max`. `--o-progress` overrides it. */
|
|
45
50
|
value?: Numeric;
|
|
46
|
-
/** Value that fills the whole range. Default `100`. */
|
|
51
|
+
/** Value that fills the whole range. Default `--o-max` of the ring or system, else `100`. */
|
|
47
52
|
max?: Numeric;
|
|
48
53
|
shape?: OrbitShape;
|
|
49
54
|
/** `stroke` draws open lines colored by `--o-stroke` and `--o-back-stroke`. */
|
|
@@ -68,7 +73,10 @@ export declare class OrbitProgress extends HTMLElement {
|
|
|
68
73
|
value: number | null;
|
|
69
74
|
/** Mirrors the `max` attribute (default 100). Setting it redraws. */
|
|
70
75
|
max: number;
|
|
71
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Redraw now. The runtime calls this when the progress or its layout changes.
|
|
78
|
+
* It also writes `--o-value-angle` on its ring, where a `.satellite.at-value` sits.
|
|
79
|
+
*/
|
|
72
80
|
update(): void;
|
|
73
81
|
}
|
|
74
82
|
|
package/dist/orbit.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* orbit
|
|
3
|
-
* v.2.0
|
|
3
|
+
* v.2.1.0
|
|
4
4
|
* Author Juan Martin Muda - Zumerlab
|
|
5
5
|
* License MIT
|
|
6
6
|
*/
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
return Number.isFinite(resolved) ? resolved : fallback;
|
|
101
101
|
}
|
|
102
102
|
function group(element) {
|
|
103
|
-
if (element.localName === "o-arc") return "arc";
|
|
103
|
+
if (element.localName === "o-arc") return element.hasAttribute("start") ? null : "arc";
|
|
104
104
|
for (const name of ["satellite", "vector", "side"]) if (element.classList.contains(name)) return name;
|
|
105
105
|
return null;
|
|
106
106
|
}
|
|
@@ -445,10 +445,22 @@
|
|
|
445
445
|
}
|
|
446
446
|
return value;
|
|
447
447
|
}
|
|
448
|
-
/**
|
|
449
|
-
|
|
448
|
+
/**
|
|
449
|
+
* The max attribute, else --o-max from the ring or system (default 100).
|
|
450
|
+
* It must be a positive number.
|
|
451
|
+
*/
|
|
452
|
+
readMax(style) {
|
|
450
453
|
const raw = this.getAttribute("max");
|
|
451
|
-
if (raw === null)
|
|
454
|
+
if (raw === null) {
|
|
455
|
+
const css = style == null ? void 0 : style.getPropertyValue("--o-max").trim();
|
|
456
|
+
if (!css) return 100;
|
|
457
|
+
const max2 = cssNumber(this, css, NaN);
|
|
458
|
+
if (!(max2 > 0)) {
|
|
459
|
+
warnOnce(this, "o-max:" + css, `--o-max: ${css} on <${this.localName}> must be a positive number, so nothing is drawn.`);
|
|
460
|
+
return 0;
|
|
461
|
+
}
|
|
462
|
+
return max2;
|
|
463
|
+
}
|
|
452
464
|
const max = Number(raw);
|
|
453
465
|
if (!(max > 0)) {
|
|
454
466
|
warnOnce(this, "max:" + raw, `<${this.localName} max="${raw}"> must be a positive number, so nothing is drawn.`);
|
|
@@ -668,14 +680,15 @@
|
|
|
668
680
|
}
|
|
669
681
|
/**
|
|
670
682
|
* Grow the SVG canvas past the ring's box so it covers the whole band, its
|
|
671
|
-
* stroke and touch area
|
|
672
|
-
* hit-test SVG content that
|
|
683
|
+
* stroke and touch area, and as far as a ripple reaches (attrs.reach).
|
|
684
|
+
* Some engines (WebKit) neither paint reliably nor hit-test SVG content that
|
|
685
|
+
* overflows its box.
|
|
673
686
|
*/
|
|
674
687
|
fitCanvas(attrs, extra) {
|
|
675
688
|
const svg = this.shadowRoot.querySelector("svg");
|
|
676
689
|
const scale = attrs.orbitRadius / 50;
|
|
677
690
|
if (!svg || !(scale > 0)) return;
|
|
678
|
-
const outer = (attrs.realRadius + attrs.arcHeightPercentage) * scale + attrs.strokeWidth + extra;
|
|
691
|
+
const outer = ((attrs.realRadius + attrs.arcHeightPercentage) * scale + attrs.strokeWidth) * (attrs.reach || 1) + extra;
|
|
679
692
|
const pad = Math.max(0, Math.ceil(outer - attrs.orbitRadius));
|
|
680
693
|
const units = pad / scale;
|
|
681
694
|
svg.setAttribute("viewBox", `${-units} ${-units} ${100 + 2 * units} ${100 + 2 * units}`);
|
|
@@ -776,6 +789,16 @@
|
|
|
776
789
|
this.shadowRoot.querySelector(".progress-bg").setAttribute("d", dBg);
|
|
777
790
|
this.shadowRoot.querySelector(".progress-bar").setAttribute("d", dBar);
|
|
778
791
|
this.updateHitArea(this.shadowRoot.querySelector(".hit"), attrs, 0, attrs.range);
|
|
792
|
+
const ring = this.parentElement;
|
|
793
|
+
if (this._valueRing && this._valueRing !== ring) this._valueRing.style.removeProperty("--o-value-angle");
|
|
794
|
+
this._valueRing = ring;
|
|
795
|
+
if (ring) setLayoutProperty(ring, "--o-value-angle", `${this.getProgressAngle(attrs, false)}deg`);
|
|
796
|
+
}
|
|
797
|
+
disconnectedCallback() {
|
|
798
|
+
var _a;
|
|
799
|
+
super.disconnectedCallback();
|
|
800
|
+
(_a = this._valueRing) == null ? void 0 : _a.style.removeProperty("--o-value-angle");
|
|
801
|
+
this._valueRing = null;
|
|
779
802
|
}
|
|
780
803
|
/**
|
|
781
804
|
* variant="stroke": open arc along the orbit radius (no closed band),
|
|
@@ -793,7 +816,7 @@
|
|
|
793
816
|
const range = Math.max(0, Math.min(360, this.readAngle(common.style, "--o-range", 360)));
|
|
794
817
|
const rawValue = common.style.getPropertyValue("--o-progress").trim();
|
|
795
818
|
const progress = rawValue ? this.readNumber(common.style, "--o-progress", 0) : this.readValue();
|
|
796
|
-
const maxValue = this.readMax();
|
|
819
|
+
const maxValue = this.readMax(common.style);
|
|
797
820
|
return {
|
|
798
821
|
...common,
|
|
799
822
|
range,
|
|
@@ -882,9 +905,32 @@
|
|
|
882
905
|
stroke: none;
|
|
883
906
|
pointer-events: none;
|
|
884
907
|
}
|
|
908
|
+
/* .ripple: a copy of the band grows out from the center of the ring and
|
|
909
|
+
fades, over and over. The band itself stays. */
|
|
910
|
+
#orbitWave {
|
|
911
|
+
display: none;
|
|
912
|
+
fill: var(--o-ripple-color, var(--o-fill));
|
|
913
|
+
stroke: none;
|
|
914
|
+
pointer-events: none;
|
|
915
|
+
transform-origin: 50px 50px;
|
|
916
|
+
}
|
|
917
|
+
:host(.ripple) #orbitWave {
|
|
918
|
+
display: inline;
|
|
919
|
+
animation: orbit-ripple var(--o-ripple-duration, 1.6s) ease-out infinite;
|
|
920
|
+
}
|
|
921
|
+
@keyframes orbit-ripple {
|
|
922
|
+
from { transform: scale(1); opacity: .9; }
|
|
923
|
+
to { transform: scale(var(--o-ripple-scale, 1.14)); opacity: 0; }
|
|
924
|
+
}
|
|
925
|
+
@media (prefers-reduced-motion: reduce) {
|
|
926
|
+
:host(.ripple) #orbitWave {
|
|
927
|
+
display: none;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
885
930
|
</style>
|
|
886
931
|
<svg viewBox="0 0 100 100">
|
|
887
932
|
<path id="orbitHit" vector-effect="non-scaling-stroke"></path>
|
|
933
|
+
<path id="orbitWave" shape-rendering="geometricPrecision"></path>
|
|
888
934
|
<path id="orbitShape" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
|
|
889
935
|
<path id="orbitPath" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
|
|
890
936
|
<text>
|
|
@@ -913,7 +959,9 @@
|
|
|
913
959
|
const orbitPath = this.shadowRoot.querySelector("#orbitPath");
|
|
914
960
|
const orbitShape = this.shadowRoot.querySelector("#orbitShape");
|
|
915
961
|
const textPath = this.shadowRoot.querySelector("textPath");
|
|
916
|
-
|
|
962
|
+
const { dShape } = this.calculateArcParameters(attrs);
|
|
963
|
+
orbitShape.setAttribute("d", dShape);
|
|
964
|
+
this.shadowRoot.querySelector("#orbitWave").setAttribute("d", dShape);
|
|
917
965
|
orbitPath.setAttribute("d", this.calculateTextArcParameters(attrs).dPath);
|
|
918
966
|
this.updateHitArea(this.shadowRoot.querySelector("#orbitHit"), attrs, 0, attrs.arcAngle);
|
|
919
967
|
const textAnchor = attrs.textAnchor;
|
|
@@ -974,26 +1022,45 @@
|
|
|
974
1022
|
const gap = Math.max(0, this.readNumber(style, "--o-gap", 1));
|
|
975
1023
|
const svgFontSize = `calc(${fontSize} * (100 / (${length}) * (12 / var(--o-orbit-number)))`;
|
|
976
1024
|
const auto = this.getAttribute("range") === "auto";
|
|
977
|
-
const
|
|
1025
|
+
const valued = this.hasAttribute("value");
|
|
1026
|
+
const placed = this.hasAttribute("start");
|
|
1027
|
+
const stacked = auto || valued || placed;
|
|
1028
|
+
const max = this.readMax(style);
|
|
978
1029
|
let arcAngle;
|
|
979
1030
|
if (auto) arcAngle = this.measureTextAngle(svgFontSize, common.realRadius, gap);
|
|
980
|
-
else if (
|
|
1031
|
+
else if (valued) arcAngle = super.getProgressAngle(range, this.readValue(), max);
|
|
981
1032
|
else arcAngle = Math.max(0, Math.min(360, this.readAngle(style, "--o-angle", 0)));
|
|
982
1033
|
this._autoAngle = auto ? arcAngle : 0;
|
|
983
1034
|
let stackOffset = 0;
|
|
984
|
-
if (
|
|
1035
|
+
if (placed) {
|
|
1036
|
+
stackOffset = max > 0 ? this.readStart() / max * range : 0;
|
|
1037
|
+
if (!auto && range < 360) {
|
|
1038
|
+
const end = Math.min(range, stackOffset + arcAngle);
|
|
1039
|
+
stackOffset = Math.max(0, stackOffset);
|
|
1040
|
+
arcAngle = Math.max(0, end - stackOffset);
|
|
1041
|
+
}
|
|
1042
|
+
} else if (stacked) {
|
|
985
1043
|
for (let prev = this.previousElementSibling; prev; prev = prev.previousElementSibling) {
|
|
986
|
-
if (prev.localName !== "o-arc") continue;
|
|
1044
|
+
if (prev.localName !== "o-arc" || prev.hasAttribute("start")) continue;
|
|
987
1045
|
const previousStyle = this.ownerDocument.defaultView.getComputedStyle(prev);
|
|
988
1046
|
if (prev.getAttribute("range") === "auto") stackOffset += prev._autoAngle || 0;
|
|
989
1047
|
else if (prev.hasAttribute("value")) {
|
|
990
|
-
const prevMax =
|
|
1048
|
+
const prevMax = this.readMax.call(prev, previousStyle);
|
|
991
1049
|
const prevRange = cssNumber(prev, previousStyle.getPropertyValue("--o-range"), range, "angle");
|
|
992
1050
|
stackOffset += super.getProgressAngle(prevRange, Number(prev.getAttribute("value")), prevMax);
|
|
993
1051
|
} else stackOffset += cssNumber(prev, previousStyle.getPropertyValue("--o-angle"), 0, "angle");
|
|
994
1052
|
}
|
|
995
1053
|
}
|
|
996
|
-
|
|
1054
|
+
const reach = this.classList.contains("ripple") ? Math.max(1, this.readNumber(style, "--o-ripple-scale", 1.14)) : 1;
|
|
1055
|
+
return { ...common, gap, max, arcAngle, stackOffset, flip, fitRange, length, fontSize, svgFontSize, textAnchor, auto, placed, stacked, reach };
|
|
1056
|
+
}
|
|
1057
|
+
/** The start attribute: where a placed arc begins, on the ring's scale. */
|
|
1058
|
+
readStart() {
|
|
1059
|
+
const raw = this.getAttribute("start");
|
|
1060
|
+
const start = Number(raw);
|
|
1061
|
+
if (Number.isFinite(start)) return start;
|
|
1062
|
+
warnOnce(this, "start:" + raw, `<o-arc start="${raw}"> is not a number, so the arc starts at 0.`);
|
|
1063
|
+
return 0;
|
|
997
1064
|
}
|
|
998
1065
|
/** range="auto": the angle that fits this arc's text, with half an em of room at each end. */
|
|
999
1066
|
measureTextAngle(svgFontSize, radius, gap) {
|