Skip to content

Commit

Permalink
update WC
Browse files Browse the repository at this point in the history
  • Loading branch information
tinchox5 committed Jul 20, 2024
1 parent 7f74513 commit dd3d018
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 395 deletions.
258 changes: 128 additions & 130 deletions src/js/orbit-label.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
function calcularExpresionCSS(cssExpression) {
const match = cssExpression.match(/calc\(\s*([\d.]+)deg\s*\/\s*\(\s*(\d+)\s*-\s*(\d+)\s*\)\s*\)/);
if (match) {
const value = parseFloat(match[1]);
const divisor = parseInt(match[2]) - parseInt(match[3]);
if (!isNaN(value) && !isNaN(divisor) && divisor !== 0) {
return value / divisor;
}
}
}



/*!
Expand Down Expand Up @@ -45,134 +36,128 @@ The number can be modify with `$max-orbiters` var at `_variables.scss`.
*/

export class OrbitLabel extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });

const template = document.createElement('template');
template.innerHTML = `
<svg viewBox="0 0 100 100" width="100%" height="100%">
<path id="orbitPath" fill="none" vector-effect="non-scaling-stroke"></path>
<text>
<textPath href="#orbitPath" alignment-baseline="middle"></textPath>
</text>
</svg>
<style>
svg {
overflow: visible;
}
:host {
display: inline-block;
width: 100%;
height: 100%;
}
text {
font-size: inherit;
}
</style>
`;

this.shadowRoot.appendChild(template.content.cloneNode(true));
}

connectedCallback() {
const pathId = `o-${Math.random().toString(36).substr(2, 9)}`;
this.update(pathId)
this.update();

const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
this.update(pathId)
this.update();
}
})
})
observer.observe(this, { attributes: true })

}
update(pathId) {
const svg = this.createSVGElement();
const path = this.createPathElement(pathId);
const text = this.createTextPath(pathId, path);

svg.appendChild(path);
svg.appendChild(text);

this.innerHTML = '';
this.appendChild(svg);
}
});
});

observer.observe(this, { attributes: true });

createSVGElement() {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg.setAttribute('viewBox', '0 0 100 100')
svg.setAttribute('width', this.getAttribute('width') || '100%')
svg.setAttribute('height', this.getAttribute('height') || '100%')
return svg
const slot = this.shadowRoot.querySelector('textPath');
slot.addEventListener('slotchange', () => {
this.update();
});
}
createPathElement(pathId) {
const path = document.createElementNS(
'http://www.w3.org/2000/svg',
'path'
)
const { strokeWidth,realRadius, gap,labelBgColor, flip, lineCap} = this.getAttributes()
const angle = this.calculateAngle()
const { d } = this.calculateArcParameters(angle, realRadius, gap, flip)
path.setAttribute('id', pathId)
path.setAttribute('d', d)
path.setAttribute('fill', 'none')
path.setAttribute('stroke', labelBgColor)
path.setAttribute('stroke-width', strokeWidth)
path.setAttribute('vector-effect', 'non-scaling-stroke')
path.setAttribute('stroke-linecap', lineCap)

return path
}

