以下是 JS响应式3D照片墙展示特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS响应式3D照片墙展示特效</title>
<style type="text/css">
html {
overflow: hidden;
}
body {
position: absolute;
margin: 0px;
padding: 0px;
background: #4f5a70;
width: 100%;
height: 100%;
}
a{ color: rgba(255, 255, 255, 0.6);outline: none;text-decoration: none;-webkit-transition: 0.2s;transition: 0.2s;}
a:hover,a:focus{color:#74777b;text-decoration: none;}
#screen {
position: absolute;
left: 10%;
top: 10%;
width: 80%;
height: 80%;
background: #3e495d;
}
#screen img {
position: absolute;
cursor: pointer;
visibility: hidden;
width: 0px;
height: 0px;
}
#screen .tvover {
border: solid #876;
opacity: 1;
filter: alpha(opacity=100);
}
#screen .tvout {
border: solid #fff;
opacity: 0.7;
}
#bankImages {
display: none;
}
</style>
</head>
<body>
<div id="screen">
</div>
<div id="bankImages">
<img alt="" src="images/1.jpg">
<img alt="" src="images/2.jpg">
<img alt="" src="images/3.jpg">
<img alt="" src="images/4.jpg">
<img alt="" src="images/5.jpg">
<img alt="" src="images/6.jpg">
<img alt="" src="images/7.jpg">
<img alt="" src="images/8.jpg">
<img alt="" src="images/1.jpg">
<img alt="" src="images/2.jpg">
<img alt="" src="images/3.jpg">
<img alt="" src="images/4.jpg">
<img alt="" src="images/5.jpg">
<img alt="" src="images/6.jpg">
<img alt="" src="images/7.jpg">
<img alt="" src="images/8.jpg">
</div>
<script src="js/3d-tv.js" type="text/javascript"></script>
<script type="text/javascript">
/* ==== start script ==== */
onresize = tv.resize;
tv.init();
</script>
</body>
</html>
JS代码(3d-tv.js):
var Library ={
}
;
Library.ease = function (){
this.target = 0;
this.position = 0;
this.move = function (target,speed){
this.position += (target - this.position) * speed;
}
}
var tv ={
/* ==== variables ==== */
O:[],screen:{
}
,grid:{
size:4,// 4x4 gridborderSize:6,// borders sizezoomed:false}
,angle:{
x:new Library.ease(),y:new Library.ease()}
,camera:{
x:new Library.ease(),y:new Library.ease(),zoom:new Library.ease(),focalLength:750 // camera Focal Length}
,/* ==== init script ==== */
init:function (){
this.screen.obj = document.getElementById('screen');
var img = document.getElementById('bankImages').getElementsByTagName('img');
this.screen.obj.onselectstart = function (){
return false;
}
this.screen.obj.ondrag = function (){
return false;
}
/* ==== create images grid ==== */
var ni = 0;
var n = (tv.grid.size / 2) - .5;
for (var y = -n;
y <= n;
y++){
for (var x = -n;
x <= n;
x++){
/* ==== create HTML image element ==== */
var o = document.createElement('img');
var i = img[(ni++) % img.length];
o.className = 'tvout';
o.src = i.src;
tv.screen.obj.appendChild(o);
/* ==== 3D coordinates ==== */
o.point3D ={
x:x,y:y,z:new Library.ease()}
;
/* ==== push object ==== */
o.point2D ={
}
;
o.ratioImage = 1;
tv.O.push(o);
/* ==== on mouse over event ==== */
o.onmouseover = function (){
if (!tv.grid.zoomed){
if (tv.o){
/* ==== mouse out ==== */
tv.o.point3D.z.target = 0;
tv.o.className = 'tvout';
}
/* ==== mouse over ==== */
this.className = 'tvover';
this.point3D.z.target = -.5;
tv.o = this;
}
}
/* ==== on click event ==== */
o.onclick = function (){
if (!tv.grid.zoomed){
/* ==== zoom in ==== */
tv.camera.x.target = this.point3D.x;
tv.camera.y.target = this.point3D.y;
tv.camera.zoom.target = tv.screen.w * 1.25;
tv.grid.zoomed = this;
}
else{
if (this == tv.grid.zoomed){
/* ==== zoom out ==== */
tv.camera.x.target = 0;
tv.camera.y.target = 0;
tv.camera.zoom.target = tv.screen.w / (tv.grid.size + .1);
tv.grid.zoomed = false;
}
}
}
/* ==== 3D transform function ==== */
o.calc = function (){
/* ==== ease mouseover ==== */
this.point3D.z.move(this.point3D.z.target,.5);
/* ==== assign 3D coords ==== */
var x = (this.point3D.x - tv.camera.x.position) * tv.camera.zoom.position;
var y = (this.point3D.y - tv.camera.y.position) * tv.camera.zoom.position;
var z = this.point3D.z.position * tv.camera.zoom.position;
/* ==== perform rotations ==== */
var xy = tv.angle.cx * y - tv.angle.sx * z;
var xz = tv.angle.sx * y + tv.angle.cx * z;
var yz = tv.angle.cy * xz - tv.angle.sy * x;
var yx = tv.angle.sy * xz + tv.angle.cy * x;
/* ==== 2D transformation ==== */
this.point2D.scale = tv.camera.focalLength / (tv.camera.focalLength + yz);
this.point2D.x = yx * this.point2D.scale;
this.point2D.y = xy * this.point2D.scale;
this.point2D.w = Math.round( Math.max( 0,this.point2D.scale * tv.camera.zoom.position * .8 ) );
/* ==== image size ratio ==== */
if (this.ratioImage > 1)this.point2D.h = Math.round(this.point2D.w / this.ratioImage);
else{
this.point2D.h = this.point2D.w;
this.point2D.w = Math.round(this.point2D.h * this.ratioImage);
}
}
/* ==== rendering ==== */
o.draw = function (){
if (this.complete){
/* ==== paranoid image load ==== */
if (!this.loaded){
if (!this.img){
/* ==== create internal image ==== */
this.img = new Image();
this.img.src = this.src;
}
if (this.img.complete){
/* ==== get width / height ratio ==== */
this.style.visibility = 'visible';
this.ratioImage = this.img.width / this.img.height;
this.loaded = true;
this.img = false;
}
}
/* ==== HTML rendering ==== */
this.style.left = Math.round( this.point2D.x * this.point2D.scale + tv.screen.w - this.point2D.w * .5 ) + 'px';
this.style.top = Math.round( this.point2D.y * this.point2D.scale + tv.screen.h - this.point2D.h * .5 ) + 'px';
this.style.width = this.point2D.w + 'px';
this.style.height = this.point2D.h + 'px';
this.style.borderWidth = Math.round( Math.max( this.point2D.w,this.point2D.h ) * tv.grid.borderSize * .01 ) + 'px';
this.style.zIndex = Math.floor(this.point2D.scale * 100);
}
}
}
}
/* ==== start script ==== */
tv.resize();
mouse.y = tv.screen.y + tv.screen.h;
mouse.x = tv.screen.x + tv.screen.w;
tv.run();
}
,/* ==== resize window ==== */
resize:function (){
var o = tv.screen.obj;
tv.screen.w = o.offsetWidth / 2;
tv.screen.h = o.offsetHeight / 2;
tv.camera.zoom.target = tv.screen.w / (tv.grid.size + .1);
for (tv.screen.x = 0,tv.screen.y = 0;
o != null;
o = o.offsetParent){
tv.screen.x += o.offsetLeft;
tv.screen.y += o.offsetTop;
}
}
,/* ==== main loop ==== */
run:function (){
/* ==== motion ease ==== */
tv.angle.x.move(-(mouse.y - tv.screen.h - tv.screen.y) * .0025,.1);
tv.angle.y.move( (mouse.x - tv.screen.w - tv.screen.x) * .0025,.1);
tv.camera.x.move(tv.camera.x.target,tv.grid.zoomed ? .25:.025);
tv.camera.y.move(tv.camera.y.target,tv.grid.zoomed ? .25:.025);
tv.camera.zoom.move(tv.camera.zoom.target,.05);
/* ==== angles sin and cos ==== */
tv.angle.cx = Math.cos(tv.angle.x.position);
tv.angle.sx = Math.sin(tv.angle.x.position);
tv.angle.cy = Math.cos(tv.angle.y.position);
tv.angle.sy = Math.sin(tv.angle.y.position);
/* ==== loop through all images ==== */
for (var i = 0,o;
o = tv.O[i];
i++){
o.calc();
o.draw();
}
/* ==== loop ==== */
setTimeout(tv.run,32);
}
}
/* ==== global mouse position ==== */
var mouse ={
x:0,y:0}
document.onmousemove = function(e){
if (window.event) e = window.event;
mouse.x = e.clientX;
mouse.y = e.clientY;
return false;
}
CSS代码(htmleaf-demo.css):
@font-face{font-family:'icomoon';src:url('../fonts/icomoon.eot?rretjt');src:url('../fonts/icomoon.eot?#iefixrretjt') format('embedded-opentype'),url('../fonts/icomoon.woff?rretjt') format('woff'),url('../fonts/icomoon.ttf?rretjt') format('truetype'),url('../fonts/icomoon.svg?rretjt#icomoon') format('svg');font-weight:normal;font-style:normal;}
[class^="icon-"],[class*=" icon-"]{font-family:'icomoon';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;/* Better Font Rendering =========== */
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}
body,html{font-size:100%;padding:0;margin:0;}
/* Reset */
*,*:after,*:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
/* Clearfix hack by Nicolas Gallagher:http://nicolasgallagher.com/micro-clearfix-hack/ */
.clearfix:before,.clearfix:after{content:" ";display:table;}
.clearfix:after{clear:both;}
body{background:#494A5F;color:#D5D6E2;font-weight:500;font-size:1.05em;font-family:"Microsoft YaHei","Segoe UI","Lucida Grande",Helvetica,Arial,sans-serif;}
a{color:rgba(255,255,255,0.6);outline:none;text-decoration:none;-webkit-transition:0.2s;transition:0.2s;}
a:hover,a:focus{color:#74777b;text-decoration:none;}
.htmleaf-container{margin:0 auto;}
.bgcolor-1{background:#f0efee;}
.bgcolor-2{background:#f9f9f9;}
.bgcolor-3{background:#e8e8e8;}
/*light grey*/
.bgcolor-4{background:#2f3238;color:#fff;}
/*Dark grey*/
.bgcolor-5{background:#df6659;color:#521e18;}
/*pink1*/
.bgcolor-6{background:#2fa8ec;}
/*sky blue*/
.bgcolor-7{background:#d0d6d6;}
/*White tea*/
.bgcolor-8{background:#3d4444;color:#fff;}
/*Dark grey2*/
.bgcolor-9{background:#ef3f52;color:#fff;}
/*pink2*/
.bgcolor-10{background:#64448f;color:#fff;}
/*Violet*/
.bgcolor-11{background:#3755ad;color:#fff;}
/*dark blue*/
.bgcolor-12{background:#3498DB;color:#fff;}
/*light blue*/
.bgcolor-20{background:#494A5F;color:#D5D6E2;}
/* Header */
.htmleaf-header{padding:1em 190px 1em;letter-spacing:-1px;text-align:center;}
.htmleaf-header h1{color:#D5D6E2;font-weight:600;font-size:2em;line-height:1;margin-bottom:0;}
.htmleaf-header h1 span{display:block;font-size:60%;font-weight:400;padding:0.8em 0 0.5em 0;color:#c3c8cd;}
/*nav*/
.htmleaf-demo a{color:#fff;text-decoration:none;}
.htmleaf-demo{width:100%;padding-bottom:1.2em;}
.htmleaf-demo a{display:inline-block;margin:0.5em;padding:0.6em 1em;border:3px solid #fff;font-weight:700;}
.htmleaf-demo a:hover{opacity:0.6;}
.htmleaf-demo a.current{background:#1d7db1;color:#fff;}
/* Top Navigation Style */
.htmleaf-links{position:relative;display:inline-block;white-space:nowrap;font-size:1.5em;text-align:center;}
.htmleaf-links::after{position:absolute;top:0;left:50%;margin-left:-1px;width:2px;height:100%;background:#dbdbdb;content:'';-webkit-transform:rotate3d(0,0,1,22.5deg);transform:rotate3d(0,0,1,22.5deg);}
.htmleaf-icon{display:inline-block;margin:0.5em;padding:0em 0;width:1.5em;text-decoration:none;}
.htmleaf-icon span{display:none;}
.htmleaf-icon:before{margin:0 5px;text-transform:none;font-weight:normal;font-style:normal;font-variant:normal;font-family:'icomoon';line-height:1;speak:none;-webkit-font-smoothing:antialiased;}
/* footer */
.htmleaf-footer{width:100%;padding-top:10px;}
.htmleaf-small{font-size:0.8em;}
.center{text-align:center;}
/****/
.related{color:#fff;background:#494A5F;text-align:center;font-size:1.25em;padding:0.5em 0;overflow:hidden;}
.related > a{vertical-align:top;width:calc(100% - 20px);max-width:340px;display:inline-block;text-align:center;margin:20px 10px;padding:25px;font-family:"Microsoft YaHei","宋体","Segoe UI","Lucida Grande",Helvetica,Arial,sans-serif,FreeSans,Arimo;}
.related a{display:inline-block;text-align:left;margin:20px auto;padding:10px 20px;opacity:0.8;-webkit-transition:opacity 0.3s;transition:opacity 0.3s;-webkit-backface-visibility:hidden;}
.related a:hover,.related a:active{opacity:1;}
.related a img{max-width:100%;opacity:0.8;border-radius:4px;}
.related a:hover img,.related a:active img{opacity:1;}
.related h3{font-family:"Microsoft YaHei",sans-serif;font-size:1.2em}
.related a h3{font-size:0.85em;font-weight:300;margin-top:0.15em;color:#fff;}
/* icomoon */
.icon-htmleaf-home-outline:before{content:"\e5000";}
.icon-htmleaf-arrow-forward-outline:before{content:"\e5001";}
@media screen and (max-width:1024px){.htmleaf-header{padding:2em 10% 2em;}
.htmleaf-header h1{font-size:1.4em;}
.htmleaf-links{font-size:1.4em}
}
@media screen and (max-width:960px){.htmleaf-header{padding:2em 10% 2em;}
.htmleaf-header h1{font-size:1.2em;}
.htmleaf-links{font-size:1.2em}
.related h3{font-size:1em;}
.related a h3{font-size:0.8em;}
}
@media screen and (max-width:766px){.htmleaf-header h1{font-size:1.3em;}
.htmleaf-links{font-size:1.3em}
}
@media screen and (max-width:640px){.htmleaf-header{padding:2em 10% 2em;}
.htmleaf-header h1{font-size:1em;}
.htmleaf-links{font-size:1em}
.related h3{font-size:0.8em;}
.related a h3{font-size:0.6em;}
}