Skip to content

Instantly share code, notes, and snippets.

@Chi-Loong
Last active December 7, 2016 16:50
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 Chi-Loong/020e3953e7942b713db31f4bca46a588 to your computer and use it in GitHub Desktop.
Save Chi-Loong/020e3953e7942b713db31f4bca46a588 to your computer and use it in GitHub Desktop.
Optical Illusions with dots

One in a series of experiments on using D3 to generate a SVG and then the Greensock library to animate the SVG elements.

Inspired by this excellent Numberphile video on Moiré optical illusions, I built this example to showcase this optical illusion.

Notice when you rotate one of the layers slightly you get the illusion that there is a circular hole of sorts. Rotate too much and the effect is lost.

When you move the layer in the leftwards direction, the circular hole moves up. If you move the layer upwards, the circular hole appears to move right. Professor Tadashi Tokieda explains why in the excellent video.

Layers are colored red and blue to more easily distinguish between the two layers.

For the whole series of experiments you can check out: A Study in Moiré Patterns

There is a UI interface there for people to manipulate the layers on this particular example.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.styleBlue {
fill: #33f;
}
.styleRed {
fill: #f33;
}
</style>
</head>
<body>
<div style="text-align:center">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="dotsvg" viewBox="0 0 960 500">
</svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script>
var t1 = new TimelineLite();
var numberDots = 2000,
dotSize = 3;
function drawLayers() {
var layer0 = d3.select("svg#dotsvg")
.append("g")
.attr("id", "layer0");
var layer1 = d3.select("svg#dotsvg")
.append("g")
.attr("id", "layer1");
for (var j=0; j<numberDots; j++) {
var xPosition = Math.random() * 960;
var yPosition = Math.random() * 500;
layer0
.append("circle")
.attr("class", "styleBlue")
.attr("cx", xPosition)
.attr("cy", yPosition)
.attr("r", dotSize);
layer1
.append("circle")
.attr("class", "styleRed")
.attr("cx", xPosition)
.attr("cy", yPosition)
.attr("r", dotSize);
}
}
function animateLayers() {
t1.to("svg#dotsvg g#layer1", 2, {rotation:5, transformOrigin:"50% 50%"}, 2);
t1.to("svg#dotsvg g#layer1", 2, {x:-10, transformOrigin:"50% 50%"}, 4);
t1.to("svg#dotsvg g#layer1", 2, {y:-10, transformOrigin:"50% 50%"}, 6);
t1.to("svg#dotsvg g#layer1", 2, {rotation:45, transformOrigin:"50% 50%"}, 8);
}
drawLayers();
animateLayers();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment