这是一款使用GSAP的TweenMax.js和CSS3来制作的效果炫酷的盒子爆炸动画特效。该爆炸动画在用户点击页面中的一个弹跳的盒子的时候,盒子会爆炸为烟雾,然后会出现SVG Logo,整个效果非常连贯逼真。
该盒子爆炸效果的HTML结构如下:div.-box
是一个立方体盒子,div.explode
用于制作爆炸的烟雾效果。svg.icon
则是最后出现的SVG Logo。
<div class="-content -index"> <div> <div class="bounce-wrap"> <div class="bounce"> <div class="-shadow"></div> <div class="-box-wrap js-box-wrap"> <div class="-box"> <div class="front wall"></div> <div class="back wall"></div> <div class="right wall"></div> <div class="left wall"></div> <div class="front-right wall"></div> <div class="front-left wall"></div> <div class="back-right wall"></div> <div class="back-left wall"></div> </div> </div> <div id="emitter"></div> <div class="explode"> <span class="cloud -one js-cloud-1"></span> <span class="cloud -two js-cloud-2"></span> <span class="cloud -three js-cloud-3"></span> </div> <svg class="icon js-icon-logo" viewBox="0 0 162.5 47"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#logo_technology"></use> </svg> </div> </div> </div> </div>
在CSS样式中,主要是制作盒子的立方体效果,以及使用CSS3帧动画来制作盒子的弹性和阴影动画效果。
盒子的弹性和阴影动画效果。
@-webkit-keyframes bounce { 0% { -webkit-transform: translateY(0); transform: translateY(0); } 100% { -webkit-transform: translateY(-25px); transform: translateY(-25px); } } @keyframes bounce { 0% { -webkit-transform: translateY(0); transform: translateY(0); } 100% { -webkit-transform: translateY(-25px); transform: translateY(-25px); } } @-webkit-keyframes shadow { 0% { background: rgba(0, 0, 0, 0.5); -webkit-transform: scale(0.75) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); transform: scale(0.75) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); box-shadow: 0 0 0px rgba(0, 0, 0, 0.6); } 100% { background: rgba(0, 0, 0, 0.15); -webkit-transform: scale(1) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); transform: scale(1) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); } } @keyframes shadow { 0% { background: rgba(0, 0, 0, 0.5); -webkit-transform: scale(0.75) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); transform: scale(0.75) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); box-shadow: 0 0 0px rgba(0, 0, 0, 0.6); } 100% { background: rgba(0, 0, 0, 0.15); -webkit-transform: scale(1) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); transform: scale(1) rotateX(75deg) rotateY(0deg) rotateZ(-45deg); box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); } }
盒子的立方体效果:由于IE浏览器不支持transform-style: preserve-3d;
属性,所以在IE浏览器中看不到盒子的立体效果。
.bounce .-box { width: 32px; height: 32px; position: relative; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-transform: rotateX(-14deg) rotateY(-45deg) rotateZ(0deg); transform: rotateX(-14deg) rotateY(-45deg) rotateZ(0deg); } .bounce .-box .wall { width: 32px; height: 32px; position: absolute; -webkit-transition: all 1s ease-out; transition: all 1s ease-out; -webkit-backface-visibility: hidden; backface-visibility: hidden; } .bounce .-box .front { background: #f8f8fc; -webkit-transform: rotateX(0deg) rotateY(0deg) translateZ(16px) rotateX(90deg); transform: rotateX(0deg) rotateY(0deg) translateZ(16px) rotateX(90deg); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; height: 50%; z-index: 1; } .bounce .-box .right { height: 32px; background: #f8f8fc; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-transform: translateX(16px) rotateY(90deg) rotateX(90deg); transform: translateX(16px) rotateY(90deg) rotateX(90deg); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; height: 50%; z-index: 1; } .bounce .-box .back { background: #f8f8fc; -webkit-transform: rotateY(180deg) translateZ(16px) rotateX(90deg); transform: rotateY(180deg) translateZ(16px) rotateX(90deg); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; height: 50%; } .bounce .-box .left { background: #f8f8fc; -webkit-transform: translateX(-16px) rotateY(-90deg) rotateX(90deg); transform: translateX(-16px) rotateY(-90deg) rotateX(90deg); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; height: 50%; } .bounce .-box .front-left { background: #d1d5e9; height: 32px; -webkit-transform: rotateX(0deg) rotateY(0deg) translateZ(16px) translateY(16px); transform: rotateX(0deg) rotateY(0deg) translateZ(16px) translateY(16px); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; } .bounce .-box .front-right { background: #96a0ce; height: 32px; -webkit-transform: translateX(16px) rotateY(90deg) translateY(16px); transform: translateX(16px) rotateY(90deg) translateY(16px); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; } .bounce .-box .back-left { background: #b0c2d6; height: 32px; -webkit-transform: rotateX(0deg) translateX(-16px) rotateY(-90deg) translateY(16px); transform: rotateX(0deg) translateX(-16px) rotateY(-90deg) translateY(16px); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; } .bounce .-box .back-right { background: #8a9fb4; height: 32px; -webkit-transform: rotateX(0deg) rotateY(180deg) translateZ(16px) translateY(16px); transform: rotateX(0deg) rotateY(180deg) translateZ(16px) translateY(16px); -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; }
该特性依赖于GSAP的TweenMax.js,使用时需要将其引入。
<script src="js/jquery.min.js"></script> <script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js'></script>
该盒子爆炸动画特性的主要JS代码如下:
function init() { var emitter = document.getElementById("emitter"), container = document.createElement("div"), emitterSize = 100, dotQuantity = 50, dotSizeMax = 100, dotSizeMin = 10, speed = 1, gravity = 1; container.setAttribute("id", "emit-wrap"); //setup the container with the appropriate styles container.style.cssText = "position:absolute; left:0; top:0; overflow:visible; z-index:5000; pointer-events:none;"; document.body.appendChild(container); function createExplosion(container) { var tl = new TimelineLite({ onComplete: function() { $('#emit-wrap').remove(); } }), angle, length, dot, i, size; //create all the dots for (i = 0; i < dotquantity;="" i++)="" {="" dot="document.createElement("div");" dot.classname="emitter-dot" ;="" size="getRandom(dotSizeMin," dotsizemax);="" container.appendchild(dot);="" angle="Math.random()" *="" math.pi="" *="" 2;="" length="Math.random()" *="" (emittersize="" 2="" -="" size="" 2);="" tweenlite.set(dot,="" {="" x:="" math.cos(angle)="" *="" length,="" y:="" math.sin(angle)="" *="" length,="" width:="" size,="" height:="" size,="" xpercent:="" -50,="" ypercent:="" -50,="" force3d:="" true="" });="" this="" is="" where="" we="" do="" the="" animation...="" tl.to(dot,="" 1="" +="" math.random(),="" {="" opacity:="" 0,="" x:="" math.cos(angle)="" *="" length="" *="" 24,="" y:="" math.sin(angle)="" *="" length="" *="" 24="" },="" 0);="" }="" return="" tl;="" }="" function="" explode(element)="" {="" var="" explosion="createExplosion(container);" var="" bounds="element.getBoundingClientRect();" var="" offset="$(element).offset();" var="" width="$(element).width();" var="" height="$(element).height();" tweenlite.set(container,="" {="" x:="" bounds.left="" +="" bounds.width="" 2,="" y:="" bounds.top="" +="" bounds.height="" 2="" });="" tweenlite.set(container,="" {="" x:="" offset.left="" +="" width="" 2,="" y:="" offset.top="" +="" height="" 2="" });="" explosion.restart();="" }="" function="" getrandom(min,="" max)="" {="" return="" min="" +="" math.random()="" *="" (max="" -="" min);="" }="" emitter.onmousedown="emitter.ontouchstart" =="" function()="" {="" explode(emitter);="" $(emitter).hide();="" $('.-shadow').hide();="" $('.js-box-wrap').hide();="" settimeout(function(){="" $('.js-trigger-reset').css({="" 'display':="" 'inline-block'="" });="" },="" 2000);="" var="" tl="new" timelinemax();="" tl.add("logo")="" .add(logoreveal,"logo");="" }="" }="" function="" logoreveal()="" {="" var="" logoreveal="new" timelinemax();="" logoreveal.to('.js-icon-logo',="" 1,="" {autoalpha:="" 1,="" ease:="" power4.easeout});="" return="" logoreveal;="" }="" function="" reset()="" {="" $('.-shadow').attr('style',="" '');="" $('.js-box-wrap').attr('style',="" '');="" $('.js-icon-logo').attr('style',="" '');="" $('#emitter').attr('style',="" '');="" $('.js-trigger-reset').hide();="" }="" $(document).ready(function="" ()="" {="" init();="" $('.js-trigger-reset').click(function()="" {="" reset();="" init();="" });="" });="">