这是一款使用GSAP的TweenMax.js和CSS3来制作的效果炫酷的盒子爆炸动画特效。该爆炸动画在用户点击页面中的一个弹跳的盒子的时候,盒子会爆炸为烟雾,然后会出现SVG Logo,整个效果非常连贯逼真。
使用方法
HTML结构
该盒子爆炸效果的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样式
在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%; }
JavaScript
该特性依赖于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(); }); });