实例介绍
【实例简介】canvas炫酷动画飞爆效果
【实例截图】
【核心代码】
| <style class="cp-pen-styles"> | |
| body{background-color:#2E2E2E;margin:0;overflow:hidden;} | |
| canvas{position:absolute;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;} | |
| img{position:absolute;cursor:pointer;} | |
| #container{width:100%;height:auto;} | |
| </style> | |
| <!--[if IE]> | |
| <script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script> | |
| <![endif]--> | |
| </head> | |
| <body> | |
| <!-- 代码部分begin --> | |
| <div class="lanren-container"> | |
| <div id="container"></div> | |
| </div> | |
| <script src="js/delaunay.js"></script> | |
| <script src="js/TweenMax.min.js"></script> | |
| <script src='js/stopExecutionOnTimeout.js?t=1'></script> | |
| <script> | |
| const TWO_PI = Math.PI * 2; | |
| var images = [], imageIndex = 0; | |
| var image, imageWidth = 768, imageHeight = 485; | |
| var vertices = [], indices = [], fragments = []; | |
| var container = document.getElementById('container'); | |
| var clickPosition = [ | |
| imageWidth * 0.5, | |
| imageHeight * 0.5 | |
| ]; | |
| window.onload = function () { | |
| TweenMax.set(container, { perspective: 500 }); | |
| var urls = [ | |
| 'images/crayon.jpg', | |
| 'images/spaceship.jpg', | |
| 'images/dj.jpg', | |
| 'images/chicken.jpg' | |
| ], image, loaded = 0; | |
| images[0] = image = new Image(); | |
| image.onload = function () { | |
| if ( loaded === 1) { | |
| imagesLoaded(); | |
| for (var i = 1; i < 4; i ) { | |
| if (window.CP.shouldStopExecution(1)) { | |
| break; | |
| } | |
| images[i] = image = new Image(); | |
| image.src = urls[i]; | |
| } | |
| window.CP.exitedLoop(1); | |
| } | |
| }; | |
| image.src = urls[0]; | |
| }; | |
| function imagesLoaded() { | |
| placeImage(false); | |
| triangulate(); | |
| shatter(); | |
| } | |
| function placeImage(transitionIn) { | |
| image = images[imageIndex]; | |
| if ( imageIndex === images.length) | |
| imageIndex = 0; | |
| image.addEventListener('click', imageClickHandler); | |
| container.appendChild(image); | |
| if (transitionIn !== false) { | |
| TweenMax.fromTo(image, 0.75, { y: -1000 }, { | |
| y: 0, | |
| ease: Elastic.easeOut | |
| }); | |
| } | |
| } | |
| function imageClickHandler(event) { | |
| var box = image.getBoundingClientRect(), top = box.top, left = box.left; | |
| clickPosition[0] = event.clientX - left; | |
| clickPosition[1] = event.clientY - top; | |
| triangulate(); | |
| shatter(); | |
| } | |
| function triangulate() { | |
| var rings = [ | |
| { | |
| r: 50, | |
| c: 12 | |
| }, | |
| { | |
| r: 150, | |
| c: 12 | |
| }, | |
| { | |
| r: 300, | |
| c: 12 | |
| }, | |
| { | |
| r: 1200, | |
| c: 12 | |
| } | |
| ], x, y, centerX = clickPosition[0], centerY = clickPosition[1]; | |
| vertices.push([ | |
| centerX, | |
| centerY | |
| ]); | |
| rings.forEach(function (ring) { | |
| var radius = ring.r, count = ring.c, variance = radius * 0.25; | |
| for (var i = 0; i < count; i ) { | |
| if (window.CP.shouldStopExecution(2)) { | |
| break; | |
| } | |
| x = Math.cos(i / count * TWO_PI) * radius centerX randomRange(-variance, variance); | |
| y = Math.sin(i / count * TWO_PI) * radius centerY randomRange(-variance, variance); | |
| vertices.push([ | |
| x, | |
| y | |
| ]); | |
| } | |
| window.CP.exitedLoop(2); | |
| }); | |
| vertices.forEach(function (v) { | |
| v[0] = clamp(v[0], 0, imageWidth); | |
| v[1] = clamp(v[1], 0, imageHeight); | |
| }); | |
| indices = Delaunay.triangulate(vertices); | |
| } | |
| function shatter() { | |
| var p0, p1, p2, fragment; | |
| var tl0 = new TimelineMax({ onComplete: shatterCompleteHandler }); | |
| for (var i = 0; i < indices.length; i = 3) { | |
| if (window.CP.shouldStopExecution(3)) { | |
| break; | |
| } | |
| p0 = vertices[indices[i 0]]; | |
| p1 = vertices[indices[i 1]]; | |
| p2 = vertices[indices[i 2]]; | |
| fragment = new Fragment(p0, p1, p2); | |
| var dx = fragment.centroid[0] - clickPosition[0], dy = fragment.centroid[1] - clickPosition[1], d = Math.sqrt(dx * dx dy * dy), rx = 300 * sign(dy), ry = 900 * -sign(dx), delay = d * 0.003 * randomRange(0.1, 0.25); | |
| fragment.canvas.style.zIndex = Math.floor(d).toString(); | |
| var tl1 = new TimelineMax(); | |
| tl1.to(fragment.canvas, randomRange(0.25, 1), { | |
| z: randomRange(-1500, 1500), | |
| rotationX: rx, | |
| rotationY: ry, | |
| x: randomRange(-2000, 2000), | |
| y: randomRange(-2000, 2000), | |
| ease: Expo.easeIn | |
| }); | |
| tl1.to(fragment.canvas, 0.4, { alpha: 0 }, 0.6); | |
| tl0.insert(tl1, delay); | |
| fragments.push(fragment); | |
| container.appendChild(fragment.canvas); | |
| } | |
| window.CP.exitedLoop(3); | |
| container.removeChild(image); | |
| image.removeEventListener('click', imageClickHandler); | |
| } | |
| function shatterCompleteHandler() { | |
| fragments.forEach(function (f) { | |
| container.removeChild(f.canvas); | |
| }); | |
| fragments.length = 0; | |
| vertices.length = 0; | |
| indices.length = 0; | |
| placeImage(); | |
| } | |
| function randomRange(min, max) { | |
| return min (max - min) * Math.random(); | |
| } | |
| function clamp(x, min, max) { | |
| return x < min ? min : x > max ? max : x; | |
| } | |
| function sign(x) { | |
| return x < 0 ? -1 : 1; | |
| } | |
| Fragment = function (v0, v1, v2) { | |
| this.v0 = v0; | |
| this.v1 = v1; | |
| this.v2 = v2; | |
| this.computeBoundingBox(); | |
| this.computeCentroid(); | |
| this.createCanvas(); | |
| this.clip(); | |
| }; | |
| Fragment.prototype = { | |
| computeBoundingBox: function () { | |
| var xMin = Math.min(this.v0[0], this.v1[0], this.v2[0]), xMax = Math.max(this.v0[0], this.v1[0], this.v2[0]), yMin = Math.min(this.v0[1], this.v1[1], this.v2[1]), yMax = Math.max(this.v0[1], this.v1[1], this.v2[1]); | |
| this.box = { | |
| x: xMin, | |
| y: yMin, | |
| w: xMax - xMin, | |
| h: yMax - yMin | |
| }; | |
| }, | |
| computeCentroid: function () { | |
| var x = (this.v0[0] this.v1[0] this.v2[0]) / 3, y = (this.v0[1] this.v1[1] this.v2[1]) / 3; | |
| this.centroid = [ | |
| x, | |
| y | |
| ]; | |
| }, | |
| createCanvas: function () { | |
| this.canvas = document.createElement('canvas'); | |
| this.canvas.width = this.box.w; | |
| this.canvas.height = this.box.h; | |
| this.canvas.style.width = this.box.w 'px'; | |
| this.canvas.style.height = this.box.h 'px'; | |
| this.canvas.style.left = this.box.x 'px'; | |
| this.canvas.style.top = this.box.y 'px'; | |
| this.ctx = this.canvas.getContext('2d'); | |
| }, | |
| clip: function () { | |
| this.ctx.translate(-this.box.x, -this.box.y); | |
| this.ctx.beginPath(); | |
| this.ctx.moveTo(this.v0[0], this.v0[1]); | |
| this.ctx.lineTo(this.v1[0], this.v1[1]); | |
| this.ctx.lineTo(this.v2[0], this.v2[1]); | |
| this.ctx.closePath(); | |
| this.ctx.clip(); | |
| this.ctx.drawImage(image, 0, 0); | |
| } | |
| }; | |
| </script> |
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论