In the following post, I use a two-and-a-half-dimensional (2.5) technique to fake a three-dimensional (3D) visualization of Joseph Wright of Derby's painting The Alchemist in Search of the Philosopher's Stone This post was mostly inspired by Román Cortès' 3D Menimas and a post on Experiment Garden.
The Alchemist in Search of the Philosopher's Stone
The following image/script was successfully tested under Firefox 3.6. Move your mouse over the image
How it works
Each component of the collage is part of a larger transparent picture:
An array defines each sprite. One sprite is defined by its rectangular clip (x,y,width,height) in the original image, its position (x,y) in the collage and a value (ratio) reflecting the amount of pixels it should scroll
var picts=[
{
/* background */
img:null,
clip:[0,0,image_width,image_height],
ratio:0.0,
x:0,y:0
},
{
/* people */
img:null,
clip:[227,1,111,147],
ratio:0.1,
x:5,y:154
},
(...)
];
The HTML is defined as follow:
<div id='id9879709_main' style='overflow:hidden;position:relative;background-color:red;width:226px;height:320px;border:1px solid black;'>
<span style="position:relative;padding:3px;background-color:white;top:15px;left:15px;border:2px solid black;z-index:100; font-weight: bold;"><a target="_wp" href="http://commons.wikimedia.org/wiki/File:JosephWright-Alchemist.jpg">The Alchemist</a></span>
</div>
.When this html document is loaded, a <div> clipping each sprite is created an inserted into the document:
var main=document.getElementById('main');
main.onmousemove = callback;
for(var i in picts)
{
var pict=picts[i];
pict.img=document.createElement("div"); pict.img.setAttribute("style","position:absolute;top:"+pict.y+"px;left:"+pict.x+"px;width:"+pict.clip[2]+"px;height:"+pict.clip[3]+"px;z-index:"+i+";background:url(alchemy02.png) no-repeat scroll -"+pict.clip[0]+"px -"+pict.clip[1]+"px;");
main.appendChild(pict.img);
}
Lastly a javascript callback is called each time the mouse moves over the image. This method shifts each sprites according to the value of its 'ratio':
var v=document.getElementById('id9879709_main');
var left=v.offsetLeft;
var width=226.0;
var midX= left+width/2.0;
var maxshift=30;
var mouseX=e.clientX;
if(mouseX > left+width) mouseX=left+width;
if(mouseX < left) mouseX=left;
var shift= ((e.clientX-midX)/(width/2.0))*maxshift;
for(var i in picts)
{
var pict=picts[i];
pict.img.style.left=(pict.x+shift*pict.ratio)+"px";
}
That's it
Pierre