<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Circle wave</title> <script src="https://d3js.org/d3.v4.js"></script> <script src="https://unpkg.com/d3-canvas-transition@0.3.7/build/d3-canvas-transition.js"></script> <style> #panel { background-color: rgba(245,245,245,0.9); padding: 5px; position: absolute; display: block; } </style> </head> <body> <div id="panel"> <div id="paper"> <label> <input id='svg' name="type" type="radio" checked> <span>svg</span> </label> <label> <input id='canvas' name="type" type="radio"> <span>canvas</span> </label> </div> <div id="fps">FPS: <span>?</span></div> </div> <div id="example" style="max-width: 960px"></div> <script> (function () { d3.select('#svg').on('click', function () { draw('svg'); }); d3.select('#canvas').on('click', function () { draw('canvas'); }); if (d3.resolution() > 1) { d3.select('#paper').append('label').html( "<input id='canvas-low' name='type' type='radio'><span>canvas low resolution</span>" ); d3.select('#canvas-low').on('click', function () { draw('canvas', 1); }); } var angles = d3.range(0, 2 * Math.PI, Math.PI / 200), fps = d3.select("#fps span"), time0 = d3.now(), frames = 0, time1; draw('svg'); d3.timer(function () { path.attr("d", function (d) { return d(angles); }); frames++; time1 = d3.now(); if (time1 - time0 > 1000) { fps.text(Math.round(1000*frames/(time1 - time0))); time0 = time1; frames = 0; } }); function draw(type, r) { var example = d3.select("#example"), width = d3.getSize(example.style('width')), height = Math.min(500, width); example.select('.paper').remove(); var paper = example .append(type) .classed('paper', true) .attr('width', width).attr('height', height).canvasResolution(r).canvas(true); path = paper.append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .attr("fill", "none") .attr("stroke-width", 10) .attr("stroke-linejoin", "round") .selectAll("path") .data(["#f03b20", "#2c7fb8", "#31a354"]) .enter().append("path") .attr("stroke", function (d) { return d; }) .style("mix-blend-mode", "darken") .datum(function (d, i) { return d3.radialLine() .curve(d3.curveLinearClosed) .angle(function (a) { return a; }) .radius(function (a) { var t = d3.now() / 1000; return 200 + Math.cos(a * 8 - i * 2 * Math.PI / 3 + t) * Math.pow((1 + Math.cos(a - t)) / 2, 3) * 32; }); }); } }()); </script> </body>