css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <svg id="svg" viewBox="-1 -1 167.217 85.619">
<defs>
  <g id="yes">
		<!--<circle id="bgyes" cx="42.658" cy="41.774" r="38.86"/>--> 
    <path id="bgyes" class="bg" d="M3.798,41.774C3.798,20.312 21.196, 2.914 42.658, 2.914 C64.12,2.914 81.518, 20.312 81.518, 41.774 C81.518,63.236 64.12, 80.634 42.658, 80.634C21.196214622772004,80.634 3.798, 63.235785377228 3.798, 41.774z"/>
    
		<path id="hidden_dot" d="M26.891,60.777C26.891 60.477 26.971 60.196 27.111 59.954 C27.253 59.708 27.457 59.502 27.701 59.358 C27.946 59.212 28.233 59.129 28.539 59.129 C28.807 59.129 29.059 59.193 29.282 59.306 C29.607 59.471 29.871 59.741 30.028 60.071 C30.130 60.285 30.187 60.524 30.187 60.778 C30.187 61.090 30.100 61.382 29.950 61.630 C29.799 61.880 29.584 62.086 29.327 62.226 C29.093 62.353 28.825 62.426 28.540 62.426 C28.231 62.426 27.941 62.341 27.694 62.192 C27.438 62.039 27.227 61.817 27.086 61.553 C26.961,61.322,26.891,61.058,26.891,60.777 z"/>
		<path id="ok" d="M12.427,48.296 C12.427 48.296 14.779 47.296 18.129 53.626 C21.480 59.956 24.775 69.908 24.775 69.908 C24.775, 69.908 25.426 68.774 28.778 66.540 C32.129 64.306 34.569 63.877 34.569 63.877 C34.569, 63.877 40.413 47.939 47.488 38.630 C54.562 29.322 69.084 17.779 69.084 17.779 C69.084, 17.779 67.595 16.661 66.850 15.545 C66.105,14.43,50.439,26.47,42.759,34.788 C35.123 43.059 27.981 55.690 27.981 55.690 C27.981, 55.690 25.557 45.668 22.542 44.590 C18.395,43.108,12.427,48.296,12.427,48.296 z"/>
	</g>
  
	<g id="no">
		<!--<circle id="bgno" cx="122.857" cy="41.774" r="38.86"/>-->
    <path id="bgno" class="bg" d="M83.997,41.774 C83.997,20.312 101.395, 2.914 122.857, 2.914 C144.31878537722798,2.914 161.717, 20.312 161.717, 41.774 C161.717,63.236 144.319, 80.634 122.857, 80.634 C101.395 ,80.634 83.997, 63.236 83.997, 41.774z"/>
    
		<path id="V" d="M113.034,16.209 C113.034 16.209 113.700 21.334 116.430 25.994 C119.160, 30.654 121.422 34.648 121.422 34.648 C121.422, 34.648 124.550 30.254 128.878 25.428 C133.204 20.602 138.263 16.541 139.262 16.541 C140.261, 16.541 145.786 23.530 145.654 24.662 C145.520 25.794 137.332 32.517 134.004 35.645 C130.676, 38.773 125.119 46.129 121.362 46.164 C119.231 46.184 112.703 36.577 111.105 34.048 C109.507 31.518 106.111 25.993 106.378 24.063 C106.644 22.132 107.110 20.801 109.041 19.137 C110.972,17.474,113.034,16.209,113.034,16.209 z"/>
		<path id="A" d="M121.03,40.64 C125.660 40.640 127.490 47.001 132.676 50.889 C134.566 52.306 142.042 56.964 145.655 55.552 C146.647 55.164 144.520 59.679 142.790 61.943 C141.060 64.206 140.061 65.538 138.663 65.471 C137.265 65.405 132.936 62.742 129.609 59.480 C126.282 56.218 123.019 51.026 122.288 51.092 C121.556 51.159 119.358 55.153 117.694 57.749 C116.030 60.345 113.300 65.538 112.635 65.804 C111.969 66.070 109.106 64.872 107.309 63.341 C105.512, 61.810 102.649 59.214 102.516 57.816 C102.383, 56.418 107.021 53.499 109.646 50.694 C115.907,44.001,115.708,40.64,121.03,40.64 z"/>
	</g>
  
	<g id="maybe">
		<!--<circle id="bgmaybe" cx="82.758" cy="41.774" r="38.86"/>-->
    <path id="bgmaybe" class="bg" d="M43.898,41.774 C43.898,20.312 61.296, 2.914 82.758, 2.914 C104.22,2.914 121.618, 20.312 121.618, 41.774 C121.618,63.235 104.22, 80.634 82.758, 80.634 C61.296,80.634 43.898, 63.236 43.898, 41.774z" />
    
		<path id="upper" d="M88.13,27.429 C84.664 21.203 73.485 30.225 72.153 30.025 C70.822 29.826 67.094 24.567 67.094 22.703 C67.094, 20.839 77.345 13.983 84.535 14.316 C87.494 14.453 91.245 14.667 94.238 16.113 C98.516 18.180 101.588 22.256 101.509 27.896 C101.376 37.481 89.261 42.807 87.797 45.803 C86.332 48.799 87.997 50.130 87.198 50.995 C86.399 51.860 83.803 52.659 82.205 52.526 C80.607 52.393 77.944 52.326 77.279 51.594 C76.613 50.862 76.281 45.936 77.146 43.340 C78.011,40.743,91.724,33.886,88.13,27.429 z"/>
		<path id="dot" d="M75.349,63.578 C75.349 62.379 75.669 61.255 76.228 60.286 C76.796 59.303 77.610 58.480 78.586 57.903 C79.568 57.321 80.714 56.988 81.938 56.988 C83.007 56.988 84.015 57.242 84.907 57.694 C86.210 58.353 87.264 59.431 87.892 60.751 C88.300 61.608 88.528 62.566 88.528 63.579 C88.528 64.826 88.181 65.992 87.579 66.987 C86.975 67.986 86.113 68.811 85.086 69.370 C84.151 69.879 83.079 70.169 81.938 70.169 C80.701 70.169 79.543 69.828 78.554 69.236 C77.530 68.622 76.687 67.737 76.122 66.681 C75.629,65.756,75.349,64.699,75.349,63.578 z"/>
	</g>
  </defs>  
  
  
 	<path id="base" d="M0.001,41.774C-0.136,18.067,18.583,0.126,40.756,0.077s66.23,0.502,85.253-0.062
		c19.023-0.565,39.046,15.154,39.207,40.625s-20.348,42.81-39.207,42.902c-18.859,0.092-64.289,0.161-85.253-0.148
		S0.146,66.785,0.001,41.774z"/> 
    
  <path id="_bgCircle" d="" />
  <path id="_p1"       d="" />
  <path id="_p2"       d="" />

