Last active
October 15, 2016 16:53
-
-
Save davo/b7e40d262c9f7a95197f630fd3efd189 to your computer and use it in GitHub Desktop.
d3 unconf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title></title> | |
<style> | |
#generative svg { | |
width: 100%; | |
height: 100%; } | |
#generative path { | |
fill-opacity: 0; | |
stroke-width: 0; | |
stroke-linecap: round; } | |
</style> | |
<body> | |
<div id="generative"></div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script> | |
<script src="https://cdn.rawgit.com/jwagner/simplex-noise.js/master/simplex-noise.min.js"></script> | |
<script> | |
// This block is largely inspired / based on the work of Christopher Manning | |
// https://gist.github.com/christophermanning/4289018 | |
// Setting up the SVG position | |
var margin = {top: 0, right: 0, bottom: 0, left: 0}, | |
width = window.innerWidth - margin.left - margin.right, | |
height = window.innerHeight - margin.top - margin.bottom; | |
var config = { "waves": 100, "width": 90, "x": 50, "y": 20, "dy": 11, "amplitude": 20, "velocity": 60}; | |
var scrollObject = {}, | |
active = true; | |
var generative = document.getElementById("generative"); | |
// Create an array with the compatible widths. | |
// then calculate | |
var offset = 120; | |
if (window.innerWidth >= 1920) { | |
config["waves"] = 110; | |
config["dy"] = 10; | |
offset = 500; | |
} else if (window.innerWidth >= 1280) { | |
config["waves"] = 90; | |
config["dy"] = 12; | |
offset = 120; | |
} else if (window.innerWidth >= 960) { | |
config["waves"] = 70; | |
config["dy"] = 12; | |
} else if (window.innerWidth >= 720) { | |
config["waves"] = 50; | |
config["dy"] = 13; | |
} else if (window.innerWidth >= 480) { | |
config["waves"] = 40; | |
config["dy"] = 15; | |
} | |
if (window.innerHeight >= 800) { | |
config["width"] = 110; | |
} else if (window.innerHeight <= 799) { | |
config["width"] = 100; | |
} | |
// Scales for the mouse capture | |
var widthScale = d3.scale.linear() | |
.domain([0,width]) | |
.range([20,50]); | |
var heightScale = d3.scale.linear() | |
.domain([0,height]) | |
.range([20,15]); | |
var mouseXPosition = d3.scale.linear() | |
.domain([0,width]) | |
.range([config["waves"],0]); | |
var scrollPositionScale = d3.scale.linear() | |
.domain([0,600]) | |
.range([1,0]); | |
var positionAffectsPath, | |
affectedPaths = []; | |
window.onscroll = getScrollPosition; | |
function getScrollPosition(){ | |
scrollObject = { | |
x: window.pageXOffset, | |
y: window.pageYOffset | |
} | |
config["x"] = 50 + scrollObject.y * 0.5; | |
svg.selectAll("#group") | |
.style("opacity", scrollPositionScale(scrollObject.y).toFixed(5)); | |
if (scrollObject.y <= height) { | |
active = true; | |
d3.select('#generative') | |
.style("visibility","visible"); | |
} else if (scrollObject.y > height+1) { | |
active = false; | |
d3.select('#generative') | |
.style("visibility","hidden"); | |
} | |
} | |
function mouseMove(){ | |
var point = [0,0]; | |
point = d3.mouse(this); | |
var p = {x: point[0], y: point[1] }; | |
config["amplitude"] = widthScale(p.x); | |
config["y"] = heightScale(p.y); | |
positionAffectsPath = Math.ceil(mouseXPosition(p.x)); | |
if (positionAffectsPath > 0 && p.x <= window.innerWidth){ | |
d3.select("#line-"+positionAffectsPath) | |
.transition() | |
.style("stroke-width", "1.25") | |
.duration(200) | |
.transition() | |
.delay(200) | |
.style("stroke-width", "0.25") | |
.duration(300); | |
} | |
}; | |
// Setup SVG | |
var svg = d3.select("#generative").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.attr("viewBox", "0 0 "+width+" "+height+""); | |
d3.select("#generative").on("mousemove", mouseMove); | |
var g = svg.append("g") | |
.attr("id","group") | |
.attr("transform", "translate("+((width*0.8)+offset)+" 0) rotate(90 0 0)"); | |
var path = g.selectAll("path"), | |
simplex = new SimplexNoise(); | |
// Adding an animated gradient based on the example by Nadieh Bremer | |
// http://bl.ocks.org/nbremer/6f5b472cabe8f85583989a40eef0303c | |
// Rotated and kinda synced to the inverse position of the rotated path | |
var defs = svg.append("defs") | |
var linearGradient = defs.append("linearGradient") | |
.attr("id","animate-gradient") | |
.attr("x1","0%") | |
.attr("y1","100%") | |
.attr("x2","0%") | |
.attr("y2","0%") | |
.attr("spreadMethod", "reflect"); | |
var colours = ["#E6C5DC", "#CCADCD", "#B295BE", "#987DAF", "#7D669F", "#634E90", "#493681", "#2F1E72"]; | |
linearGradient.selectAll(".stop") | |
.data(colours) | |
.enter().append("stop") | |
.attr("offset", function(d,i) { return i/(colours.length-1); }) | |
.attr("stop-color", function(d) { return d; }); | |
linearGradient.append("animate") | |
.attr("attributeName","y1") | |
.attr("values","0%;100%") | |
.attr("dur","12s") | |
.attr("repeatCount","indefinite"); | |
linearGradient.append("animate") | |
.attr("attributeName","y2") | |
.attr("values","100%;200%") | |
.attr("dur","12s") | |
.attr("repeatCount","indefinite"); | |
// Looping throught out the configurations and setting up the noise. | |
d3.timer(function(t){ | |
if(config["velocity"] == 0) return | |
data = [] | |
for (y = 1; y <= config["waves"]; y++) { | |
waves = [] | |
for (x = 1; x <= config["width"]; x++) { | |
waves.push([ | |
// Rounding down the coordinates into 2 digits generated by the loop and the noise. | |
(x * 8).toFixed(2), | |
((y*config["dy"])+simplex.noise3D(x/config["x"], | |
y/config["y"], | |
t/((80-config["velocity"])*100)) * config["amplitude"]).toFixed(2) | |
]) | |
} | |
data.push(waves) | |
} | |
path = path | |
.data(data) | |
// Adding path to the SVG & then adding the animated gradient | |
path.enter() | |
.insert("path") | |
.style("stroke", "url(#animate-gradient)") | |
.transition() | |
.style("stroke-width", "0.25") | |
.duration(3000); | |
path | |
.attr("d", function(d) { return "M" + d.map(function(d){ return d.join(",") }).join("L") }) | |
.attr("id", function(d,i) { return "line-" +i }) | |
path.exit() | |
.remove() | |
}); | |
// Circle to reference the desired position | |
d3.select(window).on("resize", resize); | |
function resize() { | |
// WIP Resize function to change d3 parameters and redraw the SVG | |
width = window.innerWidth | |
width = width - margin.left - margin.right; | |
if (window.innerWidth >= 1920) { | |
config["waves"] = 110; | |
config["dy"] = 10; | |
offset = 500; | |
} else if (window.innerWidth >= 1280) { | |
config["waves"] = 90; | |
config["dy"] = 12; | |
} else if (window.innerWidth >= 960) { | |
config["waves"] = 70; | |
config["dy"] = 12; | |
} else if (window.innerWidth >= 720) { | |
config["waves"] = 50; | |
config["dy"] = 13; | |
} else if (window.innerWidth < 480) { | |
config["waves"] = 40; | |
config["dy"] = 15; | |
} | |
if (window.innerHeight >= 1400) { | |
config["width"] = 200; | |
} else if (window.innerHeight <= 800) { | |
config["width"] = 110; | |
} else if (window.innerHeight <= 799) { | |
config["width"] = 100; | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment