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">
<section id="example">
  <svg id="svg" width="420" height="220">
    <circle cx="100" cy="100" r="75" />
    <ellipse cx="300" cy="100" rx="75" ry="50" />
  </svg>
</section>

<section>
  <button id="button">Replace all circles and ellipses on pathes</button>
  <label><input type="checkbox" checked="1" id="unsave" />Delete eplaced</label>
</section>

<pre>
  <code id="display" class="lang-xml">
    ...
  </code>
</pre>

CSS

@import url(https://be5invis.github.io/Iosevka/fonts.css);
@import url(https://fonts.googleapis.com/css?family=Roboto+Condensed&subset=cyrillic);
:root, body, input, button {
  font: 14px/1.375 "Roboto Condensed", sans-serif;
}

:root {
  text-align: left;
  cursor: default;
}

circle, ellipse, path {
  fill: none;
  stroke-width: 10;
  stroke-opacity: .5
}

circle, ellipse {
  stroke: blue;
}

path {
  stroke: red;
}

code, pre {
  font: 14px/1.5 'IosevkaWEB', 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 1px 1px 0 0 rgba(0,0,0,.5);
  left: 1px;
  top: 1px;
}

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;
}
label {
  white-space: nowrap;
}

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);
  hljs.highlightBlock(display, hljs.tabReplace, false, true);
  console.log(hljs, display);
};

button.onclick = () => {
  replaceAllCirclesOnPathes(svg);
  updateDisplay();
};

updateDisplay();