</svg>
<div id="buttons">
  <input type="radio" name="yesMaybeNo" id="rYes" checked />
  <label for="rYes">Yes</label>

  <input type="radio" name="yesMaybeNo" id="rMaybe" />
  <label for="rMaybe">Maybe</label>

  <input type="radio" name="yesMaybeNo" id="rNo" />
  <label for="rNo">No</label>
</div>
            
          
!
            
              body{overflow:hidden;background: #1e2730;color:linen; font-family: verdana}
svg {
  width: 10em;
  /*border: 1px solid #d9d9d9;*/
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
path{fill:linen;}
#buttons{text-align:center; margin:1em;}

#base{fill:linen}
#_bgCircle{fill:#1e2730;}
            
          
!
            
              let rid = null;
const spring = 0.1;
const friction = 0.7;


let centers = {
  rNo: 122.857,
  rMaybe: 82.758,
  rYes: 42.658
};

class pathsTriptych {
  constructor(thePath, yes, no, maybe) {
    this.path = thePath;
    this.yes = yes;
    this.maybe = maybe;
    this.no = no;
    this.vals = this.getArgsRy(maybe);
    this.target;
    this.vel = this.initRy();
  }

  initRy() {
    let Ry = [];
    this.vals.map(t => {
      let ry = [];
      t.map(() => {
        ry.push(0);
      });
      Ry.push(ry);
    });
    return Ry;
  }

  getArgsRy(path) {
    let d = path.getAttribute("d").replace(/\r?\n|\r/g, ""); //remove breaklines
    if (d.charAt(0) == "m") {
      d = "M" + d.slice(1);
    }
    let argsRX = /(?=[a-zA-Z])/;
    let args = d.split(argsRX);

    //console.log(args)

    let ArgsRy = [];

    args.map(arg => {
      let argRy = arg
        .slice(1)
        .replace(/\-/g, " -")
        .split(/[ ,]+/);
      argRy.map((p, i) => {
        if (p == "") {
          argRy.splice(i, 1);
        }
      });
      //argRy.map((e) =>{e = parseFloat(e); console.log(e)})
      for (let i = 0; i < argRy.length; i++) {
        argRy[i] = parseFloat(argRy[i]);
      }

      argRy.unshift(arg[0]);
      ArgsRy.push(argRy);
    });
    //console.log(ArgsRy)
    return ArgsRy;
  }

  morph() {
    let newD = "";

    this.vals.map((v, vi) => {
      let newStr = v[0];
      for (let i = 1; i < v.length; i++) {
        this.updateProp(vi, i);

        newStr += v[i].toFixed(3) + " ";
      }
      newD += newStr + " ";
    }); //
    this.path.setAttributeNS(null, "d", newD);
    //console.log(this.path,newD);
  }

  updateProp(vi, i) {
    let dist = this.target[vi][i] - this.vals[vi][i];
    let acc = dist * spring;
    this.vel[vi][i] += acc;
    this.vel[vi][i] *= friction;
    this.vals[vi][i] += this.vel[vi][i];
  }

  sayNO() {
    this.target = this.getArgsRy(this.no);
    //console.log("sayNO");
  }
  sayMAYBE() {
    this.target = this.getArgsRy(this.maybe);
    //console.log("sayMAYBE");
  }

  sayYES() {
    this.target = this.getArgsRy(this.yes);
    //console.log("sayYES");
  }
}

let triptychs = [];

//                                          yes         no    maybe
triptychs.push(new pathsTriptych(_bgCircle, bgyes, bgno, bgmaybe));
triptychs.push(new pathsTriptych(_p1, hidden_dot, A, dot));
triptychs.push(new pathsTriptych(_p2, ok, V, upper));


rYes.addEventListener("change", onChangeEvent);
rMaybe.addEventListener("change", onChangeEvent);
rNo.addEventListener("change", onChangeEvent);


function Frame() {
  rid = window.requestAnimationFrame(Frame);
  triptychs.map(t => {
    t.morph();
  });
}

triptychs.map(t => {
  t.target = t.getArgsRy(t.yes);
  t.morph();
});

Frame();

base.addEventListener("click", function(e) {
  let _x = oMousePosSVG(svg, e).x;

  let max = 284.859;
  let position;
  for (var key in centers) {
    if (centers.hasOwnProperty(key)) {
      let dist = Math.abs(centers[key] - _x);
      if (dist < max) {
        max = dist;
        position = key;
      }
    }
  }

  let thisRadio = document.getElementById(position);
  thisRadio.checked = true;

  ifRadioChecked(thisRadio);
});

//helpers

function ifRadioChecked(radio) {
  if (rid) {
    window.cancelAnimationFrame(rid);
    rid = null;
  }

  let prop = radio.id.substr(1).toLowerCase();
  triptychs.map(t => {
    t.target = t.getArgsRy(t[prop]);
  });
  Frame();
}

function onChangeEvent() {
  if (this.checked == true) {
    ifRadioChecked(this);
  }
}

function oMousePosSVG(svg, e) {
  let p = svg.createSVGPoint();
  p.x = e.clientX;
  p.y = e.clientY;
  let ctm = svg.getScreenCTM().inverse();
  p = p.matrixTransform(ctm);
  return p;
}

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console