Recently Bennett Feely put together a very neat 3D glasses demo using CSS blend modes. Inspired by his work, I decided to create a variant, using a true stereoscopic photograph.
This demo won’t, by itself, allow you to see a 3D image - that happens inside your brain, with the glasses held a lot closer to your face - but it does demonstrate another important aspect of the multiply mode.
Markup & Styles
The SVG glasses are a path and two rectangular “lenses” with curved corners, wrapped together with the anaglyph photograph in a <div>
container:
<div id="dino">
<img src="saguaro-national-park.jpg" alt>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 817 296" id="glasses">
<path fill="#E5F2E7" d="M795.4,7H18.6C12.2,7,7,12.2,7 …" />
<rect x="57.5" y="48.1" fill="#f00" width="254.5" height="186.9" rx="26" ry="26" />
<rect x="493" y="48.1" fill="#0ff" width="254.5" height="186.9" rx="26" ry="26" />
</svg>
</div>
The elements are styled with CSS:
#saguaro {
position: relative;
overflow: hidden;
}
#saguaro img {
width: 100%;
}
#glasses {
width: 60%;
position: absolute;
pointer-events: none;
-ms-touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
#glasses rect {
mix-blend-mode: multiply;
}
Note the use of pointer-events: none
on the #glasses
element: while it’s not foolproof, this addition often works to reduce or eliminate “jank” (visible pauses in the browser window between repaints). Without having to track interaction on the element, repositioning it tends to be a lot smoother. The remaining properties on the element turn off mobile devices tendency to prompt a “copy” request if an element is touched for more than a second or two.
There’s also a bit of JavaScript to track the movement of the glasses with mouse or touch movement:
var saguaro = document.getElementById("saguaro"),
glasses = document.getElementById("glasses"),
boundingRect = saguaro.getBoundingClientRect();
saguaro.addEventListener( "mousemove", moveGlasses, false);
saguaro.addEventListener( "touchstart", moveGlasses, false);
saguaro.addEventListener( "touchmove", moveGlasses, false);
function moveGlasses(e) {
glasses.style.left = (e.pageX - boundingRect.left)+"px";
glasses.style.top = (e.pageY - boundingRect.top)+"px";
}
The Multiply Effect
Note that the multiply
mode on the rectangular lenses effectively filters out the natural color of each lens: the multiply
filter on the left lens admits only the non-red parts of the photograph, while the multiply
on the right lens shows the non-cyan portions. You can see this for yourself by moving the 3D glasses quickly back and forth over the same spot on the photograph in the demo.
Because each of these colors is displaced in the image, the visual combination joins to create the impression of 3D space and depth, at least when you’re wearing glasses with the appropriate lenses.
Importantly, red and cyan are complementary colors: they are opposite to each other on the HSL color wheel. Either held over white will produce black, as will overlaying them over each other.
Images by Koala MeatPie and U.S. Department of the Interior, licensed under Creative Commons and public domain.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/KwjrbG