SVG: Replace all Ellipse on Pathes (2)
by denvdmj
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/androidstudio.min.css">
<link rel="stylesheet" href="https://codepen.io/DenVdmj/pen/NBGQxq.css">
<svg id="svg" width="420" height="220">
<circle cx="100" cy="100" r="75" />
<ellipse cx="300" cy="100" rx="75" ry="50" />
</svg>
<button id="button">Replace all circles and ellipses on pathes</button>
<pre>
<code id="display" class="lang-xml">
...
</code>
</pre>
CSS
:root, body, input, button {
font: 14px/1.375 "Roboto Condensed", sans-serif;
}
:root {
text-align: left;
cursor: default;
}
svg {
display: block;
}
circle, ellipse, path {
fill: none;
stroke-width: 10;
stroke-opacity: .5
}
circle, ellipse {
stroke: blue;
}
path {
stroke: red;
}
code, pre {
font: 14px/1.5 coding-local, coding, 'Iosevka Web', monospace;
}
code {
display: block;
margin: 1em 0;
padding: 5em 0 1em 5em !importnat;
background: #1d1f21 !important;
color: #fff;
}
button {
display: inline-block;
border: 1px solid #B5B5B5;
background: #FFF;
padding: .6em 2em .6em 2em;
margin: .1em;
text-align: center;
text-decoration: none;
border-radius: .1em;
box-shadow: 2px 2px 0 0 rgba(0,0,0,.1), inset 0 0 0 0 transparent;
transition: all .15s ease-out;
cursor: default;
outline: none;
position: relative;
}
button:hover {
color: #555;
text-shadow: #fff 0 0 2px;
box-shadow: 2px 2px 10px 0 rgba(0,0,0,.3), inset 0 0 0 0 transparent;
}
button:active {
color: #900;
background: #f8f8f8;
box-shadow: 0 0 0 0 transparent, inset 0px 18px 0 0 rgba(0,0,0,.06);
left: 1px;
top: 1px;
}
label, button {
user-select: none;
}
JavaScript
const ellipsePath = (cx, cy, rx, ry) =>
`M${cx-rx} ${cy}a${rx},${ry} 0 1 0 ${2*rx} 0a${rx},${ry} 0 1 0 ${-2*rx} 0`
;
const replaceCircleOnPath = (el) => {
const ns = 'http://www.w3.org/2000/svg';
const path = document.createElementNS(ns, 'path');
const r = el.getAttribute('r');
path.setAttribute('d', ellipsePath(
+(el.getAttribute('cx')),
+(el.getAttribute('cy')),
+(el.getAttribute('rx') || r),
+(el.getAttribute('ry') || r)
));
el.parentNode.insertBefore(path, el);
el.parentNode.removeChild(el);
};
const replaceAllCirclesOnPathes = (svg) => {
for (let el of svg.querySelectorAll('circle, ellipse')) {
replaceCircleOnPath(el);
}
};
const updateDisplay = () => {
display.textContent =
(new XMLSerializer()).serializeToString(svg);
// display.textContent = (new DOMParser) // for nice code
// .parseFromString(svg.outerHTML, 'image/svg+xml')
// .documentElement.outerHTML;
hljs.highlightBlock(display, hljs.tabReplace, false, true);
console.log(hljs, display);
};
button.onclick = () => {
replaceAllCirclesOnPathes(svg);
updateDisplay();
};
updateDisplay();