Built with blockbuilder.org
forked from anonymous's block: fresh block
| license: mit |
Built with blockbuilder.org
forked from anonymous's block: fresh block
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| </style> | |
| </head> | |
| <body> | |
| <script> | |
| var width = 960 | |
| var height = 500 | |
| // Feel free to change or delete any of the code you see in this editor! | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", 960) | |
| .attr("height", 500) | |
| document.documentElement.style.setProperty("--x-value", "2px") | |
| var defs = svg.append("defs") | |
| var testMask = defs.append("mask") | |
| .attr("id", "test-mask") | |
| .attr("maskUnits", "userSpaceOnUse") | |
| .attr("x", 0) | |
| .attr("y", 0) | |
| .attr("width", width) | |
| .attr("height", height) | |
| testMask.append('rect') | |
| .attr('x', 0) | |
| .attr('y', 0) | |
| .attr('width', width) | |
| .attr('height', height) | |
| .attr('fill', "white") | |
| testMask.append('circle') | |
| .attr('cx', width / 2) | |
| .attr('cy', height / 2) | |
| .attr('r', 200) | |
| .attr('opacity', 1) | |
| .attr('fill', "black") | |
| var bottomLayer = svg.append('g') | |
| .attr("style", "transform: translate(0,190px) rotateX(60deg)") | |
| var testRect = bottomLayer.append("rect") | |
| .attr("width", width) | |
| .attr("height", height) | |
| .attr("fill", "#0000ff") | |
| var limit = 50 | |
| var createMask = (id, radius) => { | |
| var m = defs.append("mask") | |
| .attr("id", id) | |
| .attr("maskUnits", "userSpaceOnUse") | |
| .attr("x", -2000) | |
| .attr("y", -1000) | |
| .attr("width", 4000) | |
| .attr("height", 2000) | |
| m.append('rect') | |
| .attr('x', -2500) | |
| .attr('y', -2500) | |
| .attr('width', 5000) | |
| .attr('height', 5000) | |
| .attr('fill', "white") | |
| m.append('circle') | |
| .attr('cx', width / 2) | |
| .attr('cy', height / 3) | |
| .attr('r', radius) | |
| .attr('opacity', 1) | |
| .attr('fill', "black") | |
| } | |
| var recursivelyDrawLayers = (layer, i) => { | |
| if (i < limit) { | |
| var dy = Math.pow(1.085, i) * 0.7 | |
| var nextLayer = layer.append('g') | |
| .attr("style", `transition: all 0.03s; transform: translate3D(var(--x-value), ${dy}px, 0)`) | |
| recursivelyDrawLayers(nextLayer, i + 1) | |
| } | |
| var maskId = "mask-" + i | |
| createMask(maskId, 160 + 800 * Math.pow(0.91, i) - i / 3) | |
| var rectFill = (i % 2 === 0) ? "#fff" : "#000" | |
| var rect = layer.append('rect') | |
| .attr('x', -2500) | |
| .attr('y', -2500) | |
| .attr('width', 5000) | |
| .attr('height', 5000) | |
| .attr('fill', rectFill) | |
| .attr("mask", `url(#${maskId})`) | |
| } | |
| recursivelyDrawLayers(bottomLayer, 0) | |
| var pixel = 0 | |
| svg.on('mousemove', (e) => { | |
| var m = d3.mouse(svg.node()) | |
| var xRatio = m[0] / width | |
| pixel = xRatio * 8 - 4 | |
| }) | |
| var setStyle = () => { | |
| document.documentElement.style.setProperty("--x-value", `${pixel}px`) | |
| setTimeout(setStyle, 300) | |
| } | |
| setTimeout(setStyle, 300) | |
| </script> | |
| </body> |