jQuery+HTML5實(shí)現(xiàn)WebGL高性能煙花綻放動(dòng)畫效果【附demo源碼下載】
本文實(shí)例講述了jQuery+HTML5實(shí)現(xiàn)WebGL高性能煙花綻放動(dòng)畫效果。分享給大家供大家參考,具體如下:
運(yùn)行效果:
完整代碼如下:
<!DOCTYPE html> <html class=" -webkit- js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths"> <head> <meta charset="UTF-8"> <meta name="viewport" content=" initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no"> <title>HTML5/WebGL高性能煙花綻放動(dòng)畫</title> <meta name="description" content="HTML5/WebGL高性能煙花綻放動(dòng)畫"> <meta name="keywords" content="HTML5/WebGL高性能煙花綻放動(dòng)畫"> <style> canvas { position: absolute; top: 0; left: 0; background-color: #111; } </style> </head> <body> <script src="jquery-1.11.1.min.js"></script> <canvas id="c" width="1440" height="304"></canvas><script src="prefixfree.min.js"></script><script src="modernizr.js"></script><script>var gl = c.getContext('webgl', { preserveDrawingBuffer: true }), w = c.width = window.innerWidth, h = c.height = window.innerHeight , webgl = {}, opts = { projectileAlpha: .8, projectileLineWidth: 1.3, fireworkAngleSpan: .5, baseFireworkVel: 3, addedFireworkVel: 3, gravity: .03, lowVelBoundary: -.2, xFriction: .995, baseShardVel: 1, addedShardVel: .2, fireworks: 1000, baseShardsParFirework: 10, addedShardsParFirework: 10, shardFireworkVelMultiplier: .3, initHueMultiplier: 1 / 360, runHueAdder: .1 / 360 } webgl.vertexShaderSource = ` uniform int u_mode; uniform vec2 u_res; attribute vec4 a_data; varying vec4 v_color; vec3 h2rgb( float h ){ return clamp( abs( mod( h * 6. + vec3( 0, 4, 2 ), 6. ) - 3. ) -1., 0., 1. ); } void clear(){ gl_Position = vec4( a_data.xy, 0, 1 ); v_color = vec4( 0, 0, 0, a_data.w ); } void draw(){ gl_Position = vec4( vec2( 1, -1 ) * ( ( a_data.xy / u_res ) * 2. - 1. ), 0, 1 ); v_color = vec4( h2rgb( a_data.z ), a_data.w ); } void main(){ if( u_mode == 0 ) draw(); else clear(); } `; webgl.fragmentShaderSource = ` precision mediump float; varying vec4 v_color; void main(){ gl_FragColor = v_color; } `; webgl.vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(webgl.vertexShader, webgl.vertexShaderSource); gl.compileShader(webgl.vertexShader); webgl.fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(webgl.fragmentShader, webgl.fragmentShaderSource); gl.compileShader(webgl.fragmentShader); webgl.shaderProgram = gl.createProgram(); gl.attachShader(webgl.shaderProgram, webgl.vertexShader); gl.attachShader(webgl.shaderProgram, webgl.fragmentShader); gl.linkProgram(webgl.shaderProgram); gl.useProgram(webgl.shaderProgram); webgl.dataAttribLoc = gl.getAttribLocation(webgl.shaderProgram, 'a_data'); webgl.dataBuffer = gl.createBuffer(); gl.enableVertexAttribArray(webgl.dataAttribLoc); gl.bindBuffer(gl.ARRAY_BUFFER, webgl.dataBuffer); gl.vertexAttribPointer(webgl.dataAttribLoc, 4, gl.FLOAT, false, 0, 0); webgl.resUniformLoc = gl.getUniformLocation(webgl.shaderProgram, 'u_res'); webgl.modeUniformLoc = gl.getUniformLocation(webgl.shaderProgram, 'u_mode'); gl.viewport(0, 0, w, h); gl.uniform2f(webgl.resUniformLoc, w, h); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.BLEND); gl.lineWidth(opts.projectileLineWidth); webgl.data = []; webgl.clear = function() { gl.uniform1i(webgl.modeUniformLoc, 1); var a = .1; webgl.data = [-1, -1, 0, a, 1, -1, 0, a, -1, 1, 0, a, -1, 1, 0, a, 1, -1, 0, a, 1, 1, 0, a ]; webgl.draw(gl.TRIANGLES); gl.uniform1i(webgl.modeUniformLoc, 0); webgl.data.length = 0; } webgl.draw = function(glType) { gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(webgl.data), gl.STATIC_DRAW); gl.drawArrays(glType, 0, webgl.data.length / 4); } var fireworks = [], tick = 0, sins = [], coss = [], maxShardsParFirework = opts.baseShardsParFirework + opts.addedShardsParFirework, tau = 6.283185307179586476925286766559; for (var i = 0; i < maxShardsParFirework; ++i) { sins[i] = Math.sin(tau * i / maxShardsParFirework); coss[i] = Math.cos(tau * i / maxShardsParFirework); } function Firework() { this.reset(); this.shards = []; for (var i = 0; i < maxShardsParFirework; ++i) this.shards.push(new Shard(this)); } Firework.prototype.reset = function() { var angle = -Math.PI / 2 + (Math.random() - .5) * opts.fireworkAngleSpan, vel = opts.baseFireworkVel + opts.addedFireworkVel * Math.random(); this.mode = 0; this.vx = vel * Math.cos(angle); this.vy = vel * Math.sin(angle); this.x = Math.random() * w; this.y = h; this.hue = tick * opts.initHueMultiplier; } Firework.prototype.step = function() { if (this.mode === 0) { var ph = this.hue, px = this.x, py = this.y; this.hue += opts.runHueAdder; this.x += this.vx *= opts.xFriction; this.y += this.vy += opts.gravity; webgl.data.push( px, py, ph, opts.projectileAlpha * .2, this.x, this.y, this.hue, opts.projectileAlpha * .2); if (this.vy >= opts.lowVelBoundary) { this.mode = 1; this.shardAmount = opts.baseShardsParFirework + opts.addedShardsParFirework * Math.random() | 0; var baseAngle = Math.random() * tau, x = Math.cos(baseAngle), y = Math.sin(baseAngle), sin = sins[this.shardAmount], cos = coss[this.shardAmount]; for (var i = 0; i < this.shardAmount; ++i) { var vel = opts.baseShardVel + opts.addedShardVel * Math.random(); this.shards[i].reset(x * vel, y * vel) var X = x; x = x * cos - y * sin; y = y * cos + X * sin; } } } else if (this.mode === 1) { this.ph = this.hue this.hue += opts.runHueAdder; var allDead = true; for (var i = 0; i < this.shardAmount; ++i) { var shard = this.shards[i]; if (!shard.dead) { shard.step(); allDead = false; } } if (allDead) this.reset(); } } function Shard(parent) { this.parent = parent; } Shard.prototype.reset = function(vx, vy) { this.x = this.parent.x; this.y = this.parent.y; this.vx = this.parent.vx * opts.shardFireworkVelMultiplier + vx; this.vy = this.parent.vy * opts.shardFireworkVelMultiplier + vy; this.starty = this.y; this.dead = false; this.tick = 1; } Shard.prototype.step = function() { this.tick += .05; var px = this.x, py = this.y; this.x += this.vx *= opts.xFriction; this.y += this.vy += opts.gravity; var proportion = 1 - (this.y - this.starty) / (h - this.starty); webgl.data.push( px, py, this.parent.ph, opts.projectileAlpha / this.tick, this.x, this.y, this.parent.hue, opts.projectileAlpha / this.tick); if (this.y > h) this.dead = true; } function anim() { window.requestAnimationFrame(anim) webgl.clear(); ++tick; if (fireworks.length < opts.fireworks) fireworks.push(new Firework); fireworks.map(function(firework) { firework.step(); }); webgl.draw(gl.LINES); } anim(); window.addEventListener('resize', function() { w = c.width = window.innerWidth; h = c.height = window.innerHeight; gl.viewport(0, 0, w, h); gl.uniform2f(webgl.resUniformLoc, w, h); }) window.addEventListener('click', function(e) { var firework = new Firework(); firework.x = e.clientX; firework.y = e.clientY; firework.vx = 0; firework.vy = 0; fireworks.push(firework); }); </script> </body> </html>
附:完整實(shí)例代碼點(diǎn)擊此處本站下載。
更多關(guān)于jQuery相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《jQuery常用插件及用法總結(jié)》、《jQuery擴(kuò)展技巧總結(jié)》、《jQuery拖拽特效與技巧總結(jié)》、《jQuery常見經(jīng)典特效匯總》、《jQuery動(dòng)畫與特效用法總結(jié)》及《jquery選擇器用法總結(jié)》
希望本文所述對(duì)大家jQuery程序設(shè)計(jì)有所幫助。
相關(guān)文章
jquery實(shí)現(xiàn)勾選復(fù)選框觸發(fā)事件給input賦值
本文給大家介紹的是一段十分實(shí)用的代碼,使用jQuery實(shí)現(xiàn)勾選復(fù)選框觸發(fā)事件給input賦值,在制作項(xiàng)目的時(shí)候經(jīng)常需要用到此功能,這里分享給大家。2015-02-02jquery通過(guò)a標(biāo)簽刪除table中的一行的代碼
刪除table中的一行的方法有很多,在本文為大家介紹下jquery是如何做到的,下面有個(gè)不錯(cuò)的示例,喜歡的朋友可以參考下2013-12-12EasyUI中combobox默認(rèn)值注意事項(xiàng)
這篇文章主要介紹了EasyUI中combobox默認(rèn)值注意事項(xiàng),是個(gè)人在項(xiàng)目中遇到并解決的事宜,分享給大家,需要的朋友可以參考下2015-03-03原生js和jquery實(shí)現(xiàn)圖片輪播特效
本文給大家分享的是使用原生JS和JQ兩種方法分別實(shí)現(xiàn)相同的圖片輪播特效,十分的實(shí)用,也非常方便大家對(duì)比學(xué)習(xí)原生js和jQuery,有需要的小伙伴可以參考下。2015-04-04