/* Magic UMD boilerplate Beginning */ /**/ (function (root, factory) { /**/ if (typeof define === 'function' && define.amd) { /**/ define([], factory); /**/ } else if (typeof module === 'object' && module.exports) { /**/ module.exports = factory(); /**/ module.exports.default = module.exports /**/ } else { /**/ root.smokemachine = root.SmokeMachine = factory(); /**/ } /**/ }(typeof self !== 'undefined' ? self : this, function () { var opacities = [0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,3,5,5,7,4,4,1,1,0,1,0,0,0,0,0,1,0,0,17,27,41,52,56,34,23,15,11,4,9,5,1,0,0,0,0,0,0,1,45,63,57,45,78,66,52,41,34,37,23,20,0,1,0,0,0,0,1,43,62,66,64,67,115,112,114,56,58,47,33,18,12,10,0,0,0,0,39,50,63,76,87,107,105,112,128,104,69,64,29,18,21,15,0,0,0,7,42,52,85,91,103,126,153,128,124,82,57,52,52,24,1,0,0,0,2,17,41,67,84,100,122,136,159,127,78,69,60,50,47,25,7,1,0,0,0,34,33,66,82,113,138,149,168,175,82,142,133,70,62,41,25,6,0,0,0,18,39,55,113,111,137,141,139,141,128,102,130,90,96,65,37,0,0,0,2,15,27,71,104,129,129,158,140,154,146,150,131,92,100,67,26,3,0,0,0,0,46,73,104,124,145,135,122,107,120,122,101,98,96,35,38,7,2,0,0,0,50,58,91,124,127,139,118,121,177,156,88,90,88,28,43,3,0,0,0,0,30,62,68,91,83,117,89,139,139,99,105,77,32,1,1,0,0,0,0,0,16,21,8,45,101,125,118,87,110,86,64,39,0,0,0,0,0,0,0,0,0,1,28,79,79,117,122,88,84,54,46,11,0,0,0,0,0,0,0,0,0,1,0,6,55,61,68,71,30,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,23,25,20,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,12,9,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,2,0,0,0,0,0,0,0,0] var smokeSpriteSize = 20 var polyfillAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; function floatInRange(start, end){ return start + Math.random()*(end - start) } function makeSmokeSprite(color){ color = color || [24, 46.8, 48.2] var smokeSprite = document.createElement('canvas'), ctx = smokeSprite.getContext('2d'), data = ctx.createImageData(smokeSpriteSize, smokeSpriteSize), d = data.data for(var i=0;i<d.length;i+=4){ d[i]=color[0] d[i+1]=color[1] d[i+2]=color[2] d[i+3]=opacities[i / 4] } smokeSprite.width = smokeSpriteSize smokeSprite.height = smokeSpriteSize ctx.putImageData(data,0,0) return smokeSprite } function createParticle(x,y,options){ options = options || {} var lifetime = options.lifetime || 4000 var particle = { x: x, y: y, vx: floatInRange(options.minVx || -4/100, options.maxVx || 4/100), startvy: floatInRange(options.minVy || -4/10, options.maxVy || -1/10), scale: floatInRange(options.minScale || 0, options.maxScale || 0.5), lifetime: floatInRange(options.minLifetime || 2000, options.maxLifetime || 8000), age: 0, } particle.finalScale = floatInRange( options.minScale || 25+particle.scale, options.maxScale || 30+particle.scale ) particle.vy = particle.startvy return particle } function updateParticle(particle, deltatime){ particle.x += particle.vx * deltatime particle.y += particle.vy * deltatime var frac = Math.sqrt(particle.age / particle.lifetime) particle.vy = (1-frac)*particle.startvy particle.age+=deltatime particle.scale=frac*particle.finalScale } function drawParticle(particle, smokeParticleImage, context){ context.globalAlpha = (1-Math.abs(1-2*particle.age/particle.lifetime))/8 var off = particle.scale*smokeSpriteSize/2 var xmin = particle.x - off var xmax = xmin + off*2 var ymin = particle.y - off var ymax = ymin + off*2 context.drawImage(smokeParticleImage, xmin, ymin, xmax-xmin, ymax-ymin) // console.log(smokeParticleImage, xmin, ymin, xmax-xmin, ymax-ymin) } return function SmokeMachine(context, color){ var smokeParticleImage = makeSmokeSprite(color), particles = [], preDrawCallback=function(){} function updateAndDrawParticles(deltatime){ context.clearRect(0, 0, context.canvas.width, context.canvas.height); particles.forEach(function(p){ updateParticle(p, deltatime) }) particles = particles.filter(function(p){ return p.age < p.lifetime }) preDrawCallback(deltatime, particles) particles.forEach(function(p){ drawParticle(p, smokeParticleImage, context) }) } var running = false, lastframe = performance.now() function frame(time){ if(!running) return var dt = time-lastframe lastframe = time; updateAndDrawParticles(dt) polyfillAnimFrame(frame) } function addParticles(x,y,numParticles,options){ numParticles = numParticles || 10 if(numParticles < 1) return Math.random() <= numParticles && particles.push(createParticle(x,y,options)); for (var i = 0; i < numParticles; i++) particles.push(createParticle(x,y,options)) } return { step: function step(dt){ dt = dt || 16 console.log(dt) updateAndDrawParticles(dt) }, start: function start(){ running = true lastframe = performance.now() polyfillAnimFrame(frame) }, setPreDrawCallback: function(f){ preDrawCallback = f }, stop: function stop(){ running = false }, addsmoke: addParticles, addSmoke: addParticles, } } /* Magic UMD Boilerplate Ending */ /**/ }))
<!DOCTYPE HTML> <title>dev</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- <link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet"> --> <style type="text/css"> html, body { position: absolute; margin: 0; 100%; overflow: hidden; height: 100%; } #hi { position: absolute; top: 40%; 100%; text-align: center; } #hi a { color: #fff; font-size: 80px; text-decoration: none; font-family: Lobster; } .noselect { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ } #gh { display: block; position: absolute; transform: rotate(45deg); top: -30px; right: -100px; transform-origin: top left; background: #38dea8; padding: 10px 40px; color: #fff; font-size: 18px; font-family: sans-serif; text-decoration: none; text-shadow: -1px -1px 0 #5aab00; box-shadow: 0 2px 10px #0000003d; } .twitter-follow-button { position: absolute !important; bottom: 10px; right: 10px; } </style> <!-- <a id="gh" href="https://github.com/bijection/smoke.js"> Fork Me on <b>Github</b> </a> --> <canvas id="canvas"></canvas> <div id='hi'> <a href="https://github.com/bijection/smoke.js" class='noselect'> 这是正文body123 这是正文body123 这是正文body123 </a> </div> <!-- <a href="https://twitter.com/biject?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @biject</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> --> <script src="smoke.js"></script> <script> setTimeout(function() { }, 8000 ); var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') var party = smokemachine(ctx, [128,128,128]) party.start() // start animating party.setPreDrawCallback(function(dt) { party.addSmoke(innerWidth /2, innerHeight/4*3, .5) canvas.width = innerWidth canvas.height = innerHeight }) party.addsmoke(innerWidth/2 , innerHeight/4*3, 0.5) setTimeout(function() { // canvas.width = innerWidth; // canvas.height = innerHeight-100; party.stop(); }, 8000 ); // onclick=e => { // console.log(e) // party.step() // } // for (var i = 0; i < 12; i++) { // var canvas = document.getElementById('canvas') // var ctx = canvas.getContext('2d') // setTimeout(function() { // canvas.width = innerWidth // canvas.height = innerHeight // var x1 = Math.floor(Math.random() * 20) // var y1 = Math.floor(Math.random() * 30) // var party = smokemachine(ctx, [18, 16, 54]) // party.start() // start animating // party.setPreDrawCallback(function(dt) { // // party.addSmoke(innerWidth / 2, innerHeight, .5) // canvas.width = innerWidth - x1 // canvas.height = innerHeight - y1 // }) // var x = Math.floor(Math.random() * 200) + Math.floor(Math.random() * 600) // var y = Math.floor(Math.random() * 200) + Math.floor(Math.random() * 100) // var n = .5 // var t = Math.floor(Math.random() * 200) + 3800 // // party = smokemachine(ctx, [1, 100, 200]) // // party.addsmoke(x, y, n, t) // // party.stop(); // // canvas=null; // }, 400) // } </script>