Built with blockbuilder.org
forked from walkerjeffd's block: Spinning Ovals II
| license: mit |
Built with blockbuilder.org
forked from walkerjeffd's block: Spinning Ovals II
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| .stop-left { | |
| stop-color: rgba(0, 192, 191, 1); /* Indigo */ | |
| } | |
| .stop-right { | |
| stop-color: rgba(44, 161, 252, 1); /* Teal */ | |
| } | |
| .outlined { | |
| fill: none; | |
| stroke: url(#mainGradient); | |
| } | |
| ellipse { mix-blend-mode: normal; } | |
| .isolate { isolation: isolate; } | |
| </style> | |
| </head> | |
| <body> | |
| <script> | |
| var gui = new dat.GUI(); | |
| var ellipseFactor = 0.92352 , | |
| speed = 10000, | |
| omega = 180, | |
| scale = 1, | |
| strokeWidth = 38, | |
| blur = 0, | |
| n = 2, | |
| minRadius = 100, | |
| radiusFactor = 1.04, | |
| pulseFactor = 4; | |
| var opacity = 0.4; | |
| // var opacity = 1/n; | |
| gui.add(window, "n", 1, 20).step(1).onChange(restart); | |
| gui.add(window, "speed", 100, 20000).step(100); | |
| gui.add(window, "strokeWidth", 0, 100).step(10); | |
| gui.add(window, "ellipseFactor", 0.1, 2).step(0.01); | |
| gui.add(window, "opacity", 0, 1).step(0.01); | |
| gui.add(window, "blur", 0, 10).step(0.1); | |
| gui.add(window, "pulseFactor", 0, 100); | |
| gui.add(window, "radiusFactor", 1, 2).step(0.01); | |
| gui.add(window, "omega", 0, 360).step(1); | |
| var width = 960, | |
| height = 500; | |
| var svg = d3.select('body').append('svg') | |
| .attr('width', width) | |
| .attr('height', height) | |
| .append('g') | |
| .attr('class', 'isolate') | |
| .attr('transform', 'scale(' + scale + ')') | |
| var defs = svg.append('defs'); | |
| // Color gradient | |
| var mainGradient = defs.append('linearGradient') | |
| .attr('id', 'mainGradient'); | |
| mainGradient.append('stop') | |
| .attr('class', 'stop-left') | |
| .attr('offset', '0'); | |
| mainGradient.append('stop') | |
| .attr('class', 'stop-right') | |
| .attr('offset', '1'); | |
| // Filter for the outside glow | |
| var filter = defs.append('filter') | |
| .attr('id', 'glow'); | |
| var feGaussianBlur = filter.append('feGaussianBlur') | |
| .attr('stdDeviation', blur) | |
| .attr('result','coloredBlur'); | |
| var feMerge = filter.append('feMerge'); | |
| feMerge.append('feMergeNode') | |
| .attr('in', 'coloredBlur'); | |
| feMerge.append('feMergeNode') | |
| .attr('in', 'SourceGraphic'); | |
| // Shapes | |
| var ellipse; | |
| function restart() { | |
| console.log("restart", n); | |
| var data = d3.range(n); | |
| svg.selectAll('ellipse').remove(); | |
| var ellipseSel = svg.selectAll('ellipse') | |
| .data(data); | |
| ellipse = ellipseSel | |
| .enter() | |
| .append('ellipse') | |
| .classed('outlined', true) | |
| .style('filter', 'url(#glow)') | |
| .style('opacity', opacity) | |
| .style('stroke-width', strokeWidth) | |
| .attr('cx', width / 2) | |
| .attr('cy', height / 2) | |
| .attr('rx', 100 * ellipseFactor) | |
| .attr('ry', 100) | |
| ellipseSel.exit().remove(); | |
| ellipse.each(function (d) { | |
| var theta = d / n * omega; | |
| d3.select(this) | |
| .attr('transform', 'rotate(' + theta + ',' + width/2 + ',' + height/2 + ')'); | |
| }); | |
| } | |
| restart(); | |
| d3.timer(function (elapsed) { | |
| feGaussianBlur.attr('stdDeviation', blur); | |
| ellipse | |
| .style('opacity', opacity) | |
| .style('stroke-width', strokeWidth) | |
| .attr('rx', 100 * ellipseFactor); | |
| ellipse.each(function (d) { | |
| var theta = elapsed % speed / speed * 360 + d / n * omega, | |
| r = minRadius + (minRadius * radiusFactor - minRadius) * (Math.sin(((elapsed % speed * pulseFactor) / speed) * 2 * Math.PI) / 2 + 0.5); | |
| d3.select(this) | |
| .attr('transform', 'rotate(' + theta + ',' + (width/2) + ',' + (height/2) + ')') | |
| .attr('rx', r * ellipseFactor) | |
| .attr('ry', r); | |
| }) | |
| }) | |
| </script> | |
| </body> |