Direct Link
Source code
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
| <html> |
| <head> |
| <title>3D rotations engine - interactive DHTML</title> |
| <meta name="Author" content="Gerard Ferrandez at http://www.dhteumeuleu.com"> |
| <meta http-equiv="imagetoolbar" content="no"> |
| <style type="text/css"> |
| html { |
| overflow: hidden; |
| } |
| body { |
| position: absolute; |
| margin: 0px; |
| padding: 0px; |
| background: #222; |
| width: 100%; |
| height: 100%; |
| } |
| #screen { |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| background: #000; |
| overflow: hidden; |
| } |
| #screen img { |
| position: absolute; |
| left: -9999px; |
| -ms-interpolation-mode:nearest-neighbor; |
| image-rendering: optimizeSpeed; |
| } |
| #bankImages { |
| visibility: hidden; |
| } |
| </style> |
| <script type="text/javascript"> |
| // ============================================================= |
| // ===== 3D experiment - rotations ===== |
| // script written by Gerard Ferrandez - June 13, 2009 |
| // http://www.dhteumeuleu.com |
| // ============================================================= |
| var m3D = function () { |
| /* ---- private vars ---- */ |
| var compos = [], |
| scr, |
| xm = 0, |
| ym = 0, |
| nw = 0, |
| nh = 0, |
| nx = 0, |
| ny = 0; |
| /* ==== Easing function ==== */ |
| var Ease = function () { |
| this.target = 0; |
| this.position = 0; |
| } |
| Ease.prototype.move = function (target, speed) { |
| this.position += (target - this.position) * speed; |
| } |
| var angle = { |
| x : new Ease(), |
| y : new Ease() |
| } |
| var camera = { |
| x : 0, |
| y : 0, |
| focalLength : 250, |
| zoom : 1, |
| izoom : .5 |
| } |
| var Compo3D = function (img, x, y, z) { |
| this.img = document.createElement('img'); |
| this.img.src = "../images/" + img; |
| scr.appendChild(this.img); |
| /* ==== 3D coordinates ==== */ |
| this.point3D = { |
| x : x, |
| y : y, |
| z : z |
| } |
| this.loaded = false; |
| this.css = this.img.style; |
| } |
| Compo3D.prototype.animate = function () { |
| if (this.loaded) { |
| /* ==== 3D coordinates ==== */ |
| var x = this.point3D.x * camera.zoom; |
| var y = this.point3D.y * camera.zoom; |
| var z = this.point3D.z * camera.zoom; |
| /* ==== rotations ==== */ |
| var xy = angle.cx * y - angle.sx * z; |
| var xz = angle.sx * y + angle.cx * z; |
| var yz = angle.cy * xz - angle.sy * x; |
| var yx = angle.sy * xz + angle.cy * x; |
| /* ==== 2D transform ==== */ |
| var scale = camera.focalLength / (camera.focalLength + yz); |
| x = yx * scale; |
| y = xy * scale; |
| var w = Math.round(Math.max(0, this.point3D.w * scale)); |
| var h = Math.round(Math.max(0, this.point3D.h * scale)); |
| /* ==== HTML rendering ==== */ |
| this.css.left = Math.round(x + nw - w * .5) + 'px'; |
| this.css.top = Math.round(y + nh - h * .5) + 'px'; |
| this.css.width = w + 'px'; |
| this.css.height = h + 'px'; |
| this.css.zIndex = Math.round(10000 - yz * 10); |
| } else { |
| if (this.img.complete) { |
| if (this.img.width) { |
| this.loaded = true; |
| this.point3D.w = this.img.width * camera.izoom; |
| this.point3D.h = this.img.height * camera.izoom; |
| } |
| } |
| } |
| } |
| //////////////////////////////////////////////////////////////////////////// |
| /* ==== DOM events ==== */ |
| function addEvent (o, e, f) { |
| if (window.addEventListener) o.addEventListener(e, f, false); |
| else if (window.attachEvent) r = o.attachEvent('on' + e, f); |
| } |
| /* ==== screen dimensions ==== */ |
| function resize() { |
| nw = scr.offsetWidth * .5; |
| nh = scr.offsetHeight * .5; |
| var o = scr; |
| for (nx = 0, ny = 0; o != null; o = o.offsetParent) { |
| nx += o.offsetLeft; |
| ny += o.offsetTop; |
| } |
| } |
| var init = function () { |
| /* ---- init script ---- */ |
| scr = document.getElementById("screen"); |
| /* ---- mouse move event ---- */ |
| addEvent(document, 'mousemove', function (e) { |
| if (window.event) e = window.event; |
| xm = e.clientX; |
| ym = e.clientY; |
| }); |
| /* ---- screen resize event ---- */ |
| resize(); |
| addEvent(window, 'resize', resize); |
| for (var i = 0; i < 100; i++) |
| compos.push(new Compo3D("KIT78_sphere_details.gif", 300 * Math.random() - 150, 300 * Math.random() - 150, 300 * Math.random() - 150)); |
| run(); |
| } |
| //////////////////////////////////////////////////////////////////////////// |
| /* ==== main loop ==== */ |
| var run = function () { |
| angle.x.move(-(ym - nh - ny) * .01, .1); |
| angle.y.move( (xm - nw - nx) * .01, .1); |
| /* ==== angles sin and cos ==== */ |
| angle.cx = Math.cos(angle.x.position); |
| angle.sx = Math.sin(angle.x.position); |
| angle.cy = Math.cos(angle.y.position); |
| angle.sy = Math.sin(angle.y.position); |
| /* ==== loop through images ==== */ |
| var i = 0, o; |
| while( o = compos[i++] ) o.animate(); |
| setTimeout(run, 16); |
| } |
| return { |
| //////////////////////////////////////////////////////////////////////////// |
| /* ==== initialize script ==== */ |
| init : function () { |
| addEvent(window, 'load', function () { init(); }); |
| } |
| } |
| }(); |
| /* ==== start script ==== */ |
| m3D.init(); |
| </script> |
| </head> |
| <body> |
| <div id="screen"></div> |
| </body> |
| </html> |


Recent Comments
November 20, 2011 (3:39)