Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
css
body, html { margin: 0; padding: 0; } canvas { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; } canvas div { background-color: transparent; } #scene { background-color: black; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
JavaScript
//****************************************************** // Yet Another Particle Engine var cos = Math.cos, sin = Math.sin, sqrt = Math.sqrt, abs = Math.abs, atan2 = Math.atan2, log = Math.log, random = Math.random, PI = Math.PI, sqr = function(v) { return v * v; }, particles = [], drawScale = 1, emitters = [], forces = [], collidedMass = 0, maxParticles = 100, emissionRate = 1; //------------------------------------------------------- // Vectors, and not the kind you put stuff in function Vector(x, y, z) { this.x = x || 0; this.y = y || 0; this.z = z || 0; } Vector.prototype = { add: function(vector) { this.x += vector.x; this.y += vector.y; this.z += vector.z; return this; }, subtract: function(vector) { this.x -= vector.x; this.y -= vector.y; this.z -= vector.z; return this; }, multiply: function(another) { this.x /= another.x; this.y /= another.y; this.z /= another.z; return this; }, divide: function(another) { this.x /= another.x; this.y /= another.y; this.z /= another.z; return this; }, scale: function(factor) { this.x *= factor; this.y *= factor; this.z *= factor; return this; }, magnitude: function() { return sqrt(sqr(this.x + this.y)); }, distance: function(another) { return abs(sqrt(sqr(this.x - another.x) + sqr(this.y - another.y))); }, angle: function(angle, magnitude) { if (angle && magnitude) return Vector.fromAngle(angle, magnitude); return atan2(this.y, this.x); }, clone: function() { return new Vector(this.x, this.y, this.z); }, equals: function(another) { return this.x === another.x && this.y === another.y && this.z === another.z; }, random: function(r) { this.x += (random() * r * 2) - r; this.y += (random() * r * 2) - r; return this; } }; Vector.fromAngle = function(angle, magnitude) { return new Vector( magnitude * cos(angle), magnitude * sin(angle), magnitude * sin(angle)); }; //****************************************************** // A thing with mass, position, and velocity - like your mom function Particle(pt, vc, ac, mass) { this.pos = pt || new Vector(0, 0); this.vc = vc || new Vector(0, 0); this.ac = ac || new Vector(0, 0); this.mass = mass || 1; this.alive = true; } Particle.prototype.move = function() { this.vc.add(this.ac); this.pos.add(this.vc); }; Particle.prototype.reactToForces = function(fields) { var totalAccelerationX = 0; var totalAccelerationY = 0; for (var i = 0; i < fields.length; i++) { var field = fields[i]; var vectorX = field.pos.x - this.pos.x; var vectorY = field.pos.y - this.pos.y; var distance = this.pos.distance(field.pos); if (distance < 1) field.grow(this); if (distance < 100) this.doubleSize = true; var force = G(this.forceBetween(field, distance)); totalAccelerationX += vectorX * force; totalAccelerationY += vectorY * force; } this.ac = new Vector(totalAccelerationX, totalAccelerationY); totalAccelerationX = 0; totalAccelerationY = 0; for (var i = 0; i < particles.length; i++) { var field = particles[i]; if (field === this || !field.alive) continue; var vectorX = field.pos.x - this.pos.x; var vectorY = field.pos.y - this.pos.y; var distance = this.pos.distance(field.pos); if (distance < 1) { if (this.mass >= field.mass) { var massRatio = this.mass / field.mass; if (particles.length <= maxParticles && this.mass > 40) { this.alive = false; this.nova = true; collidedMass += this.mass; } else this.grow(field); } else this.alive = false; } if (this.alive) { var force = G(this.forceBetween(field, distance)); totalAccelerationX += vectorX * G(force); totalAccelerationY += vectorY * G(force); } } var travelDist = this.pos.distance(this.lastPos ? this.lastPos : this.pos); this.velocity = travelDist - (this.lastDistance ? this.lastDistance : travelDist); this.lastDistance = travelDist; this.lastPos = this.pos.clone(); this.ac.add(new Vector(totalAccelerationX, totalAccelerationY)); this.lastPos = this.pos.clone(); // if(this.mass > 20) { // var chance = 1 / (this.mass - 20); // if(Math.random()>chance) { // this.supernova = true; // this.supernovaDur = 10; // this.alive = false; // if(particles.length <= maxParticles) collidedMass += this.mass; // delete this.size; // } // } }; Particle.prototype.grow = function(another) { this.mass += another.mass; this.nova = true; another.alive = false; delete this.size; }; Particle.prototype.breakApart = function(minMass, maxParts) { if (!minMass) minMass = 1; if (!maxParts) maxParts = 2; var remainingMass = this.mass; var num = 0; while (remainingMass > 0) { var np = new Particle(this.pos.clone().random(this.mass), new Vector(0, 0)); np.mass = 1 + Math.random() * (remainingMass - 1); if (num >= maxParts - 1) np.mass = remainingMass; np.mass = np.mass < minMass ? minMass : np.mass; remainingMass -= np.mass; num++; } this.nova = true; delete this.size; this.alive = false; }; Particle.prototype.forceBetween = function(another, distance) { var distance = distance ? distance : this.pos.distance(another.pos); return (this.mass * another.mass) / sqr(distance); }; //****************************************************** //This certainly doesn't *sub*mit to particles, that's for sure function ParticleEmitter(pos, vc, ang) { // to do config options for emitter - random, static, show emitter, emitter color, etc this.pos = pos; this.vc = vc; this.ang = ang || 0.09; this.color = "#999"; } ParticleEmitter.prototype.emit = function() { var angle = this.vc.angle() + this.ang - (Math.random() * this.ang * 2); var magnitude = this.vc.magnitude(); var position = this.pos.clone(); position.add( new Vector(~~((Math.random() * 100) - 50) * drawScale, ~~((Math.random() * 100) - 50) * drawScale)); var velocity = Vector.fromAngle(angle, magnitude); return new Particle(position, velocity); }; //****************************************************** // Use it, Luke // to do collapse functionality into particle function Force(pos, m) { this.pos = pos; this.mass = m || 100; } Force.prototype.grow = function(another) { this.mass += another.mass; this.burp = true; another.alive = false; }; function G(data) { return 0.00674 * data; } //****************************************************** var canvas = document.querySelector('#scene'); var ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var canvasWidth = canvas.width; var canvasHeight = canvas.height; var renderToCanvas = function(width, height, renderFunction) { var buffer = document.createElement('canvas'); buffer.width = width; buffer.height = height; renderFunction(buffer.getContext('2d')); return buffer; }; maxParticles = 500; emissionRate = 1; drawScale = 1.3; minParticleSize = 2; emitters = [ //br new ParticleEmitter( new Vector( canvasWidth / 2 * drawScale + 400, canvasHeight / 2 * drawScale ), Vector.fromAngle(2, 5), 1 ), // // bl // new ParticleEmitter( // new Vector( // canvasWidth / 2 * drawScale - 400, // canvasHeight / 2 * drawScale + 400 // ), // Vector.fromAngle(1.5, 1), // 1 // ), // tl new ParticleEmitter( new Vector( canvasWidth / 2 * drawScale - 400, canvasHeight / 2 * drawScale ), Vector.fromAngle(5, 5), 1 ), // // tr // new ParticleEmitter( // new Vector( // canvasWidth / 2 * drawScale + 400, // canvasHeight / 2 * drawScale - 400 // ), // Vector.fromAngle(4.5, 1), // 1 // ) ]; forces = [ new Force( new Vector((canvasWidth / 2 * drawScale), (canvasHeight / 2 * drawScale)), 1800) ]; function loop() { clear(); update(); draw(); queue(); } function clear() { ctx.clearRect(0, 0, canvas.width, canvas.height); } var ctr = 0; var c = [ 'rgba(255,255,255,', 'rgba(0,150,255,', 'rgba(255,255,128,', 'rgba(255,255,255,' ]; function rndc() { return c[~~(Math.random() * c.length - 1)]; } var c2 = 'rgba(255,64,32,'; function addNewParticles() { var _emit = function() { var ret = 0; for (var i = 0; i < emitters.length; i++) { for (var j = 0; j < emissionRate; j++) { var p = emitters[i].emit(); p.color = (ctr % 10 === 0) ? (Math.random() * 5 <= 1 ? c2 : rndc()) : rndc(); p.mass = ~~(Math.random() * 5); particles.push(p); ret += p.mass; ctr++; } } return ret; }; if (collidedMass !== 0) { while (collidedMass !== 0) { collidedMass -= _emit(); collidedMass = collidedMass < 0 ? 0 : collidedMass; } } if (particles.length > maxParticles) return; _emit(); } var CLIPOFFSCREEN = 1, BUFFEROFFSCREEN = 2, LOOPSCREEN = 3; function isPositionAliveAndAdjust(particle, check) { return true; var pos = particle.pos; if (!check) check = BUFFEROFFSCREEN; if (check === CLIPOFFSCREEN) { return !(!particle.alive || pos.x < 0 || (pos.x / drawScale) > boundsX || pos.y < 0 || (pos.y / drawScale) > boundsY); } else if (check === BUFFEROFFSCREEN) { return !(!particle.alive || pos.x < -boundsX * drawScale || pos.x > 2 * boundsX * drawScale || pos.y < -boundsY * drawScale || pos.y > 2 * boundsY * drawScale); } else if (check === LOOPSCREEN) { if (pos.x < 0) pos.x = boundsX * drawScale; if ((pos.x / drawScale) > boundsX) pos.x = 0; if (pos.y < 0) pos.y = boundsY * drawScale; if ((pos.y / drawScale) > boundsY) pos.y = 0; return true; } } function plotParticles(boundsX, boundsY) { var currentParticles = []; for (var i = 0; i < particles.length; i++) { var particle = particles[i]; particle.reactToForces(forces); if (!isPositionAliveAndAdjust(particle)) continue; particle.move(); currentParticles.push(particle); } } var offscreenCache = {}; function renderParticle(p) { var position = p.pos; if (!p.size) p.size = Math.floor(p.mass / 100); if (!p.opacity) p.opacity = 0.05; if (p.velocity > 0) { if (p.opacity <= 0.18) p.opacity += 0.04; } if (p.opacity > 0.08) p.opacity -= 0.02; var actualSize = p.size / drawScale; actualSize = actualSize < minParticleSize ? minParticleSize : actualSize; if (p.mass > 8) actualSize *= 2; if (p.nova) { actualSize *= 4; p.nova = false; } if (p.doubleSize) { p.doubleSize = false; actualSize *= 2; } // if(p.supernova) { // actualSize *= 6; // opacity = 0.15; // p.supernovaDur = p.supernovaDur - 1; // if(p.supernovaDur === 0) // p.supernova = false; // } var cacheKey = actualSize + '_' + p.opacity + '_' + p.color; var cacheValue = offscreenCache[cacheKey]; if (!cacheValue) { cacheValue = renderToCanvas(actualSize * 32, actualSize * 32, function(ofsContext) { var opacity = p.opacity; var fills = [{ size: actualSize / 2, opacity: 1 }, { size: actualSize, opacity: opacity }, { size: actualSize * 2, opacity: opacity / 2 }, { size: actualSize * 4, opacity: opacity / 3 }, { size: actualSize * 8, opacity: opacity / 5 }, { size: actualSize * 16, opacity: opacity / 16 }]; ofsContext.beginPath(); for (var f in fills) { f = fills[f]; ofsContext.fillStyle = p.color + f.opacity + ')'; ofsContext.arc( actualSize * 16, actualSize * 16, f.size, 0, Math.PI * 2, true); ofsContext.fill(); } ofsContext.closePath(); }); offscreenCache[cacheKey] = cacheValue; } var posX = p.pos.x / drawScale; var posY = p.pos.y / drawScale; ctx.drawImage(cacheValue, posX, posY); } var fills = [{ size: 15, opacity: 1 }, { size: 25, opacity: 0.3 }, { size: 50, opacity: 0.1 }]; function renderScene(ofsContext) { for (var i = 0; i < forces.length; i++) { var p = forces[i]; var position = p.pos; var opacity = 1; ofsContext.beginPath(); for (var f in fills) { f = fills[f]; var o = p.burp === true ? 1 : f.opacity; p.burp = false; // ofsContext.fillStyle = 'rgba(255,255,255,' + o + ')'; // ofsContext.arc(position.x / drawScale, // position.y / drawScale, // f.size / drawScale, 0, Math.PI*2, true); // ofsContext.fill(); } ofsContext.closePath(); } for (var i = 0; i < particles.length; i++) { var p = particles[i]; renderParticle(p); } } function draw() { renderScene(ctx); } function update() { addNewParticles(); plotParticles(canvas.width, canvas.height); } function queue() { window.requestAnimationFrame(loop); } $('canvas').mousedown(function(e) { }); $('canvas').mouseup(function(e) { }); loop();
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>粒子的星系-jq22.com</title> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style>
</style> </head> <body>
<script>
</script>
</body> </html>
2012-2021 jQuery插件库版权所有
jquery插件
|
jq22工具库
|
网页技术
|
广告合作
|
在线反馈
|
版权声明
沪ICP备13043785号-1
浙公网安备 33041102000314号