Exact percentage SVG fill #1

by dannye

HTML

Next challenge: how to make the blue lines not draw *outside* the shape.
<p>
The *area* is the length of all blue lines
</p>
<svg-fill>
  <svg height="500" style="background:pink" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <path d="M10,30A20,20,0,0,1,50,30A20,20,0,0,1,90,30Q90,60,50,90Q10,60,10,30z" fill="lightgreen" stroke="blue"></path>
  </svg>
</svg-fill>
<script>
  customElements.define("svg-fill", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => {
        this.svg = this.querySelector("svg");
        this.path = this.querySelector("path");
        let len = this.path.getTotalLength();
        let [y1, y2, x1, x2] = [0, 100, 0, 100];
        let points = [];
        let step = 3; // set to lower value for more points
        // loop compelete pathlenght at step to reduce points
        for (let i = 0; i < len; i += step) {
          let {
            x,
            y
          } = this.path.getPointAtLength(i);
          if (i == 0) this.circle(x, y, "red", 2); // mark start of <path>
          //calculate boundaries
          if (y < y2) y2 = y;
          if (y > y1) y1 = y;
          if (x > x1) x1 = x;
          if (x < x2) x2 = x;
          points.push(this.circle(x, y)); // draw all circles on <path>
        }
        // find lowest circle
        let start = points.filter(circle => circle.y == y1)[0];
        // now points Array starts at correct blue circle
        points.push(...points.splice(0, points.indexOf(start)));
        // proces HALF of the array
        points.slice(0, points.length / 2).map(pt => {
          pt.show("blue");
          this.line(pt, {
            x: 50,
            y: pt.y
          }); // draw line to center
          //! TODO: how can we draw right to heart-path intersection
        })
        points[0].show("blue", 2); // correct start point
      });
    }
    circle(cx, cy, fill = "green", size = 1, stroke = 0) {
      let circle =...