createTextPath(pathId, path) {
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
const textPath = document.createElementNS(
'http://www.w3.org/2000/svg',
'textPath'
);

const { labelColor, fitRange, textAnchor} = this.getAttributes()
textPath.setAttribute('href', `#${pathId}`);
textPath.setAttribute('color', labelColor);;
textPath.setAttribute('alignment-baseline', 'middle');

if (textAnchor === 'start') {
textPath.setAttribute('startOffset', '0%');
textPath.setAttribute('text-anchor', 'start');
}
if (textAnchor === 'middle') {
textPath.setAttribute('startOffset', '50%');
textPath.setAttribute('text-anchor', 'middle');
}
if (textAnchor === 'end') {
textPath.setAttribute('startOffset', '100%');
textPath.setAttribute('text-anchor', 'end');
}
update() {
const path = this.shadowRoot.getElementById('orbitPath');
const textPath = this.shadowRoot.querySelector('textPath');

const { d, strokeWidth, labelBgColor, lineCap } = this.getPathAttributes();
path.setAttribute('d', d);
path.setAttribute('stroke', labelBgColor);
path.setAttribute('stroke-width', strokeWidth);
path.setAttribute('stroke-linecap', lineCap);

const { labelColor, textAnchor, fitRange } = this.getTextAttributes();
textPath.setAttribute('color', labelColor);

if (textAnchor === 'start') {
textPath.setAttribute('startOffset', '0%');
textPath.setAttribute('text-anchor', 'start');
} else if (textAnchor === 'middle') {
textPath.setAttribute('startOffset', '50%');
textPath.setAttribute('text-anchor', 'middle');
} else if (textAnchor === 'end') {
textPath.setAttribute('startOffset', '100%');
textPath.setAttribute('text-anchor', 'end');
}

if (fitRange) {
textPath.parentElement.setAttribute('textLength', path.getTotalLength());
}

if (fitRange) {
text.setAttribute('textLength', path.getTotalLength());
textPath.textContent = this.textContent.trim();
}

textPath.textContent = this.textContent;

text.appendChild(textPath);
return text;
}
getPathAttributes() {
const { realRadius, gap, labelBgColor, flip, lineCap, strokeWidth } = this.getAttributes();
const angle = this.calculateAngle();
const { d } = this.calculateArcParameters(angle, realRadius, gap, flip);
return { d, strokeWidth, labelBgColor, lineCap };
}

getTextAttributes() {
const { labelColor, textAnchor, fitRange } = this.getAttributes();
return { labelColor, textAnchor, fitRange };
}

getAttributes() {
const orbitRadius = parseFloat(
getComputedStyle(this).getPropertyValue('r') || 0
)
const flip = this.hasAttribute('flip')
const fitRange = this.hasAttribute('fit-range')
const lineCap =
getComputedStyle(this).getPropertyValue('--o-linecap') || 'butt'
const gap = parseFloat(
getComputedStyle(this).getPropertyValue('--o-gap') || 0.001
)
const labelColor = this.getAttribute('label-color') || 'black'

const textAnchor = this.getAttribute('text-anchor') || 'start'

const labelBgColor = this.getAttribute('bg-color') || 'none'

const rawAngle = getComputedStyle(this).getPropertyValue('--o-angle')
const strokeWidth = parseFloat(
getComputedStyle(this).getPropertyValue('stroke-width') || 1
)
let strokeWithPercentage = ((strokeWidth / 2) * 100) / orbitRadius / 2
// default aligment at middle
let innerOuter = strokeWithPercentage
getAttributes() {
const orbitRadius = parseFloat(getComputedStyle(this).getPropertyValue('r') || 0);
const flip = this.hasAttribute('flip');
const fitRange = this.hasAttribute('fit-range');
const lineCap = getComputedStyle(this).getPropertyValue('--o-linecap') || 'butt';
const gap = parseFloat(getComputedStyle(this).getPropertyValue('--o-gap') || 0.001);
const labelColor = this.getAttribute('label-color') || 'black';
const textAnchor = this.getAttribute('text-anchor') || 'start';
const labelBgColor = this.getAttribute('bg-color') || 'none';
const rawAngle = getComputedStyle(this).getPropertyValue('--o-angle');
const strokeWidth = parseFloat(getComputedStyle(this).getPropertyValue('stroke-width') || 1);

let strokeWithPercentage = ((strokeWidth / 2) * 100) / orbitRadius / 2;
let innerOuter = strokeWithPercentage;
if (this.classList.contains('outer-orbit')) {
innerOuter = strokeWithPercentage * 2
innerOuter = strokeWithPercentage * 2;
}
if (this.classList.contains('quarter-outer-orbit')) {
innerOuter = strokeWithPercentage * 1.75
innerOuter = strokeWithPercentage * 1.75;
}
if (this.classList.contains('inner-orbit')) {
innerOuter = 0
innerOuter = 0;
}
if (this.classList.contains('quarter-inner-orbit')) {
innerOuter = strokeWithPercentage * 0.75
innerOuter = strokeWithPercentage * 0.75;
}
const realRadius = 50 + innerOuter - strokeWithPercentage
const labelAngle = calcularExpresionCSS(rawAngle)
const realRadius = 50 + innerOuter - strokeWithPercentage;
const labelAngle = calcularExpresionCSS(rawAngle);

return {
orbitRadius,
strokeWidth,
Expand All @@ -185,12 +170,12 @@ getAttributes() {
textAnchor,
lineCap,
fitRange
}
};
}

calculateAngle() {
const { labelAngle, gap } = this.getAttributes()
return labelAngle - gap
const { labelAngle, gap } = this.getAttributes();
return labelAngle - gap;
}

calculateArcParameters(angle, realRadius, gap, flip) {
Expand All @@ -199,20 +184,33 @@ getAttributes() {
let startX, startY, endX, endY, largeArcFlag, d;

if (flip) {
startX = 50 - gap + radiusX * Math.cos(-Math.PI / 2);
startY = 50 + radiusY * Math.sin(-Math.PI / 2);
endX = 50 + radiusX * Math.cos(((270 - angle) * Math.PI) / 180);
endY = 50 + radiusY * Math.sin(((270 - angle) * Math.PI) / 180);
largeArcFlag = angle <= 180 ? 0 : 1;
d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 0 ${endX},${endY}`;
startX = 50 - gap + radiusX * Math.cos(-Math.PI / 2);
startY = 50 + radiusY * Math.sin(-Math.PI / 2);
endX = 50 + radiusX * Math.cos(((270 - angle) * Math.PI) / 180);
endY = 50 + radiusY * Math.sin(((270 - angle) * Math.PI) / 180);
largeArcFlag = angle <= 180 ? 0 : 1;
d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 0 ${endX},${endY}`;
} else {
startX = 50 + gap + radiusX * Math.cos(-Math.PI / 2);
startY = 50 + radiusY * Math.sin(-Math.PI / 2);
endX = 50 + radiusX * Math.cos(((angle - 90) * Math.PI) / 180);
endY = 50 + radiusY * Math.sin(((angle - 90) * Math.PI) / 180);
largeArcFlag = angle <= 180 ? 0 : 1;
d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 1 ${endX},${endY}`;
startX = 50 + gap + radiusX * Math.cos(-Math.PI / 2);
startY = 50 + radiusY * Math.sin(-Math.PI / 2);
endX = 50 + radiusX * Math.cos(((angle - 90) * Math.PI) / 180);
endY = 50 + radiusY * Math.sin(((angle - 90) * Math.PI) / 180);
largeArcFlag = angle <= 180 ? 0 : 1;
d = `M ${startX},${startY} A ${radiusX},${radiusY} 0 ${largeArcFlag} 1 ${endX},${endY}`;
}
return { startX, startY, endX, endY, largeArcFlag, d };
}
}

function calcularExpresionCSS(cssExpression) {
const match = cssExpression.match(/calc\(\s*([\d.]+)deg\s*\/\s*\(\s*(\d+)\s*-\s*(\d+)\s*\)\s*\)/);
if (match) {
const value = parseFloat(match[1]);
const divisor = parseInt(match[2]) - parseInt(match[3]);
if (!isNaN(value) && !isNaN(divisor) && divisor !== 0) {
return value / divisor;
}
}
}

//customElements.define('orbit-label', OrbitLabel);
Loading

0 comments on commit dd3d018

Please sign in to comment.