@disillusion171- #9 <style> #effect-canvas { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 999999; pointer-events: none; } </style> <canvas id="effect-canvas"></canvas> <script> (function() { const canvas = document.getElementById('effect-canvas'); const ctx = canvas.getContext('2d'); let width, height; // 存放对象的数组 let fallingConfetti = []; let explosionConfetti = []; // 颜色池 const colors = ['#FF3B30', '#FF9500', '#FFCC00', '#4CD964', '#5AC8FA', '#007AFF', '#5856D6', '#FF2D55']; function resize() { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; } window.addEventListener('resize', resize); resize(); // --- 1. 飘落的碎屑类 (背景) --- class FallingPiece { constructor() { this.reset(); this.y = Math.random() * -height; // 初始随机分布在上方 } reset() { this.x = Math.random() * width; this.y = -20; this.size = Math.random() * 8 + 5; this.speed = Math.random() * 2 + 0.5; // 速度慢一点 this.angle = Math.random() * 360; this.spin = Math.random() * 3 - 1.5; this.color = colors[Math.floor(Math.random() * colors.length)]; this.isCircle = Math.random() < 0.2; this.aspectRatio = Math.random() * 0.5 + 0.8; } update() { this.y += this.speed; this.x += Math.sin(this.y * 0.01) * 0.5; this.angle += this.spin; if (this.y > height + 20) this.reset(); } draw() { drawPiece(this.x, this.y, this.angle, this.size, this.color, this.isCircle, this.aspectRatio, 1); } } // --- 2. 炸开的碎屑类 (点击产生) --- class ExplosionPiece { constructor(x, y) { this.x = x; this.y = y; this.size = Math.random() * 8 + 5; this.angle = Math.random() * 360; this.spin = Math.random() * 10 - 5; // 炸开时旋转很快 this.color = colors[Math.floor(Math.random() * colors.length)]; this.isCircle = Math.random() < 0.2; this.aspectRatio = Math.random() * 0.5 + 0.8; // 物理属性 const velocity = Math.random() * 6 + 2; // 爆发力 const rad = Math.random() * Math.PI * 2; this.vx = Math.cos(rad) * velocity; this.vy = Math.sin(rad) * velocity; this.life = 1; // 透明度/生命值 this.decay = Math.random() * 0.02 + 0.01; // 消失速度 } update() { this.x += this.vx; this.y += this.vy; this.vy += 0.15; // 重力:碎屑会下坠 this.vx *= 0.94; // 空气阻力:水平速度衰减 this.vy *= 0.94; this.angle += this.spin; this.life -= this.decay; } draw() { drawPiece(this.x, this.y, this.angle, this.size, this.color, this.isCircle, this.aspectRatio, this.life); } } // --- 通用绘制函数 --- function drawPiece(x, y, angle, size, color, isCircle, aspectRatio, alpha) { ctx.save(); ctx.translate(x, y); ctx.rotate(angle * Math.PI / 180); ctx.globalAlpha = alpha; ctx.fillStyle = color; if (isCircle) { ctx.beginPath(); ctx.arc(0, 0, size / 2, 0, Math.PI * 2); ctx.fill(); } else { const w = size; const h = size * aspectRatio; ctx.fillRect(-w / 2, -h / 2, w, h); } ctx.restore(); } // --- 初始化设置 --- // 这里设置密度:手机 25片,电脑 60片 (比之前少了一半) const count = window.innerWidth < 600 ? 25 : 60; for (let i = 0; i < count; i++) { fallingConfetti.push(new FallingPiece()); } // --- 点击事件 --- document.addEventListener('pointerdown', function(e) { // 每次点击产生 16 个碎屑 for (let i = 0; i < 16; i++) { explosionConfetti.push(new ExplosionPiece(e.clientX, e.clientY)); } }); // --- 动画循环 --- function animate() { ctx.clearRect(0, 0, width, height); // 1. 背景飘落 fallingConfetti.forEach(p => { p.update(); p.draw(); }); // 2. 点击炸裂 (倒序循环以便删除) for (let i = explosionConfetti.length - 1; i >= 0; i--) { let p = explosionConfetti[i]; p.update(); p.draw(); if (p.life <= 0) { explosionConfetti.splice(i, 1); } } requestAnimationFrame(animate); } animate(); })(); </script>
当爱好吧,就和那些花大价钱摄影、钓鱼之类的人一样。只要花的钱让自己开心了就是值得的,尽管有时候买了也用不上。
@disillusion171- #9
<style>
#effect-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999999;
pointer-events: none;
}
</style>
<canvas id="effect-canvas"></canvas>
<script>
(function() {
const canvas = document.getElementById('effect-canvas');
const ctx = canvas.getContext('2d');
let width, height;
})();
</script>
@Pokemon #12 感谢大佬!
就是想要刚连上,跑完脚本,挂完探针的激动感。
就如同海王一样,玩了一次就会腻了
@Pokemon #1 为什么你这里面这么多AWS的
@poliste #16
吃灰
小鸡吃灰才是真正的MJJ
MJJ的探针页面 一个比一个炫酷
几十台跑车放着吃灰的大富豪啥心理?