Skip to content

Instantly share code, notes, and snippets.

@davo
Last active October 15, 2016 16:53
Show Gist options
  • Save davo/b7e40d262c9f7a95197f630fd3efd189 to your computer and use it in GitHub Desktop.
Save davo/b7e40d262c9f7a95197f630fd3efd189 to your computer and use it in GitHub Desktop.
d3 unconf
<!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