以下是 HTML5图片堆叠转瀑布流布局特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!doctype html>
<html lang="zh" class="no-js">
<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>HTML5图片堆叠转瀑布流布局特效 </title>
<!--<link href='https://fonts.googleapis.com/css?family=Caveat:400,700' rel='stylesheet' type='text/css'>-->
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/square-loader.min.css" />
<link rel="stylesheet" type="text/css" href="css/default.css">
<link rel="stylesheet" type="text/css" href="css/component.css" />
<!--[if IE]>
<script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
<script>
document.documentElement.className = 'js';
</script>
</head>
<body>
<div class="view">
<header class="header">
<nav class="demos">
<a class="demos__item demos__item--current" href="index.html">Default</a>
<a class="demos__item" href="index2.html">Spring</a>
</nav>
</header>
<section class="page page--mover">
<div class="la-square-loader"><div></div></div>
</section>
<div class="title-wrap">
<h1 class="title title--main">OH<em>!</em>SNAP</h1>
<p class="title title--sub">Smart Auto-Filtering for your shots.</p>
</div>
<section class="page page--static">
<div class="page__title">
<h2 class="page__title-main">超酷堆叠相片转瀑布流网格布局动画效果设计</h2>
<p class="page__title-sub">Recreating the effect seen on the takeit website</p>
</div>
<ul class="grid">
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/1.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/2.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/3.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/4.jpg" alt="Some image" />
<h3 class="grid__item-title">Drama where you need it</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/5.jpg" alt="Some image" />
<h3 class="grid__item-title">Realistic depth</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/6.jpg" alt="Some image" />
<h3 class="grid__item-title">The common, but special</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/7.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/8.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/9.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/1.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/2.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/3.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
</ul>
<button class="button button--load" aria-label="Load more images">
<svg class="polaroid" width="100%" height="100%" viewBox="0 0 220 243" preserveAspectRatio="xMidYMid meet">
<rect class="polaroid__base" x="0" y="0" width="220" height="243" rx="5"></rect>
<rect class="polaroid__inner" x="16" y="20" width="189" height="149"></rect>
<g class="polaroid__loader">
<circle cx="61.5" cy="94.5" r="17.5"></circle>
<circle cx="110.5" cy="94.5" r="17.5"></circle>
<circle cx="159.5" cy="94.5" r="17.5"></circle>
</g>
</svg>
<span class="button__text">Load more</span>
</button>
</section>
<div class="device">
<div class="device__screen"></div>
</div>
<button id="showgrid" class="button button--view" aria-label="Show me more">
<svg width="100%" height="100%" viewBox="0 0 310 177" preserveAspectRatio="xMidYMid meet">
<path fill="#FFFFFF" d="M159.875,174.481L306.945,27.41c2.93-2.929,2.93-7.678,0-10.606L292.803,2.661c-1.406-1.407-3.314-2.197-5.303-2.197c-1.989,0-3.896,0.79-5.303,2.197L154.572,130.287L26.946,2.661c-1.406-1.407-3.314-2.197-5.303-2.197c-1.989,0-3.897,0.79-5.303,2.197L2.197,16.804C0.733,18.269,0,20.188,0,22.107s0.732,3.839,2.197,5.303l147.071,147.071C152.197,177.411,156.945,177.411,159.875,174.481L159.875,174.481z" />
</svg>
</button>
</div><!-- /view -->
<script src="js/classie.js"></script>
<script src="js/dynamics.min.js"></script>
<script src="js/imagesloaded.pkgd.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
HTML代码(index2.html):
<!doctype html>
<html lang="zh" class="no-js">
<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>HTML5图片堆叠转瀑布流布局特效 - 程序员设计师联盟淘宝店</title>
<!--<link href='https://fonts.googleapis.com/css?family=Caveat:400,700' rel='stylesheet' type='text/css'>-->
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/square-loader.min.css" />
<link rel="stylesheet" type="text/css" href="css/default.css">
<link rel="stylesheet" type="text/css" href="css/component.css" />
<!--[if IE]>
<script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
<script>
document.documentElement.className = 'js';
</script>
</head>
<body>
<div class="view">
<header class="header">
<nav class="demos">
<a class="demos__item" href="index.html">Default</a>
<a class="demos__item demos__item--current" href="index2.html">Spring</a>
</nav>
</header>
<section class="page page--mover">
<div class="la-square-loader"><div></div></div>
</section>
<div class="title-wrap">
<h1 class="title title--main">OH<em>!</em>SNAP</h1>
<p class="title title--sub">Smart Auto-Filtering for your shots.</p>
</div>
<section class="page page--static">
<div class="page__title">
<h2 class="page__title-main">超酷堆叠相片转瀑布流网格布局动画效果设计</h2>
<p class="page__title-sub">Recreating the effect seen on the takeit website</p>
</div>
<ul class="grid">
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/1.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/2.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/3.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/4.jpg" alt="Some image" />
<h3 class="grid__item-title">Drama where you need it</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/5.jpg" alt="Some image" />
<h3 class="grid__item-title">Realistic depth</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/6.jpg" alt="Some image" />
<h3 class="grid__item-title">The common, but special</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/7.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/8.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/9.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/1.jpg" alt="Some image" />
<h3 class="grid__item-title">Natural saturation effects</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/2.jpg" alt="Some image" />
<h3 class="grid__item-title">Auto-color and light</h3>
</a>
</li>
<li class="grid__item">
<a class="grid__link" href="#">
<img class="grid__img" src="img/photos/3.jpg" alt="Some image" />
<h3 class="grid__item-title">That special blur</h3>
</a>
</li>
</ul>
<button class="button button--load" aria-label="Load more images">
<svg class="polaroid" width="100%" height="100%" viewBox="0 0 220 243" preserveAspectRatio="xMidYMid meet">
<rect class="polaroid__base" x="0" y="0" width="220" height="243" rx="5"></rect>
<rect class="polaroid__inner" x="16" y="20" width="189" height="149"></rect>
<g class="polaroid__loader">
<circle cx="61.5" cy="94.5" r="17.5"></circle>
<circle cx="110.5" cy="94.5" r="17.5"></circle>
<circle cx="159.5" cy="94.5" r="17.5"></circle>
</g>
</svg>
<span class="button__text">Load more</span>
</button>
</section>
<div class="device">
<div class="device__screen"></div>
</div>
<button id="showgrid" class="button button--view" aria-label="Show me more">
<svg width="100%" height="100%" viewBox="0 0 310 177" preserveAspectRatio="xMidYMid meet">
<path fill="#FFFFFF" d="M159.875,174.481L306.945,27.41c2.93-2.929,2.93-7.678,0-10.606L292.803,2.661c-1.406-1.407-3.314-2.197-5.303-2.197c-1.989,0-3.896,0.79-5.303,2.197L154.572,130.287L26.946,2.661c-1.406-1.407-3.314-2.197-5.303-2.197c-1.989,0-3.897,0.79-5.303,2.197L2.197,16.804C0.733,18.269,0,20.188,0,22.107s0.732,3.839,2.197,5.303l147.071,147.071C152.197,177.411,156.945,177.411,159.875,174.481L159.875,174.481z" />
</svg>
</button>
</div><!-- /view -->
<script src="js/classie.js"></script>
<script src="js/dynamics.min.js"></script>
<script src="js/imagesloaded.pkgd.min.js"></script>
<script src="js/main_2.js"></script>
</body>
</html>
JS代码(imagesloaded.pkgd.min.js):
/*! * imagesLoaded PACKAGED v4.1.0 * JavaScript is all like "You images are done yet or what?" * MIT License */
!function(t,e){
"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}
(this,function(){
function t(){
}
var e=t.prototype;
return e.on=function(t,e){
if(t&&e){
var i=this._events=this._events||{
}
,n=i[t]=i[t]||[];
return-1==n.indexOf(e)&&n.push(e),this}
}
,e.once=function(t,e){
if(t&&e){
this.on(t,e);
var i=this._onceEvents=this._onceEvents||{
}
,n=i[t]=i[t]||[];
return n[e]=!0,this}
}
,e.off=function(t,e){
var i=this._events&&this._events[t];
if(i&&i.length){
var n=i.indexOf(e);
return-1!=n&&i.splice(n,1),this}
}
,e.emitEvent=function(t,e){
var i=this._events&&this._events[t];
if(i&&i.length){
var n=0,o=i[n];
e=e||[];
for(var r=this._onceEvents&&this._onceEvents[t];
o;
){
var s=r&&r[o];
s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}
return this}
}
,t}
),function(t,e){
"use strict";
"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){
return e(t,i)}
):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}
(window,function(t,e){
function i(t,e){
for(var i in e)t[i]=e[i];
return t}
function n(t){
var e=[];
if(Array.isArray(t))e=t;
else if("number"==typeof t.length)for(var i=0;
i<t.length;
i++)e.push(t[i]);
else e.push(t);
return e}
function o(t,e,r){
return this instanceof o?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=n(t),this.options=i({
}
,this.options),"function"==typeof e?r=e:i(this.options,e),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){
this.check()}
.bind(this))):new o(t,e,r)}
function r(t){
this.img=t}
function s(t,e){
this.url=t,this.element=e,this.img=new Image}
var h=t.jQuery,a=t.console;
o.prototype=Object.create(e.prototype),o.prototype.options={
}
,o.prototype.getImages=function(){
this.images=[],this.elements.forEach(this.addElementImages,this)}
,o.prototype.addElementImages=function(t){
"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);
var e=t.nodeType;
if(e&&d[e]){
for(var i=t.querySelectorAll("img"),n=0;
n<i.length;
n++){
var o=i[n];
this.addImage(o)}
if("string"==typeof this.options.background){
var r=t.querySelectorAll(this.options.background);
for(n=0;
n<r.length;
n++){
var s=r[n];
this.addElementBackgroundImages(s)}
}
}
}
;
var d={
1:!0,9:!0,11:!0}
;
return o.prototype.addElementBackgroundImages=function(t){
var e=getComputedStyle(t);
if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);
null!==n;
){
var o=n&&n[2];
o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}
}
,o.prototype.addImage=function(t){
var e=new r(t);
this.images.push(e)}
,o.prototype.addBackground=function(t,e){
var i=new s(t,e);
this.images.push(i)}
,o.prototype.check=function(){
function t(t,i,n){
setTimeout(function(){
e.progress(t,i,n)}
)}
var e=this;
return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){
e.once("progress",t),e.check()}
):void this.complete()}
,o.prototype.progress=function(t,e,i){
this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress:"+i,t,e)}
,o.prototype.complete=function(){
var t=this.hasAnyBroken?"fail":"done";
if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){
var e=this.hasAnyBroken?"reject":"resolve";
this.jqDeferred[e](this)}
}
,r.prototype=Object.create(e.prototype),r.prototype.check=function(){
var t=this.getIsImageComplete();
return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))}
,r.prototype.getIsImageComplete=function(){
return this.img.complete&&void 0!==this.img.naturalWidth}
,r.prototype.confirm=function(t,e){
this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])}
,r.prototype.handleEvent=function(t){
var e="on"+t.type;
this[e]&&this[e](t)}
,r.prototype.onload=function(){
this.confirm(!0,"onload"),this.unbindEvents()}
,r.prototype.onerror=function(){
this.confirm(!1,"onerror"),this.unbindEvents()}
,r.prototype.unbindEvents=function(){
this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)}
,s.prototype=Object.create(r.prototype),s.prototype.check=function(){
this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;
var t=this.getIsImageComplete();
t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())}
,s.prototype.unbindEvents=function(){
this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)}
,s.prototype.confirm=function(t,e){
this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])}
,o.makeJQueryPlugin=function(e){
e=e||t.jQuery,e&&(h=e,h.fn.imagesLoaded=function(t,e){
var i=new o(this,t,e);
return i.jqDeferred.promise(h(this))}
)}
,o.makeJQueryPlugin(),o}
);
JS代码(main.js):
/** * main.js * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Copyright 2016,Codrops * http://www.codrops.com */
;
(function(window){
'use strict';
// helper functions/** * enable/disable page scrolling. from http://stackoverflow.com/a/4770179 */
// left:37,up:38,right:39,down:40,// spacebar:32,pageup:33,pagedown:34,end:35,home:36var keys ={
37:1,38:1,39:1,40:1}
;
function preventDefault(e){
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e){
if (keys[e.keyCode]){
preventDefault(e);
return false;
}
}
function disableScroll(){
if (window.addEventListener) // older FF window.addEventListener('DOMMouseScroll',preventDefault,false);
window.onwheel = preventDefault;
// modern standard window.onmousewheel = document.onmousewheel = preventDefault;
// older browsers,IE window.ontouchmove = preventDefault;
// mobile document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll(){
if (window.removeEventListener)window.removeEventListener('DOMMouseScroll',preventDefault,false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
/** * from https://davidwalsh.name/javascript-debounce-function */
function debounce(func,wait,immediate){
var timeout;
return function(){
var context = this,args = arguments;
var later = function(){
timeout = null;
if (!immediate) func.apply(context,args);
}
;
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later,wait);
if (callNow) func.apply(context,args);
}
;
}
;
/** * from http://stackoverflow.com/a/7228322 */
function randomIntFromInterval(min,max){
return Math.floor(Math.random()*(max-min+1)+min);
}
// main page containervar mainContainer = document.querySelector('.view'),// the grid elementgridEl = mainContainer.querySelector('.grid'),// grid itemsgridItems = [].slice.call(gridEl.querySelectorAll('.grid__item')),// main title elementtitleEl = mainContainer.querySelector('.title-wrap > .title--main'),// main subtitle elementsubtitleEl = mainContainer.querySelector('.title-wrap > .title--sub'),// the fullscreen element/division that will slide up,giving the illusion the items will fall downpagemover = mainContainer.querySelector('.page--mover'),// the loading element shown while the images are loadedloadingStatusEl = pagemover.querySelector('.la-square-loader'),// window sizes (width and height)winsize ={
width:window.innerWidth,height:window.innerHeight}
,// translation values (x and y):percentages of the item´s width and height;
scale value;
rotation (z) value// these are the values that the 6 initial images will haveintroPositions = [{
tx:-.6,ty:-.3,s:1.1,r:-20}
,{
tx:.2,ty:-.7,s:1.4,r:1}
,{
tx:.5,ty:-.5,s:1.3,r:15}
,{
tx:-.2,ty:-.4,s:1.4,r:-17}
,{
tx:-.15,ty:-.4,s:1.2,r:-5}
,{
tx:.7,ty:-.2,s:1.1,r:15}
],// the phonedeviceEl = mainContainer.querySelector('.device'),// the animated button that triggers the effect when clickedshowGridCtrl = document.getElementById('showgrid'),// the title and subtitle shown on top of the gridpageTitleEl = mainContainer.querySelector('.page__title > .page__title-main'),pageSubTitleEl = mainContainer.querySelector('.page__title > .page__title-sub'),// the grid´s load more buttonloadMoreCtrl = mainContainer.querySelector('button.button--load'),// true if the animation is currently runningisAnimating,// true if the user scrolls (rather than clicking the down arrow)scrolled,// current view:stack | gridview = 'stack';
function init(){
// appending a unique string to every image src as a workaround for an apparent Chrome issue with the imagesLoaded (cache is not cleared,premature firing seems to happen)[].slice.call(gridEl.querySelectorAll('img')).forEach(function(el){
el.src += '?' + Number(new Date());
}
);
// disable scroll while loading imagesclassie.add(document.body,'overflow');
disableScroll();
// preload imagesimagesLoaded(gridEl,function(){
// enable page scroll againenableScroll();
// controls the visibility of the grid items. Adding this class will make them visible.classie.add(mainContainer,'view--loaded');
// show initial viewshowIntro();
// bind eventsinitEvents();
}
);
}
/** * shows the initial stack with the 6 images behind the phone */
function showIntro(){
// display the first set of 6 grid items behind the phonegridItems.slice(0,6).forEach(function(item,pos){
// first we position all the 6 items on the bottom of the page (item´s center is positioned on the middle of the page bottom)// then we move them up and to the sides (extra values) and also apply a scale and rotationvar itemOffset = item.getBoundingClientRect(),settings = introPositions[pos],center ={
x:winsize.width/2 - (itemOffset.left + item.offsetWidth/2),y:winsize.height - (itemOffset.top + item.offsetHeight/2)}
;
// first position the items behind the phonedynamics.css(item,{
opacity:1,translateX:center.x,translateY:center.y,scale:0.5}
);
// now animate each item to its final positiondynamics.animate(item,{
translateX:center.x + settings.tx*item.offsetWidth,translateY:center.y + settings.ty*item.offsetWidth,scale:settings.s,rotateZ:settings.r}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:1000,delay:pos * 80}
);
}
);
// also animate/slide the device in:// first,push it slightly down (to make it complete out of the viewport we´d need to set the translateY to winsize.height * 0.45 --> 45vh)dynamics.css(deviceEl,{
translateY:winsize.height * 0.25}
);
// now animate it updynamics.animate(deviceEl,{
translateY:0}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:1000}
);
}
/** * bind/initialize the events */
function initEvents(){
// show the grid when the showGridCtrl is clickedshowGridCtrl.addEventListener('click',showGrid);
// show the grid when the user scrolls the pagevar scrollfn = function(){
scrolled = true;
showGrid();
window.removeEventListener('scroll',scrollfn);
}
;
window.addEventListener('scroll',scrollfn);
// todo:show/load more grid itemsloadMoreCtrl.addEventListener('click',loadNextItems);
// window resize:recalculate window sizes and reposition the 6 grid items behind the phone (if the grid view is not yet shown)window.addEventListener('resize',debounce(function(ev){
// reset window sizeswinsize ={
width:window.innerWidth,height:window.innerHeight}
;
if( view === 'stack' ){
gridItems.slice(0,6).forEach(function(item,pos){
// first reset all itemsdynamics.css(item,{
scale:1,translateX:0,translateY:0,rotateZ:0}
);
// now,recalculate..var itemOffset = item.getBoundingClientRect(),settings = introPositions[pos];
dynamics.css(item,{
translateX:winsize.width/2 - (itemOffset.left + item.offsetWidth/2) + settings.tx*item.offsetWidth,translateY:winsize.height - (itemOffset.top + item.offsetHeight/2) + settings.ty*item.offsetWidth,scale:settings.s,rotateZ:settings.r}
);
}
);
}
}
,10));
}
/** * shows the grid */
function showGrid(){
// return if currently animatingif( isAnimating ) return;
isAnimating = true;
// hide the showGrid ctrldynamics.css(showGridCtrl,{
display:'none'}
);
// main title animationdynamics.animate(titleEl,{
translateY:-winsize.height/2,opacity:0}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.7,"y":0}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:600}
);
// main subtitle animationdynamics.animate(subtitleEl,{
translateY:-winsize.height/2,opacity:0}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.7,"y":0}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:600,delay:100}
);
// device animationdynamics.animate(deviceEl,{
translateY:500,opacity:0}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.7,"y":0}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:600}
);
// pagemover animationdynamics.animate(pagemover,{
translateY:-winsize.height}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.7,"y":0}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:600,delay:scrolled ? 0:120,complete:function(el){
// hide the pagemoverdynamics.css(el,{
opacity:0}
);
// view is now ´grid´view = 'grid';
classie.add(mainContainer,'view--grid');
}
}
);
// items animationgridItems.slice(0,6).forEach(function(item,pos){
dynamics.stop(item);
dynamics.animate(item,{
scale:1,translateX:0,translateY:0,rotateZ:0}
,{
type:dynamics.easeInOut,duration:600,delay:scrolled ? 0:120}
);
}
);
// page title animationdynamics.css(pageTitleEl,{
translateY:200,opacity:0}
);
dynamics.animate(pageTitleEl,{
translateY:0,opacity:1}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:800,delay:400}
);
// page subtitle animationdynamics.css(pageSubTitleEl,{
translateY:150,opacity:0}
);
dynamics.animate(pageSubTitleEl,{
translateY:0,opacity:1}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:800,delay:500}
);
// the remaining grid itemsgridItems.slice(6).forEach(function(item){
dynamics.css(item,{
scale:0,opacity:0}
);
dynamics.animate(item,{
scale:1,opacity:1}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:800,delay:randomIntFromInterval(100,400)}
);
}
);
}
/** * dummy fn:simulate the load of the next grid items */
function loadNextItems(){
// loadMoreCtrl button gets class button--loading. This will transform the button into a loading/animated buttonclassie.add(loadMoreCtrl,'button--loading');
// the timeout serves to simulate the time that we would probably wait for the responsesetTimeout(function(){
// hide buttonclassie.add(loadMoreCtrl,'button--hidden');
// add some extra items to the gridvar dummyContent = '<li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/1.jpg" alt="Some image" /><h3 class="grid__item-title">Natural saturation effects</h3></a></li><li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/2.jpg" alt="Some image" /><h3 class="grid__item-title">Auto-color and light</h3></a></li><li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/3.jpg" alt="Some image" /><h3 class="grid__item-title">That special blur</h3></a></li><li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/4.jpg" alt="Some image" /><h3 class="grid__item-title">Drama where you need it</h3></a></li><li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/5.jpg" alt="Some image" /><h3 class="grid__item-title">Realistic depth</h3></a></li><li class="grid__item grid__item--hidden"><a class="grid__link" href="#"><img class="grid__img" src="img/photos/6.jpg" alt="Some image" /><h3 class="grid__item-title">The common,but special</h3></a></li>';
gridEl.innerHTML += dummyContent;
[].slice.call(gridEl.querySelectorAll('.grid__item--hidden')).forEach(function(item){
gridItems.push(item);
dynamics.css(item,{
scale:0,opacity:0}
);
classie.remove(item,'grid__item--hidden');
dynamics.animate(item,{
scale:1,opacity:1}
,{
type:dynamics.bezier,points:[{
"x":0,"y":0,"cp":[{
"x":0.2,"y":1}
]}
,{
"x":1,"y":1,"cp":[{
"x":0.3,"y":1}
]}
],duration:800,delay:randomIntFromInterval(0,300)}
);
}
);
}
,1500);
}
// force the scrolling to the top of the page (from http://stackoverflow.com/a/23312671)window.onbeforeunload = function(){
window.scrollTo(0,0);
}
init();
}
)(window);
CSS代码(demo.css):
@font-face{font-family:'codropsicons';font-weight:normal;font-style:normal;src:url('../fonts/codropsicons/codropsicons.eot');src:url('../fonts/codropsicons/codropsicons.eot?#iefix') format('embedded-opentype'),url('../fonts/codropsicons/codropsicons.woff') format('woff'),url('../fonts/codropsicons/codropsicons.ttf') format('truetype'),url('../fonts/codropsicons/codropsicons.svg#codropsicons') format('svg');}
*,*::after,*::before{-webkit-box-sizing:border-box;box-sizing:border-box;}
body{font-family:'Avenir Next',Avenir,'Helvetica Neue',Helvetica,Arial,sans-serif;overflow-x:hidden;color:#a5aeb5;background:#e9ecef;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}
a{text-decoration:none;color:#df2d70;outline:none;}
a:hover,a:focus{color:#03a9f4;}
/* Top Navigation Style */
.codrops-links{position:relative;display:inline-block;text-align:center;white-space:nowrap;pointer-events:auto;border:2px solid #fff;}
.codrops-links::after{content:'';position:absolute;top:50%;left:50%;width:2px;height:110%;margin-left:-1px;background:#fff;-webkit-transform:translateY(-50%) rotate3d(0,0,1,22.5deg);transform:translateY(-50%) rotate3d(0,0,1,22.5deg);}
.codrops-icon{display:inline-block;width:1.5em;margin:0.5em;padding:0em 0;text-decoration:none;}
.codrops-icon span{display:none;}
.codrops-icon::before{font-family:'codropsicons';font-weight:normal;font-style:normal;font-variant:normal;line-height:1;margin:0 5px;text-transform:none;-webkit-font-smoothing:antialiased;speak:none;}
.codrops-icon--drop::before{content:'\e001';color:#09c;}
.codrops-icon--prev::before{content:'\e004';color:#fff;}
/* Demos */
.demos__item{font-weight:bold;display:inline-block;margin:0.25em 0.75em;pointer-events:auto;}
.demos__item--current,.demos__item--current:hover,.demos__item--current:focus{color:#96acb6;border-bottom:2px solid;}
/* Content */
.content{padding:3em 0;}
/* Related demos */
.content--related{font-weight:bold;margin:8em 0 0 0;padding:8em 0;text-align:center;color:#fff;background:#2d323c;}
.media-item{display:inline-block;padding:1em;vertical-align:top;color:#1e2129;-webkit-transition:color 0.3s;transition:color 0.3s;}
.media-item:hover,.media-item:focus{color:#fff;}
.media-item__img{max-width:100%;opacity:0.6;-webkit-transition:opacity 0.3s;transition:opacity 0.3s;}
.media-item:hover .media-item__img,.media-item:focus .media-item__img{opacity:1;}
.media-item__title{font-size:1em;margin:0;padding:0.5em;}
CSS代码(normalize.css):
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}
audio,canvas,video{display:inline-block;}
audio:not([controls]){display:none;height:0;}
[hidden]{display:none;}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}
body{margin:0;}
a:focus{outline:thin dotted;}
a:active,a:hover{outline:0;}
h1{font-size:2em;margin:0.67em 0;}
abbr[title]{border-bottom:1px dotted;}
b,strong{font-weight:bold;}
dfn{font-style:italic;}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}
mark{background:#ff0;color:#000;}
code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}
pre{white-space:pre-wrap;}
q{quotes:"\201C" "\201D" "\2018" "\2019";}
small{font-size:80%;}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}
sup{top:-0.5em;}
sub{bottom:-0.25em;}
img{border:0;}
svg:not(:root){overflow:hidden;}
figure{margin:0;}
fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}
legend{border:0;padding:0;}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}
button,input{line-height:normal;}
button,select{text-transform:none;}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
button[disabled],html input[disabled]{cursor:default;}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
textarea{overflow:auto;vertical-align:top;}
table{border-collapse:collapse;border-spacing:0;}