How to make a 3D gallery using javascript

Tutorials

Today we continue JavaScript lessons, and our article will about creating modern 3d photo gallery using pure javascript. We will simulate 3D effect using z-indexes. Via mouse clicking we will moving from one photo to another. And I sure that better to see demo now.

Here are sample and downloadable package:

Live Demo

[sociallocker]

download in package

[/sociallocker]


Ok, download the example files and lets start coding !


Step 1. HTML

As usual, we start with the HTML.

This is our main page code of 3d gallery.

index.html

01 <link rel="stylesheet" href="css/main.css" type="text/css" media="all" />
02 <script src="js/main.js" type="text/javascript"></script>
03 <div class="example" id="gall">
04     <img src="images/pic1.jpg"><span>Picture 1 title<br>and description.</span>
05     <img src="images/pic2.jpg"><span>Picture 2 description.</span>
06     <img src="images/pic3.jpg"><span>Picture 3 description.</span>
07     <img src="images/pic4.jpg"><span>Picture 4 description.</span>
08     <img src="images/pic5.jpg"><span>Picture 5 description.</span>
09     <img src="images/pic6.jpg"><span>Picture 6 description.</span>
10     <img src="images/pic7.jpg"><span>Picture 7 description.</span>
11     <img src="images/pic8.jpg"><span>Picture 8 description.</span>
12     <img src="images/pic9.jpg"><span>Picture 9 description.</span>
13     <img src="images/pic10.jpg"><span>Picture 10 description.</span>
14     <img src="images/pic11.jpg"><span>Picture 11 description.</span>
15     <img src="images/pic12.jpg"><span>Picture 12 description.</span>
16     <img src="images/pic13.jpg"><span>Picture 13 description.</span>
17     <img src="images/pic14.jpg"><span>Picture 14 description.</span>
18     <img src="images/pic15.jpg"><span>Picture 15 description.</span>
19 </div>

As we can see – I put all used images for gallery in ‘images’ folder. All pretty easy here.

Step 2. CSS

Here are used CSS styles:

css/main.css

01 body{background:#333;margin:0;padding:0}
02 .example {
03     position:absolute;
04     left0%;
05     top0%;
06     width100%;
07     height95%;
08     background#333;
09     overflowhidden;
10 }
11 .example img {
12     positionabsolute;
13     background#666;
14     overflowhidden;
15     cursorpointer;
16     left100%;
17     border-color#333;
18     border-stylesolid;
19     border-width1px;
20 }
21 .example span {
22     positionabsolute;
23     color#efe;
24     font-familyverdana;
25     font-size0px;
26     white-spacenowrap;
27     left-999px;
28     background#333;
29     /*filter: alpha(opacity=70);
30     opacity: 0.7;*/
31     background: rgba(0000.7);
32 }

Step 3. JS

Here are our main control JS file.

js/main.js

001 to_px = function (x) { return ''.concat(Math.round(x), 'px'); }
002 g_resize = function() { pgal.resize(); }
003 var pgal = {
004     O : [], N : 0, S : 0, img : 0, span : 0, xm : 0, ym : 0, nx : 0, ny : 0, nw : 0, nh : 0,
005     cx : 0, cy : 0, zoom : 1, x : 0, y : 0, z : -30000, xt : 0, yt : 0, zt : 0,
006     init : function () {
007         this.cx   = this.nw / 2;
008         this.cy   = this.nh / 2;
009         this.img  = document.getElementById('gall').getElementsByTagName('img');
010         this.span  = document.getElementById('gall').getElementsByTagName('span');
011         this.N    = this.img.length;
012         for (var i = 0; i < this.N; i++) this.O[i] = new this.PGObj(i);
013         this.run();
014         this.O[0].click();
015     },
016     resize : function () {
017         var o   = document.getElementById('gall');
018         this.nx   = o.offsetLeft;
019         this.ny   = o.offsetTop;
020         this.nw   = o.offsetWidth;
021         this.nh   = o.offsetHeight;
022         this.zoom = this.nh / 900;
023     },
024     run : function () {
025         pgal.cx += (pgal.xm - pgal.cx) * .1;
026         pgal.cy += (pgal.ym - pgal.cy) * .1;
027         pgal.x  += (pgal.xt - pgal.x)  * .05;
028         pgal.y  += (pgal.yt - pgal.y)  * .05;
029         pgal.z  += (pgal.zt - pgal.z)  * .1;
030         var i = pgal.N;
031         while (i--) pgal.O[i].anim();
032         setTimeout(pgal.run, 16);
033     },
034     PGObj : function (n) {
035         this.n                = n;
036         this.x                = pgal.zoom * Math.random() * pgal.nw * 3 - pgal.nw;
037         this.y                = pgal.zoom * Math.random() * pgal.nh * 3 - pgal.nh;
038         this.z                = Math.round(n * (10000 / pgal.N));
039         this.w                = pgal.img[n].width;
040         this.h                = pgal.img[n].height;
041         this.oxt              = pgal.span[n];
042         this.oxs              = this.oxt.style;
043         this.txt              = pgal.span[n].innerHTML;
044         this.oxt.innerHTML    = "";
045         this.obj              = pgal.img[n];
046         this.obs              = this.obj.style;
047         this.obj.parent       = this;
048         this.obj.onclick      = function() { this.parent.click(); }
049         this.obj.ondrag       = function() { return false; }
050         this.oxt.style.zIndex = this.obj.style.zIndex = Math.round(1000000 - this.z);
051         this.F                = false;
052         this.CF               = 100;
053         this.sto              = [];
054         this.anim = function() {
055             var f = 700 + this.z - pgal.z;
056             if (f > 0) {
057                 var d               = 1000 / f;
058                 var X               = pgal.nw * .5 + ((this.x - pgal.x - pgal.cx) * d);
059                 var Y               = pgal.nh * .5 + ((this.y - pgal.y - pgal.cy) * d);
060                 var W               = d * this.w * pgal.zoom;
061                 var H               = d * this.h * pgal.zoom;
062                 this.obs.left       = to_px(X - W * .5);
063                 this.obs.top        = to_px(Y - H * .5);
064                 this.obs.width      = to_px(W);
065                 this.obs.height     = to_px(H);
066                 this.oxs.visibility = (this.CF-- > 0 && Math.random() > .9) ? "hidden" "visible";
067                 this.oxs.left       = to_px(X - W * .5);
068                 this.oxs.top        = to_px(Y + H * .5);
069                 if ((pgal.zt - pgal.z) < 20) {
070                     if (! this.F) {
071                         this.F            = true;
072                         this.CF           = Math.random() * 200;
073                         this.oxs.fontSize = to_px(1 + d * 20 * pgal.zoom);
074                         var T             = "";
075                         var tn            = this.txt.length;
076                         for(var i = 0; i < tn; i++) {
077                             T = T.concat(this.txt.charAt(i));
078                             this.sto[i] = setTimeout('pgal.O['.concat(n, '].oxt.innerHTML = "', T, '";'), Math.round(f / 4) + 10 * i);
079                         }
080                     }
081                 else {
082                     this.F = false;
083                     this.oxt.innerHTML = "";
084                 }
085             else {
086                 this.x  = pgal.zoom * Math.random() * pgal.nw * 3 - pgal.nw;
087                 this.y  = pgal.zoom * Math.random() * pgal.nh * 3 - pgal.nh;
088                 this.z += 10000;
089                 this.oxs.zIndex = this.obs.zIndex = Math.round(1000000 - this.z);
090             }
091         }
092         this.cto = function() {
093             var i = this.txt.length;
094             while (i--) clearTimeout(this.sto[i]);
095         }
096         this.click = function() {
097             var i = pgal.N;
098             while (i--) pgal.O[i].cto();
099             if (pgal.S != this) {
100                 pgal.xt = this.x;
101                 pgal.yt = this.y;
102                 pgal.zt = this.z;
103                 pgal.S  = this;
104             else {
105                 pgal.S   = 0;
106                 pgal.zt += 1600;
107             }
108         }
109     }
110 }
111 // event handlers
112 window.onresize = g_resize;
113 document.onmousemove = function(e) {
114     if (window.event) e=window.event;
115     pgal.xm = (e.x || e.clientX) - pgal.nx - pgal.nw * .5;
116     pgal.ym = (e.y || e.clientY) - pgal.ny - pgal.nh * .5;
117 }
118 window.onload = function() {
119     g_resize();
120     pgal.init();
121 }

This is most interesting and important part of our gallery. Our photo gallery object (pgal) contain next functions: init, resize and run. During resize we re-saving all current positions of gallery object. In initialization we perform initialization of all main params and objects (images and span text objects). Each photo object (PGObj) have own set of variables, and few main functions – for animation and onclick handling.


Live Demo

Conclusion

Today we prepared interesting 3d gallery, sure that was interesting to you. If is you were wondering – do not forget to thank us. I would be grateful for your interesting comments. Good luck!

Rate article