Skip to content

Instantly share code, notes, and snippets.

@pnavarrc
Last active May 4, 2016 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pnavarrc/df555a89d8aa590d61aa to your computer and use it in GitHub Desktop.
Save pnavarrc/df555a89d8aa590d61aa to your computer and use it in GitHub Desktop.
Moiré Patterns

Moiré Patterns

Moiré Patterns are patterns that results from overlapping two periodical patterns (series of straight lines, for instance). This demo allows to create Moiré patterns by changing the relative angle between the patterns, the number of bars, the bar width and the color of the bars.

Moiré Patterns

This demo uses D3 to create the patterns with SVG rectangles.

References

function barPattern() {
'use strict';
// Chart attributes
var me = {
width: 100,
height: 100
};
function chart(selection) {
selection.each(function(data) {
var grp = d3.select(this);
var items = d3.range(data.n),
angle = data.angle,
color = data.color;
var xScale = d3.scale.ordinal()
.domain(items)
.rangeBands([0, me.width], data.padding);
grp.transition().duration(1000)
.attr('transform', 'rotate(' + angle + ')');
var bars = grp.selectAll('rect.bar').data(items);
bars.enter().append('rect').classed('bar', true)
.attr('fill', color);
bars.transition().duration(1000)
.attr('x', function(d, i) { return xScale(i); })
.attr('width', xScale.rangeBand())
.attr('height', me.height)
.attr('fill', color);
bars.exit().remove();
});
}
// Accessor methods
chart.width = function(value) {
if (!arguments.length) { return me.width; }
me.width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) { return me.height; }
me.height = value;
return chart;
};
return chart;
}
<html>
<head>
<title>The Moiré Patterns</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.4/d3.min.js" charset="utf-8"></script>
<style>
.footer {
height: 100px;
}
.bar {
stroke: none;
stroke-width: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Moiré Pattern</h1>
Moiré Patterns are patterns that results from overlapping two periodical patterns (series of straight lines, for instance). This demo allows to create Moiré patterns by changing the relative angle between the patterns, the number of bars, the bar width and the color of the bars.
<form role="form">
<div class="form-group">
<label for="input-na">Bars</label>
<input id="input-na" type="number" min="80" max="112" step="1" value="105">
<label for="input-ta">Angle</label>
<input id="input-ta" type="number" min="-90" max="90" step="0.1" value="0">
<label for="input-pa">Padding</label>
<input id="input-pa" type="number" min="0.05" max="0.95" step="0.05" value="0.5">
<label for="input-ca">Color</label>
<input id="input-ca" type="color" value="#FF6B6B">
</div>
<div class="form-group">
<label for="input-nb">Bars</label>
<input id="input-nb" type="number" min="80" max="112" step="1" value="100">
<label for="input-tb">Angle</label>
<input id="input-tb" type="number" min="-90" max="90" step="0.1" value="0">
<label for="input-pb">Padding</label>
<input id="input-pb" type="number" min="0.05" max="0.95" step="0.05" value="0.5">
<label for="input-cb">Color</label>
<input id="input-cb" type="color" value="#4ECDC4">
</div>
</form>
<div id="patterns"></div>
<div class="footer"></div>
</div>
<script src="bar-pattern.js"></script>
<script src="main.js"></script>
</body>
</html>
// Define the width and height
var width = 800,
height = 600;
// Select the container div and create the SVG element
var div = d3.select('#patterns'),
svg = div.append('svg');
svg
.attr('width', width)
.attr('height', height);
// Create an instance of the bar pattern chart
var pattern = barPattern()
.width(width)
.height(height);
var data = [
{n: 105, angle: 0, padding: 0.5, color: '#FF6B6B'},
{n: 100, angle: 0, padding: 0.5, color: '#4ECDC4'}
];
function updatePattern() {
var groups = svg.selectAll('g.pattern').data(data);
groups.enter().append('g').classed('pattern', true);
groups.call(pattern);
}
updatePattern();
// Update the pattern when the user changes the input value
d3.select('#input-na').on('input', function() {
data[0].n = +this.value;
updatePattern();
});
d3.select('#input-ta').on('input', function() {
data[0].angle = +this.value;
updatePattern();
});
d3.select('#input-pa').on('input', function() {
data[0].padding = +this.value;
updatePattern();
});
d3.select('#input-ca').on('input', function() {
data[0].color = this.value;
updatePattern();
});
d3.select('#input-nb').on('input', function() {
data[1].n = +this.value;
updatePattern();
});
d3.select('#input-tb').on('input', function() {
data[1].angle = +this.value;
updatePattern();
});
d3.select('#input-pb').on('input', function() {
data[1].padding = +this.value;
updatePattern();
});
d3.select('#input-cb').on('input', function() {
data[1].color = this.value;
updatePattern();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment