@zumer/orbit 1.0.0 → 1.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/dist/orbit.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /*
3
3
  * orbit
4
- * v.1.0.0
4
+ * v.1.1.0
5
5
  * Author Juan Martin Muda - Zumerlab
6
6
  * License MIT
7
7
  **/
@@ -14,213 +14,155 @@
14
14
  this.shadowRoot.innerHTML = `
15
15
  <style>
16
16
  :host {
17
- display: block;
18
- }
19
- svg {
17
+ --o-fill: var(--o-gray-light);
18
+ --o-stroke: var(--o-fill);
19
+ --o-stroke-width: 1;
20
+ --o-back-fill: transparent;
21
+ --o-back-stroke: none;
22
+ --o-back-stroke-width: 1;
23
+ }
24
+ :host(:hover){
25
+ --o-fill: var(--o-gray-light);
26
+ --o-stroke: var(--o-fill);
27
+ --o-stroke-width: 1;
28
+ --o-back-fill: transparent;
29
+ --o-back-stroke: none;
30
+ --o-back-stroke-width: 1;
31
+ }
32
+ svg {
20
33
  width: 100%;
21
34
  height: 100%;
22
35
  overflow: visible;
23
36
  pointer-events: none;
24
37
  }
25
38
  svg * {
26
- pointer-events: stroke;
39
+ pointer-events: visiblePainted;
27
40
  }
28
41
  .progress-bar {
29
- fill: transparent;
30
- stroke: var(--o-color);
31
- transition: stroke 0.3s;
42
+ fill: var(--o-fill);
43
+ stroke: var(--o-stroke);
44
+ stroke-width: var(--o-stroke-width);
45
+ transition: all 0.3s;
46
+ stroke-linejoin: round;
32
47
  }
33
48
  .progress-bg {
34
- stroke: var(--o-background-color, transparent);
35
- }
36
- :host(:hover) .progress-bar {
37
- stroke: var(--o-hover-color, var(--o-color));
38
-
49
+ fill: var(--o-back-fill);
50
+ stroke: var(--o-back-stroke);
51
+ stroke-width: var(--o-back-stroke-width);
39
52
  }
40
53
  </style>
41
54
  <svg viewBox="0 0 100 100">
42
- <defs></defs>
43
- <path class="progress-bg"></path>
44
- <path class="progress-bar"></path>
55
+ <path class="progress-bg" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
56
+ <path class="progress-bar" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
45
57
  </svg>
46
58
  `;
47
59
  }
48
60
  connectedCallback() {
49
61
  this.update();
50
- const observer = new MutationObserver((mutations) => {
62
+ this.observer = new MutationObserver((mutations) => {
63
+ this.observer.disconnect();
51
64
  mutations.forEach((mutation) => {
52
65
  this.update();
53
66
  });
67
+ this.observer.observe(this, { attributes: true, childList: true });
54
68
  });
55
- observer.observe(this, { attributes: true, childList: true });
69
+ this.observer.observe(this, { attributes: true, childList: true });
56
70
  }
57
71
  update() {
58
- const { shape } = this.getAttributes();
59
- const svg = this.shadowRoot.querySelector("svg");
60
- if (shape !== "none" && shape !== "circle") {
61
- const defs = this.createDefs();
62
- defs.appendChild(this.createMarker("head", "end"));
63
- defs.appendChild(this.createMarker("tail", "start"));
64
- svg.querySelector("defs").replaceWith(defs);
65
- }
66
72
  const progressBg = this.shadowRoot.querySelector(".progress-bg");
67
73
  const progressBar = this.shadowRoot.querySelector(".progress-bar");
68
74
  this.updateArc(progressBg, true);
69
75
  this.updateArc(progressBar, false);
70
76
  }
71
- createSVGElement() {
72
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
73
- svg.setAttribute("viewBox", "0 0 100 100");
74
- svg.setAttribute("width", this.getAttribute("width") || "100%");
75
- svg.setAttribute("height", this.getAttribute("height") || "100%");
76
- return svg;
77
- }
78
77
  updateArc(arc, full) {
79
- const {
80
- strokeWidth,
81
- realRadius,
82
- ellipseX,
83
- ellipseY,
84
- progressBarColor,
85
- progressBgColor,
86
- maxAngle,
87
- shape
88
- } = this.getAttributes();
89
- const angle = this.getProgressAngle(maxAngle, full);
90
- const { d } = this.calculateArcParameters(angle, realRadius, ellipseX, ellipseY);
78
+ const { d } = this.calculateArcParameters(full);
91
79
  arc.setAttribute("d", d);
92
- arc.setAttribute("stroke", full ? progressBgColor : progressBarColor);
93
- arc.setAttribute("fill", "transparent");
94
- if (shape === "circle")
95
- arc.setAttribute("stroke-linecap", "round");
96
- if (shape !== "none" && shape !== "circle" && CSS.supports("fill", "context-stroke")) {
97
- arc.setAttribute("marker-end", "url(#head)");
98
- arc.setAttribute("marker-start", "url(#tail)");
99
- }
100
- arc.setAttribute("stroke-width", strokeWidth);
101
- arc.setAttribute("vector-effect", "non-scaling-stroke");
102
80
  }
103
81
  getAttributes() {
104
- const orbitRadius = parseFloat(
105
- getComputedStyle(this).getPropertyValue("r") || 0
106
- );
107
- const range = parseFloat(
108
- getComputedStyle(this).getPropertyValue("--o-range") || 360
109
- );
110
- const ellipseX = parseFloat(
111
- getComputedStyle(this).getPropertyValue("--o-ellipse-x") || 1
112
- );
113
- const ellipseY = parseFloat(
114
- getComputedStyle(this).getPropertyValue("--o-ellipse-y") || 1
115
- );
116
- const progress = parseFloat(
117
- getComputedStyle(this).getPropertyValue("--o-progress") || this.getAttribute("value") || 0
118
- );
82
+ const orbitRadius = parseFloat(getComputedStyle(this).getPropertyValue("r") || 0);
83
+ let orbitNumber = parseFloat(getComputedStyle(this).getPropertyValue("--o-orbit-number"));
84
+ let size = parseFloat(getComputedStyle(this).getPropertyValue("--o-size-ratio"));
85
+ const range = parseFloat(getComputedStyle(this).getPropertyValue("--o-range") || 360);
86
+ const progress = parseFloat(getComputedStyle(this).getPropertyValue("--o-progress") || this.getAttribute("value") || 0);
119
87
  const shape = this.getAttribute("shape") || "none";
120
- const progressBarColor = this.getAttribute("bar-color");
121
- const progressBgColor = this.getAttribute("bgcolor") || "transparent";
122
- const strokeWidth = parseFloat(
123
- getComputedStyle(this).getPropertyValue("stroke-width") || 1
124
- );
125
- let strokeWithPercentage = strokeWidth / 2 * 100 / orbitRadius / 2;
126
- let innerOuter = strokeWithPercentage;
88
+ const strokeWidth = parseFloat(getComputedStyle(this).getPropertyValue("--o-stroke-width"));
89
+ const arcHeight = orbitRadius / orbitNumber * size - strokeWidth + 0.3;
90
+ const arcHeightPercentage = arcHeight / 2 * 100 / orbitRadius / 2;
91
+ const maxAngle = range;
92
+ const maxValue = parseFloat(this.getAttribute("max")) || 100;
93
+ let innerOuter;
127
94
  if (this.classList.contains("outer-orbit")) {
128
- innerOuter = strokeWithPercentage * 2;
129
- }
130
- if (this.classList.contains("quarter-outer-orbit")) {
131
- innerOuter = strokeWithPercentage * 1.75;
132
- }
133
- if (this.classList.contains("inner-orbit")) {
95
+ innerOuter = arcHeightPercentage;
96
+ } else if (this.classList.contains("quarter-outer-orbit")) {
97
+ innerOuter = arcHeightPercentage * -0.5;
98
+ } else if (this.classList.contains("inner-orbit")) {
99
+ innerOuter = arcHeightPercentage * -1;
100
+ } else if (this.classList.contains("quarter-inner-orbit")) {
101
+ innerOuter = arcHeightPercentage * 0.5;
102
+ } else {
134
103
  innerOuter = 0;
135
104
  }
136
- if (this.classList.contains("quarter-inner-orbit")) {
137
- innerOuter = strokeWithPercentage * 0.75;
138
- }
139
- const realRadius = 50 + innerOuter - strokeWithPercentage;
140
- const maxAngle = range;
105
+ const realRadius = 50 + innerOuter;
141
106
  return {
142
107
  orbitRadius,
143
- ellipseX,
144
- ellipseY,
145
108
  progress,
146
- progressBarColor,
147
- progressBgColor,
148
109
  strokeWidth,
149
110
  realRadius,
150
111
  maxAngle,
151
- shape
112
+ maxValue,
113
+ shape,
114
+ arcHeightPercentage,
115
+ orbitNumber
152
116
  };
153
117
  }
154
- getProgressAngle(maxAngle, full) {
155
- const progress = parseFloat(
156
- getComputedStyle(this).getPropertyValue("--o-progress") || this.getAttribute("value") || 0
157
- );
158
- const maxValue = parseFloat(this.getAttribute("max")) || 100;
118
+ getProgressAngle(full) {
119
+ const { maxAngle, progress, maxValue } = this.getAttributes();
159
120
  return full ? (maxValue - 1e-5) / maxValue * maxAngle : progress / maxValue * maxAngle;
160
121
  }
161
- calculateArcParameters(angle, realRadius, ellipseX, ellipseY) {
162
- const radiusX = realRadius / ellipseX;
163
- const radiusY = realRadius / ellipseY;
164
- const startX = 50 + radiusX * Math.cos(-Math.PI / 2);
165
- const startY = 50 + radiusY * Math.sin(-Math.PI / 2);
166
- const endX = 50 + radiusX * Math.cos((angle - 90) * Math.PI / 180);
167
- const endY = 50 + radiusY * Math.sin((angle - 90) * Math.PI / 180);
168
- const largeArcFlag = angle <= 180 ? 0 : 1;
169
- const d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 1 ${endX},${endY}`;
170
- return { startX, startY, endX, endY, largeArcFlag, d };
171
- }
172
- createDefs() {
173
- const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
174
- return defs;
175
- }
176
- createMarker(id, position = "end") {
177
- const { shape } = this.getAttributes();
178
- const marker = document.createElementNS("http://www.w3.org/2000/svg", "marker");
179
- marker.setAttribute("id", id);
180
- marker.setAttribute("viewBox", "0 0 10 10");
181
- if (position === "start" && shape !== "circle") {
182
- marker.setAttribute("refX", "2");
183
- } else if (position === "start" && shape === "circle") {
184
- marker.setAttribute("refX", "5");
185
- } else {
186
- marker.setAttribute("refX", "0.1");
187
- }
188
- marker.setAttribute("refY", "5");
189
- marker.setAttribute("markerWidth", "1");
190
- marker.setAttribute("markerHeight", "1");
191
- marker.setAttribute("orient", "auto");
192
- marker.setAttribute("markerUnits", "strokeWidth");
193
- marker.setAttribute("fill", "context-stroke");
194
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
195
- const shapes = {
196
- arrow: {
197
- head: "M 0 0 L 2 5 L 0 10 z",
198
- tail: "M 2 0 L 0 0 L 1 5 L 0 10 L 2 10 L 2 5 z"
199
- },
200
- slash: {
201
- head: "M 0 0 L 0 0 L 1 5 L 2 10 L 0 10 L 0 5 z",
202
- tail: "M 2 0 L 0 0 L 1 5 L 2 10 L 2 10 L 2 5 z"
203
- },
204
- backslash: {
205
- head: "M 0 0 L 2 0 L 1 5 L 0 10 L 0 10 L 0 5 z",
206
- tail: "M 2 0 L 2 0 L 1 5 L 0 10 L 2 10 L 2 5 z"
207
- },
208
- circle: {
209
- head: "M 0 0 C 7 0 7 10 0 10 z",
210
- tail: "M 6 0 C -1 0 -1 10 6 10 z"
211
- },
212
- zigzag: {
213
- head: "M 1 0 L 0 0 L 0 5 L 0 10 L 1 10 L 2 7 L 1 5 L 2 3 z",
214
- tail: "M 0 0 L 2 0 L 2 5 L 2 10 L 0 10 L 1 7 L 0 5 L 1 3 z"
215
- }
216
- };
217
- if (position === "end") {
218
- path.setAttribute("d", shapes[shape].head);
219
- } else {
220
- path.setAttribute("d", shapes[shape].tail);
221
- }
222
- marker.appendChild(path);
223
- return marker;
122
+ calculateArcParameters(full) {
123
+ const arcAngle = this.getProgressAngle(full);
124
+ const { realRadius, arcHeightPercentage, orbitNumber, shape, strokeWidth } = this.getAttributes();
125
+ const radius = realRadius;
126
+ let startX, startY, endX, endY, largeArcFlag, startX1, startY1, endX1, endY1, dShape, pointX, pointX1, pointY, pointY1;
127
+ let offset = Math.PI / 2;
128
+ let stroke = strokeWidth;
129
+ let fangle = arcAngle * Math.PI / 180;
130
+ let bigRadius = radius + arcHeightPercentage;
131
+ let smallRadius = radius - arcHeightPercentage !== 0 ? radius - arcHeightPercentage : radius;
132
+ let bigGap = stroke * 2 / orbitNumber / 2 / bigRadius;
133
+ let smallGap = stroke * 2 / orbitNumber / 2 / smallRadius;
134
+ let startAngle = bigGap - offset;
135
+ let endAngle = fangle - bigGap - offset;
136
+ let startAngle1 = smallGap - offset;
137
+ let endAngle1 = fangle - smallGap - offset;
138
+ startX = 50 + bigRadius * Math.cos(startAngle);
139
+ startY = 50 + bigRadius * Math.sin(startAngle);
140
+ endX = 50 + bigRadius * Math.cos(endAngle);
141
+ endY = 50 + bigRadius * Math.sin(endAngle);
142
+ pointX = 50 + bigRadius * Math.cos(endAngle + 3 * Math.PI / 180);
143
+ pointY = 50 + bigRadius * Math.sin(endAngle + 3 * Math.PI / 180);
144
+ startX1 = 50 + smallRadius * Math.cos(startAngle1);
145
+ startY1 = 50 + smallRadius * Math.sin(startAngle1);
146
+ endX1 = 50 + smallRadius * Math.cos(endAngle1);
147
+ endY1 = 50 + smallRadius * Math.sin(endAngle1);
148
+ pointX1 = 50 + smallRadius * Math.cos(endAngle1 + 3 * Math.PI / 180);
149
+ pointY1 = 50 + smallRadius * Math.sin(endAngle1 + 3 * Math.PI / 180);
150
+ largeArcFlag = arcAngle <= 180 ? 0 : 1;
151
+ let d = `M ${startX},${startY} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${endX},${endY}`;
152
+ if (shape === "arrow")
153
+ d += `L ${(pointX + pointX1) / 2} ${(pointY + pointY1) / 2} `;
154
+ if (shape === "circle" || shape === "bullet")
155
+ d += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 1 ${endX1},${endY1} `;
156
+ d += `L ${endX1} ${endY1}`;
157
+ d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${startX1},${startY1}`;
158
+ if (shape === "circle")
159
+ d += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 1 ${startX},${startY} `;
160
+ if (shape === "bullet")
161
+ d += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 0 ${startX},${startY} `;
162
+ if (shape === "arrow")
163
+ d += `L ${startX1 + 3} ${(startY + startY1) / 2} `;
164
+ d += `Z`;
165
+ return { d };
224
166
  }
225
167
  };
226
168
 
@@ -228,36 +170,46 @@
228
170
  var template = document.createElement("template");
229
171
  template.innerHTML = `
230
172
  <style>
231
- :host {
232
- display: inline-block;
233
- }
234
- svg {
235
- width: 100%;
236
- height: 100%;
237
- overflow: visible;
238
- pointer-events: none;
239
- }
173
+ :host {
174
+ --o-fill: var(--o-gray-light);
175
+ --o-stroke: var(--o-fill);
176
+ --o-stroke-width: 1;
177
+ --o-color: currentcolor;
178
+ }
179
+ :host(:hover){
180
+ --o-fill: var(--o-gray-light);
181
+ --o-stroke: var(--o-fill);
182
+ --o-stroke-width: 1;
183
+ --o-color: currentcolor;
184
+ }
185
+ svg {
186
+ width: 100%;
187
+ height: 100%;
188
+ overflow: visible;
189
+ pointer-events: none;
190
+ }
240
191
  svg * {
241
- pointer-events: stroke;
192
+ pointer-events: visiblePainted;
242
193
  }
243
- .arc {
244
- stroke: var(--o-color, transparent);
245
- stroke-width: calc(var(--o-radius) / var(--o-orbit-number) * var(--o-size-ratio, 1));
246
- transition: stroke 0.3s;
194
+ #orbitShape {
195
+ fill: var(--o-fill);
196
+ stroke: var(--o-stroke);
197
+ stroke-width: var(--o-stroke-width);
198
+ transition: all 0.3s;
199
+ stroke-linejoin: round;
247
200
  }
248
201
  text {
249
- color: var(--o-text-color, currentcolor);
250
- }
251
- :host(:hover) text {
252
- color: var(--o-hover-text-color, var(--o-text-color));
202
+ fill: var(--o-color);
253
203
  }
254
- :host(:hover) .arc {
255
- stroke: var(--o-hover-color, var(--o-color));
204
+ #orbitPath {
205
+ fill: transparent;
206
+ stroke: none;
207
+ stroke-width: 0;
256
208
  }
257
209
  </style>
258
210
  <svg viewBox="0 0 100 100">
259
- <defs></defs>
260
- <path id="orbitPath" class="arc" vector-effect="non-scaling-stroke" fill="transparent"></path>
211
+ <path id="orbitShape" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
212
+ <path id="orbitPath" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke" ></path>
261
213
  <text>
262
214
  <textPath href="#orbitPath" alignment-baseline="middle"></textPath>
263
215
  </text>
@@ -281,24 +233,15 @@
281
233
  this.observer.observe(this, { attributes: true, childList: true });
282
234
  }
283
235
  update() {
284
- const { shape, realRadius, gap, flip } = this.getAttributes();
285
- const path = this.shadowRoot.getElementById("orbitPath");
286
- const defs = this.shadowRoot.querySelector("defs");
236
+ const { length, fontSize, textAnchor, fitRange } = this.getAttributes();
237
+ const orbitPath = this.shadowRoot.getElementById("orbitPath");
238
+ const orbitShape = this.shadowRoot.getElementById("orbitShape");
287
239
  const text = this.shadowRoot.querySelector("text");
288
240
  const textPath = this.shadowRoot.querySelector("textPath");
289
- if (shape === "circle")
290
- path.setAttribute("stroke-linecap", "round");
291
- if (shape !== "none" && shape !== "circle" && CSS.supports("fill", "context-stroke")) {
292
- defs.innerHTML = "";
293
- defs.appendChild(this.createMarker("head", "end"));
294
- defs.appendChild(this.createMarker("tail", "start"));
295
- path.setAttribute("marker-end", "url(#head)");
296
- path.setAttribute("marker-start", "url(#tail)");
297
- }
298
- const { length, fontSize, textAnchor, fitRange } = this.getTextAttributes();
299
- const angle = this.calculateAngle();
300
- const { d } = this.calculateArcParameters(angle, realRadius, gap, flip);
301
- path.setAttribute("d", d);
241
+ const { dShape } = this.calculateArcParameters();
242
+ const { dPath } = this.calculateTextArcParameters();
243
+ orbitShape.setAttribute("d", dShape);
244
+ orbitPath.setAttribute("d", dPath);
302
245
  if (textAnchor === "start") {
303
246
  textPath.setAttribute("startOffset", "0%");
304
247
  textPath.setAttribute("text-anchor", "start");
@@ -309,79 +252,56 @@
309
252
  textPath.setAttribute("startOffset", "100%");
310
253
  textPath.setAttribute("text-anchor", "end");
311
254
  }
312
- if (fitRange) {
313
- textPath.parentElement.setAttribute("textLength", path.getTotalLength());
314
- }
255
+ if (fitRange)
256
+ textPath.parentElement.setAttribute("textLength", orbitPath.getTotalLength());
315
257
  text.style.fontSize = `calc(${fontSize} * (100 / (${length}) * (12 / var(--o-orbit-number) ))`;
316
258
  textPath.textContent = this.textContent;
317
259
  }
318
- getTextAttributes() {
319
- const { length, fontSize, textAnchor, fitRange } = this.getAttributes();
320
- return { length, fontSize, textAnchor, fitRange };
321
- }
322
260
  getAttributes() {
323
- const orbitRadius = parseFloat(
324
- getComputedStyle(this).getPropertyValue("r") || 0
325
- );
326
- const gap = parseFloat(getComputedStyle(this).getPropertyValue("--o-gap")) || 1e-3;
261
+ let rawAngle, arcAngle, orbitNumber, size, innerOuter;
262
+ const strokeWidth = parseFloat(getComputedStyle(this).getPropertyValue("--o-stroke-width"));
263
+ const orbitRadius = parseFloat(getComputedStyle(this).getPropertyValue("r") || 0);
327
264
  const shape = this.getAttribute("shape") || "none";
328
265
  const flip = this.hasAttribute("flip") || this.classList.contains("flip");
329
266
  const fitRange = this.hasAttribute("fit-range") || this.classList.contains("fit-range") || false;
330
- const length = parseFloat(
331
- getComputedStyle(this).getPropertyValue("--o-force")
332
- );
267
+ const length = parseFloat(getComputedStyle(this).getPropertyValue("--o-force"));
333
268
  const textAnchor = this.getAttribute("text-anchor") || "middle";
334
269
  const fontSize = getComputedStyle(this).getPropertyValue("font-size") || getComputedStyle(this).getPropertyValue("--font-size");
270
+ const range = parseFloat(getComputedStyle(this).getPropertyValue("--o-range") || 360);
335
271
  const value = parseFloat(this.getAttribute("value"));
336
- const range = parseFloat(
337
- getComputedStyle(this).getPropertyValue("--o-range") || 360
338
- );
339
- let rawAngle;
340
- let arcAngle;
341
272
  if (value) {
342
273
  arcAngle = this.getProgressAngle(range, value);
343
274
  const prevElement = this.previousElementSibling;
344
- const stackOffset = prevElement ? parseFloat(
345
- getComputedStyle(prevElement).getPropertyValue("--o_stack")
346
- ) : 0;
275
+ const stackOffset = prevElement ? parseFloat(getComputedStyle(prevElement).getPropertyValue("--o_stack")) : 0;
347
276
  this.style.setProperty("--o_stack", stackOffset + arcAngle);
348
- if (stackOffset >= 0 && flip) {
349
- this.style.setProperty(
350
- "--o-angle-composite",
351
- parseFloat(stackOffset + arcAngle) + "deg"
352
- );
353
- }
354
- if (stackOffset > 0 && !flip) {
355
- this.style.setProperty(
356
- "--o-angle-composite",
357
- parseFloat(stackOffset) + "deg"
358
- );
359
- }
277
+ if (stackOffset >= 0 && flip)
278
+ this.style.setProperty("--o-angle-composite", parseFloat(stackOffset) + "deg");
279
+ if (stackOffset > 0 && !flip)
280
+ this.style.setProperty("--o-angle-composite", parseFloat(stackOffset) + "deg");
360
281
  } else {
361
282
  rawAngle = getComputedStyle(this).getPropertyValue("--o-angle");
362
283
  arcAngle = calcularExpresionCSS(rawAngle);
363
284
  }
364
- const strokeWidth = parseFloat(
365
- getComputedStyle(this).getPropertyValue("stroke-width") || 1
366
- );
367
- const strokeWithPercentage = strokeWidth / 2 * 100 / orbitRadius / 2;
368
- let innerOuter = strokeWithPercentage;
285
+ orbitNumber = parseFloat(getComputedStyle(this).getPropertyValue("--o-orbit-number"));
286
+ size = parseFloat(getComputedStyle(this).getPropertyValue("--o-size-ratio"));
287
+ const arcHeight = orbitRadius / orbitNumber * size - strokeWidth + 0.3;
288
+ const arcHeightPercentage = arcHeight / 2 * 100 / orbitRadius / 2;
289
+ const gap = parseFloat(getComputedStyle(this).getPropertyValue("--o-gap"));
369
290
  if (this.classList.contains("outer-orbit")) {
370
- innerOuter = strokeWithPercentage * 2;
371
- }
372
- if (this.classList.contains("quarter-outer-orbit")) {
373
- innerOuter = strokeWithPercentage * 1.75;
374
- }
375
- if (this.classList.contains("inner-orbit")) {
291
+ innerOuter = arcHeightPercentage;
292
+ } else if (this.classList.contains("quarter-outer-orbit")) {
293
+ innerOuter = arcHeightPercentage * -0.5;
294
+ } else if (this.classList.contains("inner-orbit")) {
295
+ innerOuter = arcHeightPercentage * -1;
296
+ } else if (this.classList.contains("quarter-inner-orbit")) {
297
+ innerOuter = arcHeightPercentage * 0.5;
298
+ } else {
376
299
  innerOuter = 0;
377
300
  }
378
- if (this.classList.contains("quarter-inner-orbit")) {
379
- innerOuter = strokeWithPercentage * 0.75;
380
- }
381
- const realRadius = 50 + innerOuter - strokeWithPercentage;
301
+ const realRadius = 50 + innerOuter;
382
302
  return {
383
303
  orbitRadius,
384
- strokeWidth,
304
+ arcHeight,
385
305
  realRadius,
386
306
  gap,
387
307
  arcAngle,
@@ -390,82 +310,87 @@
390
310
  fontSize,
391
311
  flip,
392
312
  fitRange,
393
- textAnchor
313
+ textAnchor,
314
+ arcHeightPercentage,
315
+ innerOuter,
316
+ orbitNumber,
317
+ size,
318
+ strokeWidth
394
319
  };
395
320
  }
396
- calculateAngle() {
397
- const { arcAngle, gap, flip } = this.getAttributes();
398
- let calculation = flip ? arcAngle : arcAngle;
399
- return calculation;
400
- }
401
321
  getProgressAngle(maxAngle, value) {
402
322
  const progress = value;
403
323
  const maxValue = parseFloat(this.getAttribute("max")) || 100;
404
324
  return progress / maxValue * maxAngle;
405
325
  }
406
- calculateArcParameters(angle, realRadius, gap, flip) {
407
- const radiusX = realRadius / 1;
408
- const radiusY = realRadius / 1;
409
- let startX, startY, endX, endY, largeArcFlag, d;
326
+ calculateArcParameters() {
327
+ const { arcAngle, realRadius, gap, arcHeightPercentage, orbitNumber, shape, strokeWidth } = this.getAttributes();
328
+ const radius = realRadius;
329
+ let startX, startY, endX, endY, largeArcFlag, startX1, startY1, endX1, endY1, dShape, pointX, pointX1, pointY, pointY1;
330
+ let offset = Math.PI / 2;
331
+ let stroke = strokeWidth;
332
+ let fangle = arcAngle * Math.PI / 180;
333
+ let bigRadius = radius + arcHeightPercentage;
334
+ let smallRadius = radius - arcHeightPercentage !== 0 ? radius - arcHeightPercentage : radius;
335
+ let bigGap = (gap * 2 + stroke * 2) / orbitNumber / 2 / bigRadius;
336
+ let smallGap = (gap * 2 + stroke * 2) / orbitNumber / 2 / smallRadius;
337
+ let startAngle = bigGap - offset;
338
+ let endAngle = fangle - bigGap - offset;
339
+ let startAngle1 = smallGap - offset;
340
+ let endAngle1 = fangle - smallGap - offset;
341
+ startX = 50 + bigRadius * Math.cos(startAngle);
342
+ startY = 50 + bigRadius * Math.sin(startAngle);
343
+ endX = 50 + bigRadius * Math.cos(endAngle);
344
+ endY = 50 + bigRadius * Math.sin(endAngle);
345
+ pointX = 50 + bigRadius * Math.cos(endAngle + 3 * Math.PI / 180);
346
+ pointY = 50 + bigRadius * Math.sin(endAngle + 3 * Math.PI / 180);
347
+ startX1 = 50 + smallRadius * Math.cos(startAngle1);
348
+ startY1 = 50 + smallRadius * Math.sin(startAngle1);
349
+ endX1 = 50 + smallRadius * Math.cos(endAngle1);
350
+ endY1 = 50 + smallRadius * Math.sin(endAngle1);
351
+ pointX1 = 50 + smallRadius * Math.cos(endAngle1 + 3 * Math.PI / 180);
352
+ pointY1 = 50 + smallRadius * Math.sin(endAngle1 + 3 * Math.PI / 180);
353
+ largeArcFlag = arcAngle <= 180 ? 0 : 1;
354
+ dShape = `M ${startX},${startY} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${endX},${endY}`;
355
+ if (shape === "arrow")
356
+ dShape += `L ${(pointX + pointX1) / 2} ${(pointY + pointY1) / 2} `;
357
+ if (shape === "circle" || shape === "bullet")
358
+ dShape += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 1 ${endX1},${endY1} `;
359
+ dShape += `L ${endX1} ${endY1}`;
360
+ dShape += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${startX1},${startY1}`;
361
+ if (shape === "circle")
362
+ dShape += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 1 ${startX},${startY} `;
363
+ if (shape === "bullet")
364
+ dShape += `A ${arcHeightPercentage}, ${arcHeightPercentage} 0 0 0 ${startX},${startY} `;
365
+ if (shape === "arrow")
366
+ dShape += `L ${startX1 + 3} ${(startY + startY1) / 2} `;
367
+ dShape += `Z`;
368
+ return { dShape };
369
+ }
370
+ calculateTextArcParameters() {
371
+ const { arcAngle, realRadius, gap, flip } = this.getAttributes();
372
+ const radius = realRadius;
373
+ let startX, startY, endX, endY, largeArcFlag, dPath, sweepFlag;
410
374
  let adjustedGap = gap * 0.5;
375
+ sweepFlag = flip ? 0 : 1;
376
+ largeArcFlag = arcAngle <= 180 ? 0 : 1;
377
+ let coordX1 = 50 + radius * Math.cos((-90 + adjustedGap) * (Math.PI / 180));
378
+ let coordY1 = 50 + radius * Math.sin((-90 + adjustedGap) * (Math.PI / 180));
379
+ let coordX2 = 50 + radius * Math.cos((arcAngle - 90 - adjustedGap) * Math.PI / 180);
380
+ let coordY2 = 50 + radius * Math.sin((arcAngle - 90 - adjustedGap) * Math.PI / 180);
411
381
  if (flip) {
412
- startX = 50 + radiusX * Math.cos((-90 - adjustedGap) * (Math.PI / 180));
413
- startY = 50 + radiusY * Math.sin((-90 - adjustedGap) * (Math.PI / 180));
414
- endX = 50 + radiusX * Math.cos((270 - angle + adjustedGap) * Math.PI / 180);
415
- endY = 50 + radiusY * Math.sin((270 - angle + adjustedGap) * Math.PI / 180);
416
- largeArcFlag = angle <= 180 ? 0 : 1;
417
- d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 0 ${endX},${endY}`;
382
+ startX = coordX2;
383
+ startY = coordY2;
384
+ endX = coordX1;
385
+ endY = coordY1;
418
386
  } else {
419
- startX = 50 + radiusX * Math.cos((-90 + adjustedGap) * (Math.PI / 180));
420
- startY = 50 + radiusY * Math.sin((-90 + adjustedGap) * (Math.PI / 180));
421
- endX = 50 + radiusX * Math.cos((angle - 90 - adjustedGap) * Math.PI / 180);
422
- endY = 50 + radiusY * Math.sin((angle - 90 - adjustedGap) * Math.PI / 180);
423
- largeArcFlag = angle <= 180 ? 0 : 1;
424
- d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 1 ${endX},${endY}`;
387
+ startX = coordX1;
388
+ startY = coordY1;
389
+ endX = coordX2;
390
+ endY = coordY2;
425
391
  }
426
- return { d };
427
- }
428
- createMarker(id, position = "end") {
429
- const { shape } = this.getAttributes();
430
- const marker = document.createElementNS(
431
- "http://www.w3.org/2000/svg",
432
- "marker"
433
- );
434
- marker.setAttribute("id", id);
435
- marker.setAttribute("viewBox", "0 0 10 10");
436
- position === "start" && shape !== "circle" ? marker.setAttribute("refX", "2") : position === "start" && shape === "circle" ? marker.setAttribute("refX", "5") : marker.setAttribute("refX", "0.1");
437
- marker.setAttribute("refY", "5");
438
- marker.setAttribute("markerWidth", "1");
439
- marker.setAttribute("markerHeight", "1");
440
- marker.setAttribute("orient", "auto");
441
- marker.setAttribute("markerUnits", "strokeWidth");
442
- marker.setAttribute("fill", "context-stroke");
443
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
444
- const shapes = {
445
- arrow: {
446
- head: "M 0 0 L 2 5 L 0 10 z",
447
- tail: "M 2 0 L 0 0 L 1 5 L 0 10 L 2 10 L 2 5 z"
448
- },
449
- slash: {
450
- head: "M 0 0 L 0 0 L 1 5 L 2 10 L 0 10 L 0 5 z",
451
- tail: "M 2 0 L 0 0 L 1 5 L 2 10 L 2 10 L 2 5 z"
452
- },
453
- backslash: {
454
- head: "M 0 0 L 2 0 L 1 5 L 0 10 L 0 10 L 0 5 z",
455
- tail: "M 2 0 L 2 0 L 1 5 L 0 10 L 2 10 L 2 5 z"
456
- },
457
- circle: {
458
- head: "M 0 0 C 7 0 7 10 0 10 z",
459
- tail: "M 6 0 C -1 0 -1 10 6 10 z"
460
- },
461
- zigzag: {
462
- head: "M 1 0 L 0 0 L 0 5 L 0 10 L 1 10 L 2 7 L 1 5 L 2 3 z",
463
- tail: "M 0 0 L 2 0 L 2 5 L 2 10 L 0 10 L 1 7 L 0 5 L 1 3 z"
464
- }
465
- };
466
- position === "end" ? path.setAttribute("d", shapes[shape].head) : path.setAttribute("d", shapes[shape].tail);
467
- marker.appendChild(path);
468
- return marker;
392
+ dPath = `M ${startX},${startY} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${endX},${endY}`;
393
+ return { dPath };
469
394
  }
470
395
  };
471
396
  function calcularExpresionCSS(cssExpression) {
@@ -510,7 +435,11 @@
510
435
  };
511
436
 
512
437
  // src/orbit.js
513
- customElements.define("o-progress", OrbitProgress);
514
- customElements.define("o-arc", OrbitArc);
438
+ if (!customElements.get("o-progress")) {
439
+ customElements.define("o-progress", OrbitProgress);
440
+ }
441
+ if (!customElements.get("o-arc")) {
442
+ customElements.define("o-arc", OrbitArc);
443
+ }
515
444
  window.Orbit = Orbit;
516
445
  })();