Skip to content

Instantly share code, notes, and snippets.

@exakte-aesthetik
Last active February 23, 2016 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save exakte-aesthetik/0fd7231f2b39e8238240 to your computer and use it in GitHub Desktop.
Save exakte-aesthetik/0fd7231f2b39e8238240 to your computer and use it in GitHub Desktop.
Moirés with D3

Moirés with random deformed sine curves. Click on chart produces new random curves. Move mouse to translate a layer.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Moire</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
.curve,
.vertical-line {
fill: none;
stroke: steelblue;
stroke-width: 1px;
}
</style>
</head>
<body>
<script type="text/javascript">
var setupChart = {
"margin": {
"top": 10,
"right": 10,
"bottom": 10,
"left": 10
},
width: function() {return 960 - this.margin.left - this.margin.right;},
height: function() {return 500 - this.margin.top - this.margin.bottom;}
};
var curvesHorizontal = [];
var curvesVertical = [];
var sinH = [];
var sinV = [];
var mouseCoordinates = [];
var sinWidth = 1;
var sinAmp = 12;
var sinAmpMax = 20;
var sinAmpMin = 8;
var xDistance = 12;
var xDistanceMax = 20;
var xDistanceMin = 8;
var curveAmount = 400;
var curvesDistance = 4;
var yOffset = 0;
var xOffset = 0;
fillArrays();
var xScale = d3.scale.linear()
.range([0, setupChart.width()])
.domain([0, (setupChart.width()/4) - 1]);
var yScale = d3.scale.linear()
.range([setupChart.height(),0])
.domain([100,0]);
var line = d3.svg.line()
.x(function(d) { return xScale(d.x); })
.y(function(d) { return yScale(d.y); })
.interpolate("cardinal");
var svg = d3.select("body").append("svg")
.attr("width", setupChart.width() + setupChart.margin.left + setupChart.margin.right)
.attr("height", setupChart.height() + setupChart.margin.top + setupChart.margin.bottom)
.append("g")
.attr("transform", "translate(" + setupChart.margin.left + "," + setupChart.margin.top + ")")
.on("mousemove", mouseMove);
var clip = svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0")
.attr("width", setupChart.width())
.attr("height", setupChart.height());
var allCurves = svg.append("g").attr("class", "all-curves").attr("clip-path", "url(#clip)");
var curvesH = allCurves.append("g").attr("class", "curves-horizontal");
var curvesV = allCurves.append("g").attr("class", "curves-vertical");
update(curvesHorizontal, curvesVertical);
mouseClick();
function fillArrays(){
//empty the arrays
curvesHorizontal = [];
curvesVertical = [];
sinH = [];
sinV= [];
// fill the arrays
for (var i = 0; i < setupChart.width(); i = i+xDistance) {
var y = Math.sin(i/sinWidth)*sinAmp;
sinAmp = getRandomInt(sinAmpMin, sinAmpMax);
xDistance = getRandomInt(xDistanceMin, xDistanceMax);
sinH.push({"x": i, "y": y});
if(y < yOffset){
yOffset = y;
};
};
for (var i = 0; i < setupChart.height(); i = i+xDistance){
var x = Math.sin(i/sinWidth)*sinAmp;
sinAmp = getRandomInt(sinAmpMin, sinAmpMax);
xDistance = getRandomInt(xDistanceMin, xDistanceMax);
sinV.push({"x": x, "y": i});
if(x < xOffset){
xOffset = x;
};
};
for (var i = 0; i < curveAmount; i++){
curvesHorizontal.push(sinH);
curvesVertical.push(sinV);
};
};
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
};
function mouseMove(){
var coors = d3.mouse(this);
curvesV.transition().duration(100).ease("linear").attr("transform", "translate("
+ (coors[0] - (curveAmount*curvesDistance/2)) + ","
+ (coors[1] - (curveAmount*curvesDistance/2)) + ")");
}
function update(data1, data2){
// Datajoin data1
var pathH = curvesH.selectAll("path")
.data(data1);
// Update
pathH.attr("class", "curve");
// Enter
pathH.enter()
.append("path")
.attr("class", "curve");
pathH.attr("d", line)
.attr("transform", function(d,i){ return "translate(-2000," + (i*curvesDistance + yScale(yOffset)) + ")"});
// Exit
pathH.exit().remove();
// Datajoin data2
var pathV = curvesV.selectAll("path")
.data(data2);
// Update
pathV.attr("class", "curve");
// Enter
pathV.enter()
.append("path")
.attr("class", "curve");
pathV.attr("d", line)
.attr("transform", function(d,i){ return "translate(" + (i*curvesDistance + xScale(xOffset)) + ", 0)"});
// Exit
pathV.exit().remove();
};
function mouseClick(){
d3.select("svg")
.on("click", function(){
fillArrays();
update(curvesHorizontal, curvesVertical);
});
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment