这是一款效果非常炫酷的HTML5 SVG和CSS3蹦床式图片切换特效插件。该图片切换插件在进行图片切换时,整个屏幕就像一张大蹦床一样,将图片弹射出去,切换到另一张图片,效果非常有创意。另外,所有图片都以栈的方式堆叠在一起,你也可以使用鼠标来拖拽图片,拖拽效果就和《拖拽式超弹性效果堆叠图片切换展示特效》一样。背景蹦床效果使用SVG来制作,通过Snap.svg来制作动画效果。整个动画动使用 CSS Transitions 来制作平滑的过渡效果。
HTML结构
该图片切换特效的HTML结构中,第一个元素是SVG图形,当切换图片时,它将从一个规则的矩形变为一个被压缩的矩形。
规则的SVG矩形图形保存在SVG path
中,被压缩的SVG矩形图形则保存在data-morph-next
属性中。
图片栈的HTML结构如下:
"Once you have eliminated the impossible, whatever remains, however improbable, must be the truth."
"The needs of the many outweigh the needs of the few, or the one."
"Insufficient facts always invite danger."
"Without followers, evil cannot spread."
"Logic is the beginning of wisdom, not the end."
"Change is the essential process of all existence."
上面的结构包括一个图片栈、一个用于导航到下一张图片的图标按钮和一组图片标题。
CSS样式
SVG“蹦床”矩形需要和屏幕一样大小:
.morph-shape { position: absolute; width: 100%; height: 100%; top: 0; left: 0; } .morph-shape svg { position: absolute; margin: 0; pointer-events: none; }
为了制作一些3D效果,插件在图片栈的图片列表ul
元素上使用了perspective
。在下面的这段CSS代码中,最后两个class是在拖动或动画图片栈是通过js动态添加的。
.stack ul { position: relative; margin: 0 auto; padding: 0; list-style: none; } .stack ul li { position: absolute; width: 100%; opacity: 0; } ul.stack__images { width: 400px; height: 300px; z-index: 10; perspective: 1000px; perspective-origin: 50% -50%; } @media screen and (max-height: 530px), screen and (max-width: 400px) { ul.stack__images { width: 260px; height: 195px; } } .stack__images li { top: 0; z-index: 1; transform: translate3d(0, 0, -180px); transform-style: preserve-3d; } .stack__images li img { display: block; max-width: 100%; pointer-events: none; } .stack__images li:hover { cursor: url(../img/cursor_vulcan.png), auto; } .stack__images li:active { cursor: -webkit-grabbing; cursor: grabbing; } .stack__images li.animate { transition: all 0.3s ease-out; } .stack__images li.move-back { transition-timing-function: cubic-bezier(0.175, 0.885, 0.470, 1.515); }
其它元素,如导航图标按钮和图片标题的样式如下:
.stack__next { border: none; background: none; display: block; padding: 0; overflow: hidden; width: 36px; height: 36px; margin: 10px auto 0; font-size: 30px; position: relative; cursor: pointer; color: #067ba7; } .stack__next:hover { color: #fff; } .stack__next:focus { outline: none; } .stack__next span { position: absolute; top: 200%; } ul.stack__titles { height: 18vh; max-width: 560px; width: 95%; } .stack__titles blockquote { margin: 0; text-align: center; font-size: 1.4em; } .stack__titles blockquote footer { font-size: 50%; padding-bottom: 1em; font-family: 'Montserrat', Arial, sans-serif; } .stack__titles li { pointer-events: none; transition: opacity 0.45s ease; } .stack__titles li.current { opacity: 1; pointer-events: auto; }
图片标题绘制图片切换时淡入淡出的显示。
最后,插件中为图片维护动画效果添加了一些过渡效果,SVG图形在执行“蹦床”动画的时候将会被填充,SVG图形的父容器会使用3D transform
沿Z轴推拉页面。这个效果是写在base.css
样式表中。
当切换图片的时候,navigate-next
class会被添加到元素上。在第二个例子中,添加了一些旋转效果,在Z轴上旋转10deg和在X轴上旋转-5deg。
.morph-shape svg { fill: #01AEF0; transition: fill 0.1s ease-out; } .navigate-next .morph-shape svg { fill: #01a0dc; transition-duration: 0.45s; } .container { transition: transform 0.1s cubic-bezier(0.6, 0, 0.5, 1); } .demo-1.navigate-next .container { transition-duration: 0.45s; transform: translate3d(0, 0, -600px); } .demo-2.navigate-next .container { transition-duration: 0.45s; transform: rotate3d(-0.5, 0, 1, -6deg) translate3d(0, 0, -600px); } .demo-2 .morph-shape svg { fill: #A2CD72; } .demo-2.navigate-next .morph-shape svg { fill: #95C264; }
JAVASCRIPT
js文件部分,需要引入snap.svg-min.js
文件和Modernizr文件。还需要Draggabilly和elastiStack.js
文件来制作堆叠图片栈和拖拽效果。插件中的js代码关注于SVG图形的变形和导航事件的处理,以及图片标题效果的处理。
(function() { var body = document.body, titles = [].slice.call( document.querySelectorAll( '#stack-titles > li' ) ), totalTitles = titles.length, stack = new ElastiStack( document.getElementById( 'elasticstack' ), { onUpdateStack : function( idx ) { classie.remove( titles[idx === 0 ? totalTitles - 1 : idx - 1], 'current' ); classie.add( titles[idx], 'current' ); } } ), shapeEl = document.getElementById( 'morph-shape' ), s = Snap( shapeEl.querySelector( 'svg' ) ), pathEl = s.select( 'path' ), paths = { reset : pathEl.attr( 'd' ), next : shapeEl.getAttribute( 'data-morph-next' ) }; document.getElementById( 'stack-next' ).addEventListener( 'mousedown', nextItem ); function nextItem() { classie.add( body, 'animating' ); classie.add( body, 'navigate-next' ); pathEl.stop().animate( { 'path' : paths.next }, 450, mina.easeinout, function() { classie.remove( body, 'navigate-next' ); stack.nextItem( { transform : 'translate3d(0,-60px,400px)' } ); pathEl.stop().animate( { 'path' : paths.reset }, 100, mina.easeout, function() { classie.remove( body, 'animating' ); } ); } ); } })();
动态评分
0