Skip to content

Instantly share code, notes, and snippets.

@kbseah
Last active July 24, 2020 21:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kbseah/7815b861ee3b3fbc0a939815d0b8e5bb to your computer and use it in GitHub Desktop.
Save kbseah/7815b861ee3b3fbc0a939815d0b8e5bb to your computer and use it in GitHub Desktop.
Pulfrich effect - Moving scenery

Pulfrich effect - Moving scenery demo

The Pulfrich effect is an optical illusion where objects moving in a single plane also appear to have depth, because the processing of the visual signal in one eye is delayed, e.g. by holding a filter in front of one eye to dim the light reaching that eye but not the other.

To view the animation you'll need to make such a filter. One simple method is to take a cheap pair of sunglasses and pop the lens out of one side.

What also works, but not so well, is to fan out the fingers of one hand in front of one eye and rapidly wave the hand up and down to occlude the image with a "strobe" effect.

What to expect

For this demo the filter should be over the right eye.

Further information

<!DOCTYPE html>
<meta charset="utf-8">
<meta name="author" content="Brandon Seah">
<head></head>
<body>
<div>
<svg class="chart2"></svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// DEMO 2 - Moving scenery
var height=400;
var width=800;
time2 = 0;
var speedParam2 = 2;
var chart2 = d3.select(".chart2")
.attr("height",height)
.attr("width",width)
.append("g");
// Background color light yellow
chart2.append("rect")
.attr("height",height)
.attr("width",width)
.attr("fill","#feffe7");
// Rearmost row of disks
var row0x = [0, 80, 160, 240, 320, 400, 480, 560, 640, 720];
var row0 = chart2.append("g")
.selectAll("circle")
.data(row0x)
.enter().append("circle")
.attr("class","c2row0")
.attr("cx", function(d) { return d; })
.attr("cy",90)
.attr("r",25)
.attr("fill","brown")
.attr("opacity","0.8");
// Second row of disks
var row1x = [0, 100, 200, 300, 400, 500, 600, 700];
var row1 = chart2.append("g")
.selectAll("circle")
.data(row1x)
.enter().append("circle")
.attr("class","c2row1")
.attr("cx", function(d) { return d; })
.attr("cy",140)
.attr("r",35)
.attr("fill","green")
.attr("opacity","0.8");
// Third row of disks
var row2x = [0, 200, 400, 600];
var row2 = chart2.append("g")
.selectAll("circle")
.data(row2x)
.enter().append("circle")
.attr("class","c2row2")
.attr("cx",function(d) {return d;} )
.attr("cy",250)
.attr("r",90)
.attr("fill","blue")
.attr("opacity","0.9");
// Update function for animation
function updateMoving2 () {
// Speed is varied by dividing time param update per step
// Modulo 800 to loop around when reaches end of frame (800 pixel width)
chart2.selectAll(".c2row0")
.attr("cx",function(d) {return Math.round((d + time2/4) % 800); });
chart2.selectAll(".c2row1")
.attr("cx",function(d) {return Math.round((d + time2/2) % 800); });
chart2.selectAll(".c2row2")
.attr("cx",function(d) {return Math.round((d + time2) % 800); });
}
// Update every 10 ms
setInterval(function() {
time2 = time2 + speedParam2 ;
return updateMoving2();
}, 10);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment