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.
This demo uses D3 to create the patterns with SVG rectangles.
<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>
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;
}
// 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();
});