特炫照片墙
多日未更新博客,近日研究了一个3D效果的js照片墙效果
修改了源码中关于无限setTimeout的问题
html页面
1 <!DOCTYPE html> 2 <html lang="zh-CH"> 3 4 <head> 5 <meta charset="utf-8"> 6 <title>漂亮的3D相片展示效果 </title> 7 <meta http-equiv="imagetoolbar" content="false"> 8 <link rel="stylesheet" type="text/css" href="plugin/photowall/wall.css"> 9 </head> 10 11 <body> 12 <div id="screen"> 13 <div id="command"> 14 <h1>bar</h1> 15 点击放大 16 <div id="bar"></div> 17 </div> 18 </div> 19 <script src="plugin/photowall/m3D.js"></script> 20 <script type="text/javascript"> 21 /* ==== start script ==== */ 22 window.onload = function() { 23 // src 是图片位置,可以是相对于路径也可以是绝对路径,甚至是网络图片 24 m3D.init( 25 [ 26 { src: './img/lunbo1.jpg' }, 27 { src: './img/lunbo2.jpg' }, 28 { src: './img/lunbo3.jpg' }, 29 { src: './img/lunbo4.jpg' }, 30 { src: './img/lunbo5.jpg' }, 31 { src: './img/lunbo6.jpg' }, 32 { src: './img/lunbo7.jpg' }, 33 { src: './img/lunbo8.jpg' }, 34 { src: './img/lunbo9.jpg' }, 35 { src: './img/lunbo10.jpg' }, 36 { src: './img/lunbo11.jpg' }, 37 ] 38 ); 39 } 40 </script> 41 </body> 42 43 </html>
css页面
#screen { position: absolute; top: 300px; width: 100%; height: 400px; background: #f2ebe2; overflow: hidden; color: white; } #screen img{ position: absolute; left: -9999px; cursor: pointer; image-rendering: optimizeSpeed; } #command { position: absolute; left: 1em; top: 6em; width: 130px; z-index: 30000; background: #93989c; padding: 1em; } #bar { position: relative; top: 1em; height: 100px; } #bar .button { position: absolute; background: #222; width: 20px; height: 20px; cursor: pointer; } #bar .loaded { background: #666; } #bar .viewed { background: #fff; } #bar .selected { background: #f00; }
js页面
1 // ============================================================= 2 // ===== 3D gallery experiment ===== 3 // script written by Gerard Ferrandez - April 5, 2010 4 // use under a CC-BY-NC license 5 // ------------------------------------------------------------- 6 // update: April 17 : added hyperlinks, tweaked z-index 7 // update: 1/28,2019 : change dom , init , create img by lmaster 8 // ============================================================= 9 var m3D = function() { 10 /* ---- private vars ---- */ 11 var diapo = [], 12 scr, 13 bar, 14 selected, 15 nw = 0, 16 nh = 0, 17 engine, 18 loaded = false; 19 /* ---- camera ---- */ 20 var camera = { 21 x: 0, 22 y: 0, 23 z: -650, 24 s: 0, 25 fov: 500, 26 setTarget: function(c0, t1, p) { 27 if (Math.abs(t1 - c0) > .1) { 28 camera.s = 1; 29 camera.p = 0; 30 camera.d = t1 - c0; 31 if (p) { 32 camera.d *= 2; 33 camera.p = 9; 34 } 35 } 36 }, 37 tween: function(v) { 38 if (camera.s != 0) { 39 camera.p += camera.s; 40 camera[v] += camera.d * camera.p * .01; 41 if (camera.p == 10) camera.s = -1; 42 else if (camera.p == 0) camera.s = 0; 43 } 44 return camera.s; 45 } 46 47 }; 48 49 50 /* ==== diapo constructor ==== */ 51 var Diapo = function(init, img) { 52 /* ---- image ---- */ 53 this.img = img; 54 this.img.diapo = this; 55 /* ---- bar buttons ---- */ 56 this.but = document.createElement('div'); 57 this.but.className = "button loaded"; 58 bar.appendChild(this.but); 59 this.but.diapo = this; 60 var i = init.i - 1; 61 this.but.style.left = Math.round((this.but.offsetWidth * 1.2) * (i % 4)) + 'px'; 62 this.but.style.top = Math.round((this.but.offsetHeight * 1.2) * Math.floor(i / 4)) + 'px'; 63 this.but.onclick = this.img.onclick; 64 /* ---- object variables ---- */ 65 this.w = init.width; 66 this.h = init.height; 67 this.zi = 25000; 68 this.x = init.x; 69 this.y = init.y; 70 this.z = init.z; 71 this.css = this.img.style; 72 } 73 74 /* ==== main 3D animation ==== */ 75 Diapo.prototype.anim = function() { 76 /* ---- 3D to 2D projection ---- */ 77 var x = this.x - camera.x; 78 var y = this.y - camera.y; 79 var z = this.z - camera.z; 80 if (z < 20) z += 5000; 81 var p = camera.fov / z; 82 var w = this.w * p; 83 var h = this.h * p; 84 /* ---- HTML rendering ---- */ 85 this.css.left = Math.round(nw + x * p - w * .5) + 'px'; 86 this.css.top = Math.round(nh + y * p - h * .5) + 'px'; 87 this.css.width = Math.round(w) + 'px'; 88 this.css.height = Math.round(h) + 'px'; 89 this.css.zIndex = this.zi - Math.round(z); 90 } 91 92 93 /* ==== screen dimensions ==== */ 94 var resize = function() { 95 nw = scr.offsetWidth * .5; 96 nh = scr.offsetHeight * .5; 97 } 98 99 /* ==== disable interpolation during animation ==== */ 100 /* ==== Low version browser : IE8 ==== */ 101 var interpolation = function(bicubic) { 102 var i = 0, 103 o; 104 while (o = diapo[i++]) { 105 if (o.but) { 106 o.css.msInterpolationMode = bicubic ? 'bicubic' : 'nearest-neighbor'; // makes IE8 happy 107 o.css.imageRendering = bicubic ? 'optimizeQuality' : 'optimizeSpeed'; // does not really work... 108 } 109 } 110 } 111 112 /* ==== init script ==== */ 113 var init = function(data) { 114 /* ---- containers ---- */ 115 scr = document.getElementById("screen"); 116 bar = document.getElementById("bar"); 117 resize(); 118 119 /* ---- loading images ---- */ 120 var i = 0, 121 o, 122 n = data.length; 123 while (o = data[i++]) { 124 img(o, i, n); 125 } 126 } 127 128 /* ---- init image : i x y z width height ---- */ 129 var initImg = function(i, n, width, height) { 130 var x = 1000 * ((i % 4) - 1.5), 131 y = Math.round(Math.random() * 4000) - 2000, 132 z = i * (5000 / n), 133 _width = width / 2, 134 _height = height / 2; 135 return { i: i, x: x, y: y, z: z, width: _width, height: _height }; 136 } 137 138 /* ==== main loop ==== */ 139 var run = function() { 140 /* ---- x axis move ---- */ 141 if (camera.tx) { 142 if (!camera.s) camera.setTarget(camera.x, camera.tx); 143 var m = camera.tween('x'); 144 if (!m) camera.tx = 0; 145 /* ---- y axis move ---- */ 146 } else if (camera.ty) { 147 if (!camera.s) camera.setTarget(camera.y, camera.ty); 148 var m = camera.tween('y'); 149 if (!m) camera.ty = 0; 150 /* ---- z axis move ---- */ 151 } else if (camera.tz) { 152 if (!camera.s) camera.setTarget(camera.z, camera.tz); 153 var m = camera.tween('z'); 154 if (!m) { 155 /* ---- animation end ---- */ 156 camera.tz = 0; 157 // interpolation(true); 158 clearTimeout(engine); 159 return; 160 } 161 } 162 /* ---- anim images ---- */ 163 var i = 0, 164 o; 165 while (o = diapo[i++]) o.anim(); 166 /* ---- loop ---- */ 167 engine = setTimeout(run, 32); 168 } 169 170 /* ==== create image ==== */ 171 var img = function(data, i, n) { 172 var img = document.createElement('img'); 173 img.src = data.src; 174 scr.appendChild(img); 175 /* ---- on onload event ---- */ 176 img.onload = function() { 177 var _diapo = new Diapo(initImg(i, n, this.width, this.height), this); 178 diapo.push(_diapo); 179 _diapo.anim(); 180 } 181 /* ---- on click event ---- */ 182 img.onclick = function() { 183 if (camera.s) return; 184 /* ---- target positions ---- */ 185 camera.tz = this.diapo.z - camera.fov; 186 camera.tx = this.diapo.x; 187 camera.ty = this.diapo.y; 188 /* ---- disable previously selected img ---- */ 189 if (selected) { 190 selected.but.className = "button viewed"; 191 } 192 /* ---- select current img ---- */ 193 this.diapo.but.className = "button selected"; 194 // interpolation(false); 195 selected = this.diapo; 196 run(); 197 } 198 } 199 200 return { 201 /* ==== initialize script ==== */ 202 init: init 203 } 204 }();
原来效果地址: http://www.jq22.com/yanshi1486