JSFiddle - React, Tailwind, and code Playground

by rwaldin

HTML

<script src="https://raw.github.com/rwaldin/d3.stage/master/dist/d3.stage.js"></script>
<svg></svg>

JavaScript

function heartY(x,density,off, beat) {
    return ((Math.sqrt(Math.cos(x*beat)) *
                Math.cos(density*(x*beat+off))+Math.sqrt(Math.abs(x*beat))-0.4)*
            Math.pow((4-x*x), 0.1))/beat;
}

var svg = d3.select('svg').append('g').attr('transform','scale(200,-200) translate(3,-2)'),
    density = 65,
    interval = 1/(density*10);

function computePoints(density, interval, xOffset, beat) {
    var points = [];

    for(var x = -2; x < 2; x += interval) {
        var y = heartY(x, density,xOffset, beat);
        if(!isNaN(y)) {
            points.push([x,y]);
        }
    }
    return points;
}

var points = computePoints(density, interval, 0, 1);

var pline = svg.append('polyline').style('stroke','red').style('fill', 'transparent').style('stroke-width','0.02');
var i = 0,
    anim = setInterval(function() {
        if(points.length <= i) {
            clearInterval(anim);
            svg.selectAll('circle').remove();
            anim = setInterval(wiggle, 25, 0.005);
        } else {
            pline.attr('points', points.slice(0,i).map(function(p) {return p.join(',');}).join(' '));
            svg.stage('circle', [points[i]], function(enter,transition) {
                enter().attr('r', 0.03).attr('cx', function(d){return d[0]})
                    .attr('cy', function(d){return d[1];});
                transition().duration(20)
                    .attr('cx', function(d){return d[0]})
                    .attr('cy', function(d){return d[1];})

            });
        }
        i++;
    }, 20);

var xOffset = 0;
function wiggle(xOffsetInterval) {
    xOffset += xOffsetInterval;
    points = computePoints(density, interval, xOffset, 1);
    pline.attr('points', points.map(function(p) {return p.join(',');}).join(' '));
    if(Math.abs(xOffset) >= 1.5) {
        clearInterval(anim);
        setTimeout(function() {
            if(xOffset > 0) {
                anim = setInterval(wiggle, 25, -0.005);
            } else {
                anim =...