DeepSeek-V4-Pro 对比 Gpt-5.4 烟花问题
- 内容介绍
- 文章标签
- 相关推荐
这是DeepSeek V4 Pro的
我要js,给了我一个html
443e69ad137f6a39866×734 42.1 KB
(function() {
// --- 创建全屏 Canvas ---
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const W = window.innerWidth;
const H = window.innerHeight;
canvas.width = W;
canvas.height = H;
canvas.style.cssText = `
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
z-index: 2147483647;
pointer-events: none;
background: transparent;
`;
document.body.appendChild(canvas);
// --- 全局状态 ---
const particles = []; // 所有粒子
const rockets = []; // 飞行中的火箭
const flashes = []; // 爆炸闪光
let lastTime = performance.now();
let allFireworksLaunched = false;
let launchIndex = 0;
let cleanupTimer = null;
// --- 绚丽的颜色主题 ---
const colorThemes = [
{ hue: 5, name: '经典红' }, // 正红
{ hue: 30, name: '金橙' }, // 金橙色
{ hue: 50, name: '璀璨金' }, // 金色
{ hue: 330, name: '玫红' }, // 玫红
{ hue: 280, name: '紫罗兰' }, // 紫色
{ hue: 180, name: '青蓝' }, // 青色
{ hue: 15, name: '橘红' }, // 橘红
{ hue: 340, name: '粉红' }, // 粉红
{ hue: 45, name: '琥珀金' }, // 琥珀金
{ hue: 260, name: '薰衣草紫' }, // 薰衣草紫
{ hue: 200, name: '天蓝' }, // 天蓝色
{ hue: 355, name: '深红' }, // 深红
];
// --- 工具函数:HSL 转 CSS 颜色字符串 ---
function hslToColor(h, s, l, a = 1) {
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
}
// --- 创建爆炸粒子 ---
function createExplosion(x, y, themeHue, particleCount = 120) {
// 闪光效果
flashes.push({
x,
y,
radius: 0,
maxRadius: 60 + Math.random() * 40,
life: 1.0,
decay: 4.5 + Math.random() * 3,
});
// 爆炸粒子
for (let i = 0; i < particleCount; i++) {
const angle = (Math.PI * 2 * i) / particleCount;
// 添加随机偏移让爆炸更自然
const angleOffset = (Math.random() - 0.5) * 0.25;
const finalAngle = angle + angleOffset;
const speed = 280 + Math.random() * 520; // 像素/秒
const speedVariation = 1 + (Math.random() - 0.5) * 0.6;
const vx = Math.cos(finalAngle) * speed * speedVariation;
const vy = Math.sin(finalAngle) * speed * speedVariation;
// 粒子颜色在主题色周围变化
const hueShift = (Math.random() - 0.5) * 40;
const h = (themeHue + hueShift + 360) % 360;
const s = 75 + Math.random() * 25;
const l = 50 + Math.random() * 30;
particles.push({
x,
y,
vx,
vy,
life: 1.0,
maxLife: 1.4 + Math.random() * 1.6, // 秒
color: hslToColor(h, s, l, 1),
size: 1.8 + Math.random() * 3.5,
type: 'spark',
gravity: 160 + Math.random() * 80, // 重力加速度 px/s²
friction: 0.3 + Math.random() * 0.5,
twinkle: Math.random() < 0.25, // 25%的粒子会闪烁
twinkleSpeed: 8 + Math.random() * 25,
});
}
// 额外添加一些"金色雨"慢速粒子
const glitterCount = Math.floor(particleCount * 0.3);
for (let i = 0; i < glitterCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = 60 + Math.random() * 180;
const vx = Math.cos(angle) * speed;
const vy = Math.sin(angle) * speed - 40;
const h = 40 + Math.random() * 25; // 金色范围
const s = 80 + Math.random() * 20;
const l = 55 + Math.random() * 35;
particles.push({
x,
y,
vx,
vy,
life: 1.0,
maxLife: 2.0 + Math.random() * 2.5, // 金色雨持续更久
color: hslToColor(h, s, l, 1),
size: 1.2 + Math.random() * 2.2,
type: 'glitter',
gravity: 60 + Math.random() * 50,
friction: 0.6 + Math.random() * 0.35,
twinkle: true,
twinkleSpeed: 12 + Math.random() * 20,
});
}
}
// --- 创建火箭尾焰粒子 ---
function createTrailParticle(x, y, themeHue) {
const h = 25 + Math.random() * 35; // 尾焰偏橙黄
particles.push({
x: x + (Math.random() - 0.5) * 8,
y: y + (Math.random() - 0.5) * 6,
vx: (Math.random() - 0.5) * 30,
vy: 30 + Math.random() * 60,
life: 1.0,
maxLife: 0.3 + Math.random() * 0.5,
color: hslToColor(h, 90, 55 + Math.random() * 30, 1),
size: 1.5 + Math.random() * 3,
type: 'trail',
gravity: 20,
friction: 0.8,
twinkle: false,
twinkleSpeed: 0,
});
}
// --- 发射烟花 ---
function launchFirework(themeHue, delayMs = 0) {
const startX = W * 0.15 + Math.random() * W * 0.7;
const startY = H + 20;
const targetY = H * 0.18 + Math.random() * H * 0.45;
const targetX = startX + (Math.random() - 0.5) * W * 0.35;
const dx = targetX - startX;
const dy = targetY - startY;
const distance = Math.sqrt(dx * dx + dy * dy);
const flightTime = 0.7 + Math.random() * 0.6; // 飞行时间(秒)
const speed = distance / flightTime;
const vx = (dx / distance) * speed;
const vy = (dy / distance) * speed;
const rocket = {
x: startX,
y: startY,
vx,
vy,
targetY,
targetX,
themeHue,
alive: true,
trailTimer: 0,
trailInterval: 0.015, // 每0.015秒产生一个尾焰粒子
};
if (delayMs > 0) {
// 延迟发射
rocket.delayed = true;
rocket.launchAt = performance.now() + delayMs;
rocket.x = startX;
rocket.y = startY;
// 在延迟期间不更新位置
rocket._vx = vx;
rocket._vy = vy;
rocket.vx = 0;
rocket.vy = 0;
}
rockets.push(rocket);
}
// --- 发射计划:分波次发射 ---
function scheduleFireworks() {
const now = performance.now();
const schedule = [
// [延迟ms, 主题索引]
[0, 0],
[80, 5],
[200, 2],
[350, 8],
[500, 3],
[600, 10],
[750, 1],
[900, 7],
[1050, 4],
[1150, 11],
[1300, 6],
[1450, 9],
[1600, 0],
[1700, 2],
[1850, 5],
[2000, 3],
[2150, 8],
[2300, 1],
[2500, 10],
[2650, 7],
[2800, 4],
[3000, 11],
[3200, 0],
[3350, 6],
[3500, 2],
];
schedule.forEach(([delay, themeIdx]) => {
const theme = colorThemes[themeIdx % colorThemes.length];
launchFirework(theme.hue, delay);
});
// 设置全部发射完毕标志(在最后一个发射后)
const maxDelay = schedule[schedule.length - 1][0] + 2000;
setTimeout(() => {
allFireworksLaunched = true;
}, maxDelay);
}
// --- 更新粒子 ---
function updateParticles(dt) {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.life -= dt / p.maxLife;
if (p.life <= 0) {
particles.splice(i, 1);
continue;
}
// 物理更新
p.vy += p.gravity * dt;
p.vx *= (1 - p.friction * dt * 3);
p.vy *= (1 - p.friction * dt * 3);
p.x += p.vx * dt;
p.y += p.vy * dt;
}
}
// --- 更新火箭 ---
function updateRockets(dt, now) {
for (let i = rockets.length - 1; i >= 0; i--) {
const r = rockets[i];
// 处理延迟发射
if (r.delayed) {
if (now >= r.launchAt) {
r.delayed = false;
r.vx = r._vx;
r.vy = r._vy;
r._vx = undefined;
r._vy = undefined;
} else {
continue; // 还在等待发射
}
}
// 更新位置
r.x += r.vx * dt;
r.y += r.vy * dt;
// 产生尾焰
r.trailTimer += dt;
while (r.trailTimer >= r.trailInterval) {
r.trailTimer -= r.trailInterval;
createTrailParticle(r.x, r.y, r.themeHue);
}
// 检查是否到达目标高度
if (r.y <= r.targetY || r.y <= H * 0.08) {
// 爆炸!
createExplosion(r.x, r.y, r.themeHue, 100 + Math.floor(Math.random() * 80));
rockets.splice(i, 1);
}
// 安全检查:如果火箭飞出屏幕
if (r.y < -200 || r.x < -200 || r.x > W + 200) {
rockets.splice(i, 1);
}
}
}
// --- 更新闪光 ---
function updateFlashes(dt) {
for (let i = flashes.length - 1; i >= 0; i--) {
const f = flashes[i];
f.life -= f.decay * dt;
f.radius += (f.maxRadius - f.radius) * 6 * dt;
if (f.life <= 0) {
flashes.splice(i, 1);
}
}
}
// --- 渲染 ---
function render() {
ctx.clearRect(0, 0, W, H);
// 使用 additive 混合让烟花更绚丽
ctx.globalCompositeOperation = 'lighter';
// 绘制闪光
flashes.forEach(f => {
const alpha = f.life;
const gradient = ctx.createRadialGradient(f.x, f.y, 0, f.x, f.y, f.radius);
gradient.addColorStop(0, `rgba(255,255,240,${alpha * 0.9})`);
gradient.addColorStop(0.3, `rgba(255,240,200,${alpha * 0.5})`);
gradient.addColorStop(0.7, `rgba(255,180,100,${alpha * 0.15})`);
gradient.addColorStop(1, `rgba(255,150,50,0)`);
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(f.x, f.y, f.radius, 0, Math.PI * 2);
ctx.fill();
});
// 绘制粒子
particles.forEach(p => {
const alpha = p.life;
let size = p.size * (0.4 + 0.6 * p.life);
// 闪烁粒子
if (p.twinkle) {
const twinkleFactor = 0.5 + 0.5 * Math.sin(p.life * p.twinkleSpeed * Math.PI * 2);
size *= (0.6 + 0.4 * twinkleFactor);
}
if (size < 0.3) return;
// 光晕
const glowRadius = size * 3;
const gradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, glowRadius);
const baseColor = p.color.replace(/[\d.]+\)$/, '');
gradient.addColorStop(0, p.color.replace(/[\d.]+\)$/, `${Math.min(1, alpha)})`));
gradient.addColorStop(0.35, baseColor + `${alpha * 0.55})`);
gradient.addColorStop(0.7, baseColor + `${alpha * 0.1})`);
gradient.addColorStop(1, baseColor + '0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(p.x, p.y, glowRadius, 0, Math.PI * 2);
ctx.fill();
// 核心亮点
ctx.fillStyle = `rgba(255,255,255,${alpha * 0.8})`;
ctx.beginPath();
ctx.arc(p.x, p.y, size * 0.5, 0, Math.PI * 2);
ctx.fill();
});
// 绘制火箭(小亮点)
ctx.globalCompositeOperation = 'lighter';
rockets.forEach(r => {
if (r.delayed) return;
const gradient = ctx.createRadialGradient(r.x, r.y, 0, r.x, r.y, 8);
gradient.addColorStop(0, 'rgba(255,255,240,0.95)');
gradient.addColorStop(0.4, 'rgba(255,200,100,0.6)');
gradient.addColorStop(1, 'rgba(255,100,30,0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(r.x, r.y, 8, 0, Math.PI * 2);
ctx.fill();
});
// 恢复默认混合模式
ctx.globalCompositeOperation = 'source-over';
}
// --- 检查是否应该清理 ---
function shouldCleanup() {
return allFireworksLaunched &&
rockets.length === 0 &&
particles.length === 0 &&
flashes.length === 0;
}
// --- 执行清理 ---
function cleanup() {
if (canvas.parentNode) {
// 淡出效果
canvas.style.transition = 'opacity 0.8s ease-out';
canvas.style.opacity = '0';
setTimeout(() => {
if (canvas.parentNode) {
canvas.parentNode.removeChild(canvas);
}
}, 800);
}
}
// --- 主循环 ---
function mainLoop(timestamp) {
let dt = (timestamp - lastTime) / 1000; // 转换为秒
lastTime = timestamp;
// 防止大的时间跳跃(如标签页切换)
if (dt > 0.2) dt = 0.2;
if (dt <= 0) dt = 0.016;
const now = performance.now();
updateRockets(dt, now);
updateParticles(dt);
updateFlashes(dt);
render();
if (shouldCleanup()) {
if (!cleanupTimer) {
cleanupTimer = setTimeout(cleanup, 400);
}
}
if (!cleanupTimer || particles.length > 0 || rockets.length > 0 || flashes.length > 0) {
requestAnimationFrame(mainLoop);
} else if (cleanupTimer && particles.length === 0 && rockets.length === 0 && flashes.length ===
0) {
// 已经触发清理,不再请求新帧
// 但再检查一次以防万一
if (!canvas.parentNode) return;
// 如果清理还没执行,继续循环
if (canvas.style.opacity !== '0') {
requestAnimationFrame(mainLoop);
}
}
}
// --- 启动 ---
scheduleFireworks();
lastTime = performance.now();
requestAnimationFrame(mainLoop);
// --- 安全超时:15秒后强制清理 ---
setTimeout(() => {
if (canvas.parentNode && !cleanupTimer) {
allFireworksLaunched = true;
// 快速衰减所有粒子
particles.forEach(p => { p.maxLife *= 0.3;
p.life = Math.min(p.life, 0.3); });
rockets.length = 0;
cleanupTimer = setTimeout(cleanup, 600);
if (!cleanupTimer._set) {
// 确保清理最终执行
setTimeout(cleanup, 2000);
}
}
}, 15000);
console.log('🎆 礼花绽放!欣赏表演吧~(约6-8秒)');
})();
这是Gpt-5.4的(没开思考)
image831×653 36.9 KB
(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
Object.assign(canvas.style, {
position: 'fixed',
left: '0',
top: '0',
width: '100vw',
height: '100vh',
pointerEvents: 'none',
zIndex: '999999'
});
let w = canvas.width = window.innerWidth;
let h = canvas.height = window.innerHeight;
const particles = [];
const colors = ['#ff4d4d', '#ffd24d', '#4dff88', '#4db8ff', '#b84dff', '#ffffff', '#ff7fd1'];
window.addEventListener('resize', () => {
w = canvas.width = window.innerWidth;
h = canvas.height = window.innerHeight;
});
function createFirework(x, y) {
const count = 80 + Math.random() * 40;
for (let i = 0; i < count; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 6 + 2;
particles.push({
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: 60 + Math.random() * 30,
maxLife: 90,
color: colors[Math.floor(Math.random() * colors.length)],
size: Math.random() * 3 + 1
});
}
}
function animate() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.18)';
ctx.fillRect(0, 0, w, h);
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += 0.05;
p.vx *= 0.99;
p.vy *= 0.99;
p.life--;
const alpha = Math.max(p.life / p.maxLife, 0);
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fillStyle = hexToRgba(p.color, alpha);
ctx.fill();
if (p.life <= 0) particles.splice(i, 1);
}
if (particles.length > 0 || running) {
requestAnimationFrame(animate);
} else {
setTimeout(() => canvas.remove(), 500);
}
}
function hexToRgba(hex, alpha) {
const c = hex.replace('#', '');
const bigint = parseInt(c, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return `rgba(${r},${g},${b},${alpha})`;
}
let running = true;
let times = 0;
const timer = setInterval(() => {
createFirework(
Math.random() * w * 0.8 + w * 0.1,
Math.random() * h * 0.5 + h * 0.1
);
times++;
if (times >= 10) {
clearInterval(timer);
running = false;
}
}, 500);
ctx.fillStyle = 'rgba(0,0,0,1)';
ctx.fillRect(0, 0, w, h);
animate();
})();
个人总结:deepseek思考时间长,效果不如gpt5.4
网友解答:--【壹】--:
你看看我刚刚发的glm5.1的,感觉比gpt优秀,也是透明的
--【贰】--:
对比一下GLM5.1
个人认为gpt5.4旗鼓相当,甚至更优秀
(function () {
/* ========== 创建画布 ========== */
const C = document.createElement('canvas');
C.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2147483647;pointer-events:none;';
document.body.appendChild(C);
const ctx = C.getContext('2d');
let W, H;
const resize = () => { W = C.width = innerWidth; H = C.height = innerHeight; };
resize();
addEventListener('resize', resize);
/* ========== 工具函数 ========== */
const rand = (a, b) => Math.random() * (b - a) + a;
const pick = arr => arr[Math.floor(rand(0, arr.length))];
/* ========== 调色板(避免蓝紫系) ========== */
const palettes = [
['#FF6B6B', '#FFE66D', '#FF8E53'], // 暖阳
['#00F5A0', '#00D9F5', '#00FFC6'], // 翡翠
['#FF3CAC', '#FFE66D', '#FF8E53'], // 玫瑰金
['#FF4500', '#FFD700', '#FF6347'], // 烈焰
['#00FF88', '#FFD700', '#FF6B6B'], // 圣诞
['#FF1493', '#FF69B4', '#FFD700'], // 霓虹粉
['#7FFF00', '#00FA9A', '#ADFF2F'], // 荧光绿
['#FF6B35', '#F7C59F', '#FFE66D'], // 沙漠落日
];
/* ========== 粒子 ========== */
class Particle {
constructor(x, y, vx, vy, color, size, life) {
this.x = x; this.y = y; this.vx = vx; this.vy = vy;
this.color = color; this.size = size;
this.life = this.maxLife = life;
this.trail = [];
this.flicker = Math.random() > 0.5;
}
update() {
this.trail.push({ x: this.x, y: this.y });
if (this.trail.length > 7) this.trail.shift();
this.vx *= 0.975; this.vy *= 0.975;
this.vy += 0.045;
this.x += this.vx; this.y += this.vy;
this.life--;
}
draw() {
const alpha = Math.max(0, this.life / this.maxLife);
// 拖尾
for (let i = 0; i < this.trail.length; i++) {
const t = this.trail[i], r = i / this.trail.length;
ctx.globalAlpha = alpha * r * 0.35;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(t.x, t.y, Math.max(0.3, this.size * r * 0.55), 0, Math.PI * 2);
ctx.fill();
}
// 本体
const a = this.flicker ? alpha * (0.6 + 0.4 * Math.sin(this.life * 0.6)) : alpha;
ctx.globalAlpha = a;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, Math.max(0.3, this.size * alpha), 0, Math.PI * 2);
ctx.fill();
// 发光
ctx.globalAlpha = a * 0.18;
ctx.beginPath();
ctx.arc(this.x, this.y, Math.max(0.3, this.size * alpha * 4), 0, Math.PI * 2);
ctx.fill();
}
get dead() { return this.life <= 0; }
}
/* ========== 礼花 ========== */
class Firework {
constructor(sx, tx, ty, palette) {
this.x = sx; this.y = H;
this.tx = tx; this.ty = ty;
this.palette = palette;
const angle = Math.atan2(ty - H, tx - sx);
const speed = rand(11, 15);
this.vx = Math.cos(angle) * speed;
this.vy = Math.sin(angle) * speed;
this.exploded = false;
this.particles = [];
this.trail = [];
}
update() {
if (!this.exploded) {
this.trail.push({ x: this.x + rand(-1, 1), y: this.y, a: 1 });
if (this.trail.length > 22) this.trail.shift();
this.x += this.vx; this.y += this.vy;
this.vy += 0.13;
if (Math.hypot(this.x - this.tx, this.y - this.ty) < 25 || this.vy > 0) {
this.explode();
}
}
for (let i = this.trail.length - 1; i >= 0; i--) {
this.trail[i].a -= 0.04;
if (this.trail[i].a <= 0) this.trail.splice(i, 1);
}
for (let i = this.particles.length - 1; i >= 0; i--) {
this.particles[i].update();
if (this.particles[i].dead) this.particles.splice(i, 1);
}
}
explode() {
this.exploded = true;
const n = rand(90, 170) | 0;
const type = rand(0, 5) | 0;
for (let i = 0; i < n; i++) {
const angle = Math.PI * 2 / n * i + rand(-0.08, 0.08);
let speed;
const color = pick(this.palette);
if (type === 0) speed = rand(2, 8); // 球形
else if (type === 1) speed = i % 2 ? rand(3, 5) : rand(7, 10); // 双环
else if (type === 2) speed = rand(1, 11); // 满天星
else if (type === 3) speed = rand(3, 7) * Math.pow(rand(0.4, 1), 2); // 浓缩
else speed = 4 + 4 * Math.abs(Math.sin(angle * 3)); // 花朵
this.particles.push(new Particle(
this.x, this.y,
Math.cos(angle) * speed, Math.sin(angle) * speed,
color, rand(1.5, 3.2), rand(50, 95) | 0
));
}
// 白色中心闪光
for (let i = 0; i < 10; i++) {
const a = rand(0, Math.PI * 2);
this.particles.push(new Particle(
this.x, this.y,
Math.cos(a) * rand(0.5, 2.5), Math.sin(a) * rand(0.5, 2.5),
'#FFFFFF', rand(3, 5.5), rand(8, 18) | 0
));
}
// 余烬火花
for (let i = 0; i < 20; i++) {
const a = rand(0, Math.PI * 2);
const s = rand(0.3, 1.5);
this.particles.push(new Particle(
this.x, this.y,
Math.cos(a) * s, Math.sin(a) * s,
'#FFD700', rand(0.8, 1.5), rand(70, 130) | 0
));
}
}
draw() {
if (!this.exploded) {
for (let i = 0; i < this.trail.length; i++) {
const t = this.trail[i], r = i / this.trail.length;
ctx.globalAlpha = t.a * r;
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(t.x, t.y, Math.max(0.3, 2 * r), 0, Math.PI * 2);
ctx.fill();
}
ctx.globalAlpha = 1;
ctx.fillStyle = '#FFF';
ctx.beginPath(); ctx.arc(this.x, this.y, 2.5, 0, Math.PI * 2); ctx.fill();
ctx.globalAlpha = 0.5;
ctx.beginPath(); ctx.arc(this.x, this.y, 7, 0, Math.PI * 2); ctx.fill();
}
for (const p of this.particles) p.draw();
ctx.globalAlpha = 1;
}
get done() { return this.exploded && this.particles.length === 0 && this.trail.length === 0; }
}
/* ========== 发射控制 ========== */
const fireworks = [];
const launch = (x) => {
const sx = x ?? rand(W * 0.15, W * 0.85);
fireworks.push(new Firework(sx, sx + rand(-60, 60), rand(H * 0.08, H * 0.35), pick(palettes)));
};
// 开场连发
for (let i = 0; i < 7; i++) setTimeout(() => launch(), i * 220);
// 点击页面任意位置额外发射
const onClick = (e) => { for (let i = 0; i < 2; i++) setTimeout(() => launch(e.clientX + rand(-40, 40)), i * 100); };
document.addEventListener('click', onClick);
/* ========== 主循环 ========== */
let frame = 0, animId;
const loop = () => {
// 用 destination-out 在透明画布上实现淡出拖尾
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0,0,0,0.14)';
ctx.fillRect(0, 0, W, H);
ctx.globalCompositeOperation = 'source-over';
frame++;
if (frame % 38 === 0) launch();
if (frame % 110 === 0) {
const n = rand(2, 5) | 0;
for (let i = 0; i < n; i++) setTimeout(() => launch(), i * 130);
}
for (let i = fireworks.length - 1; i >= 0; i--) {
fireworks[i].update();
fireworks[i].draw();
if (fireworks[i].done) fireworks.splice(i, 1);
}
animId = requestAnimationFrame(loop);
};
loop();
/* ========== 12秒后自动收尾 ========== */
setTimeout(() => {
cancelAnimationFrame(animId);
document.removeEventListener('click', onClick);
C.style.transition = 'opacity 1.5s ease-out';
C.style.opacity = '0';
setTimeout(() => C.remove(), 1600);
}, 12000);
console.log('%c🎆 礼花绽放中!点击页面可追加发射,12秒后自动结束', 'color:#FFD700;font-size:15px;font-weight:bold;');
})();
--【叁】--:
测试过了,GPT会把背景强行变成黑屏,页面内容都不可见,deepseek4不会改变背景,是在原有页面上出现烟花。烟花效果只能说各有各的喜好吧
--【肆】--:
既然都是最新的模型,应该用gpt5.5对比一下,更加合适
这是DeepSeek V4 Pro的
我要js,给了我一个html
443e69ad137f6a39866×734 42.1 KB
(function() {
// --- 创建全屏 Canvas ---
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const W = window.innerWidth;
const H = window.innerHeight;
canvas.width = W;
canvas.height = H;
canvas.style.cssText = `
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
z-index: 2147483647;
pointer-events: none;
background: transparent;
`;
document.body.appendChild(canvas);
// --- 全局状态 ---
const particles = []; // 所有粒子
const rockets = []; // 飞行中的火箭
const flashes = []; // 爆炸闪光
let lastTime = performance.now();
let allFireworksLaunched = false;
let launchIndex = 0;
let cleanupTimer = null;
// --- 绚丽的颜色主题 ---
const colorThemes = [
{ hue: 5, name: '经典红' }, // 正红
{ hue: 30, name: '金橙' }, // 金橙色
{ hue: 50, name: '璀璨金' }, // 金色
{ hue: 330, name: '玫红' }, // 玫红
{ hue: 280, name: '紫罗兰' }, // 紫色
{ hue: 180, name: '青蓝' }, // 青色
{ hue: 15, name: '橘红' }, // 橘红
{ hue: 340, name: '粉红' }, // 粉红
{ hue: 45, name: '琥珀金' }, // 琥珀金
{ hue: 260, name: '薰衣草紫' }, // 薰衣草紫
{ hue: 200, name: '天蓝' }, // 天蓝色
{ hue: 355, name: '深红' }, // 深红
];
// --- 工具函数:HSL 转 CSS 颜色字符串 ---
function hslToColor(h, s, l, a = 1) {
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
}
// --- 创建爆炸粒子 ---
function createExplosion(x, y, themeHue, particleCount = 120) {
// 闪光效果
flashes.push({
x,
y,
radius: 0,
maxRadius: 60 + Math.random() * 40,
life: 1.0,
decay: 4.5 + Math.random() * 3,
});
// 爆炸粒子
for (let i = 0; i < particleCount; i++) {
const angle = (Math.PI * 2 * i) / particleCount;
// 添加随机偏移让爆炸更自然
const angleOffset = (Math.random() - 0.5) * 0.25;
const finalAngle = angle + angleOffset;
const speed = 280 + Math.random() * 520; // 像素/秒
const speedVariation = 1 + (Math.random() - 0.5) * 0.6;
const vx = Math.cos(finalAngle) * speed * speedVariation;
const vy = Math.sin(finalAngle) * speed * speedVariation;
// 粒子颜色在主题色周围变化
const hueShift = (Math.random() - 0.5) * 40;
const h = (themeHue + hueShift + 360) % 360;
const s = 75 + Math.random() * 25;
const l = 50 + Math.random() * 30;
particles.push({
x,
y,
vx,
vy,
life: 1.0,
maxLife: 1.4 + Math.random() * 1.6, // 秒
color: hslToColor(h, s, l, 1),
size: 1.8 + Math.random() * 3.5,
type: 'spark',
gravity: 160 + Math.random() * 80, // 重力加速度 px/s²
friction: 0.3 + Math.random() * 0.5,
twinkle: Math.random() < 0.25, // 25%的粒子会闪烁
twinkleSpeed: 8 + Math.random() * 25,
});
}
// 额外添加一些"金色雨"慢速粒子
const glitterCount = Math.floor(particleCount * 0.3);
for (let i = 0; i < glitterCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = 60 + Math.random() * 180;
const vx = Math.cos(angle) * speed;
const vy = Math.sin(angle) * speed - 40;
const h = 40 + Math.random() * 25; // 金色范围
const s = 80 + Math.random() * 20;
const l = 55 + Math.random() * 35;
particles.push({
x,
y,
vx,
vy,
life: 1.0,
maxLife: 2.0 + Math.random() * 2.5, // 金色雨持续更久
color: hslToColor(h, s, l, 1),
size: 1.2 + Math.random() * 2.2,
type: 'glitter',
gravity: 60 + Math.random() * 50,
friction: 0.6 + Math.random() * 0.35,
twinkle: true,
twinkleSpeed: 12 + Math.random() * 20,
});
}
}
// --- 创建火箭尾焰粒子 ---
function createTrailParticle(x, y, themeHue) {
const h = 25 + Math.random() * 35; // 尾焰偏橙黄
particles.push({
x: x + (Math.random() - 0.5) * 8,
y: y + (Math.random() - 0.5) * 6,
vx: (Math.random() - 0.5) * 30,
vy: 30 + Math.random() * 60,
life: 1.0,
maxLife: 0.3 + Math.random() * 0.5,
color: hslToColor(h, 90, 55 + Math.random() * 30, 1),
size: 1.5 + Math.random() * 3,
type: 'trail',
gravity: 20,
friction: 0.8,
twinkle: false,
twinkleSpeed: 0,
});
}
// --- 发射烟花 ---
function launchFirework(themeHue, delayMs = 0) {
const startX = W * 0.15 + Math.random() * W * 0.7;
const startY = H + 20;
const targetY = H * 0.18 + Math.random() * H * 0.45;
const targetX = startX + (Math.random() - 0.5) * W * 0.35;
const dx = targetX - startX;
const dy = targetY - startY;
const distance = Math.sqrt(dx * dx + dy * dy);
const flightTime = 0.7 + Math.random() * 0.6; // 飞行时间(秒)
const speed = distance / flightTime;
const vx = (dx / distance) * speed;
const vy = (dy / distance) * speed;
const rocket = {
x: startX,
y: startY,
vx,
vy,
targetY,
targetX,
themeHue,
alive: true,
trailTimer: 0,
trailInterval: 0.015, // 每0.015秒产生一个尾焰粒子
};
if (delayMs > 0) {
// 延迟发射
rocket.delayed = true;
rocket.launchAt = performance.now() + delayMs;
rocket.x = startX;
rocket.y = startY;
// 在延迟期间不更新位置
rocket._vx = vx;
rocket._vy = vy;
rocket.vx = 0;
rocket.vy = 0;
}
rockets.push(rocket);
}
// --- 发射计划:分波次发射 ---
function scheduleFireworks() {
const now = performance.now();
const schedule = [
// [延迟ms, 主题索引]
[0, 0],
[80, 5],
[200, 2],
[350, 8],
[500, 3],
[600, 10],
[750, 1],
[900, 7],
[1050, 4],
[1150, 11],
[1300, 6],
[1450, 9],
[1600, 0],
[1700, 2],
[1850, 5],
[2000, 3],
[2150, 8],
[2300, 1],
[2500, 10],
[2650, 7],
[2800, 4],
[3000, 11],
[3200, 0],
[3350, 6],
[3500, 2],
];
schedule.forEach(([delay, themeIdx]) => {
const theme = colorThemes[themeIdx % colorThemes.length];
launchFirework(theme.hue, delay);
});
// 设置全部发射完毕标志(在最后一个发射后)
const maxDelay = schedule[schedule.length - 1][0] + 2000;
setTimeout(() => {
allFireworksLaunched = true;
}, maxDelay);
}
// --- 更新粒子 ---
function updateParticles(dt) {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.life -= dt / p.maxLife;
if (p.life <= 0) {
particles.splice(i, 1);
continue;
}
// 物理更新
p.vy += p.gravity * dt;
p.vx *= (1 - p.friction * dt * 3);
p.vy *= (1 - p.friction * dt * 3);
p.x += p.vx * dt;
p.y += p.vy * dt;
}
}
// --- 更新火箭 ---
function updateRockets(dt, now) {
for (let i = rockets.length - 1; i >= 0; i--) {
const r = rockets[i];
// 处理延迟发射
if (r.delayed) {
if (now >= r.launchAt) {
r.delayed = false;
r.vx = r._vx;
r.vy = r._vy;
r._vx = undefined;
r._vy = undefined;
} else {
continue; // 还在等待发射
}
}
// 更新位置
r.x += r.vx * dt;
r.y += r.vy * dt;
// 产生尾焰
r.trailTimer += dt;
while (r.trailTimer >= r.trailInterval) {
r.trailTimer -= r.trailInterval;
createTrailParticle(r.x, r.y, r.themeHue);
}
// 检查是否到达目标高度
if (r.y <= r.targetY || r.y <= H * 0.08) {
// 爆炸!
createExplosion(r.x, r.y, r.themeHue, 100 + Math.floor(Math.random() * 80));
rockets.splice(i, 1);
}
// 安全检查:如果火箭飞出屏幕
if (r.y < -200 || r.x < -200 || r.x > W + 200) {
rockets.splice(i, 1);
}
}
}
// --- 更新闪光 ---
function updateFlashes(dt) {
for (let i = flashes.length - 1; i >= 0; i--) {
const f = flashes[i];
f.life -= f.decay * dt;
f.radius += (f.maxRadius - f.radius) * 6 * dt;
if (f.life <= 0) {
flashes.splice(i, 1);
}
}
}
// --- 渲染 ---
function render() {
ctx.clearRect(0, 0, W, H);
// 使用 additive 混合让烟花更绚丽
ctx.globalCompositeOperation = 'lighter';
// 绘制闪光
flashes.forEach(f => {
const alpha = f.life;
const gradient = ctx.createRadialGradient(f.x, f.y, 0, f.x, f.y, f.radius);
gradient.addColorStop(0, `rgba(255,255,240,${alpha * 0.9})`);
gradient.addColorStop(0.3, `rgba(255,240,200,${alpha * 0.5})`);
gradient.addColorStop(0.7, `rgba(255,180,100,${alpha * 0.15})`);
gradient.addColorStop(1, `rgba(255,150,50,0)`);
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(f.x, f.y, f.radius, 0, Math.PI * 2);
ctx.fill();
});
// 绘制粒子
particles.forEach(p => {
const alpha = p.life;
let size = p.size * (0.4 + 0.6 * p.life);
// 闪烁粒子
if (p.twinkle) {
const twinkleFactor = 0.5 + 0.5 * Math.sin(p.life * p.twinkleSpeed * Math.PI * 2);
size *= (0.6 + 0.4 * twinkleFactor);
}
if (size < 0.3) return;
// 光晕
const glowRadius = size * 3;
const gradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, glowRadius);
const baseColor = p.color.replace(/[\d.]+\)$/, '');
gradient.addColorStop(0, p.color.replace(/[\d.]+\)$/, `${Math.min(1, alpha)})`));
gradient.addColorStop(0.35, baseColor + `${alpha * 0.55})`);
gradient.addColorStop(0.7, baseColor + `${alpha * 0.1})`);
gradient.addColorStop(1, baseColor + '0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(p.x, p.y, glowRadius, 0, Math.PI * 2);
ctx.fill();
// 核心亮点
ctx.fillStyle = `rgba(255,255,255,${alpha * 0.8})`;
ctx.beginPath();
ctx.arc(p.x, p.y, size * 0.5, 0, Math.PI * 2);
ctx.fill();
});
// 绘制火箭(小亮点)
ctx.globalCompositeOperation = 'lighter';
rockets.forEach(r => {
if (r.delayed) return;
const gradient = ctx.createRadialGradient(r.x, r.y, 0, r.x, r.y, 8);
gradient.addColorStop(0, 'rgba(255,255,240,0.95)');
gradient.addColorStop(0.4, 'rgba(255,200,100,0.6)');
gradient.addColorStop(1, 'rgba(255,100,30,0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(r.x, r.y, 8, 0, Math.PI * 2);
ctx.fill();
});
// 恢复默认混合模式
ctx.globalCompositeOperation = 'source-over';
}
// --- 检查是否应该清理 ---
function shouldCleanup() {
return allFireworksLaunched &&
rockets.length === 0 &&
particles.length === 0 &&
flashes.length === 0;
}
// --- 执行清理 ---
function cleanup() {
if (canvas.parentNode) {
// 淡出效果
canvas.style.transition = 'opacity 0.8s ease-out';
canvas.style.opacity = '0';
setTimeout(() => {
if (canvas.parentNode) {
canvas.parentNode.removeChild(canvas);
}
}, 800);
}
}
// --- 主循环 ---
function mainLoop(timestamp) {
let dt = (timestamp - lastTime) / 1000; // 转换为秒
lastTime = timestamp;
// 防止大的时间跳跃(如标签页切换)
if (dt > 0.2) dt = 0.2;
if (dt <= 0) dt = 0.016;
const now = performance.now();
updateRockets(dt, now);
updateParticles(dt);
updateFlashes(dt);
render();
if (shouldCleanup()) {
if (!cleanupTimer) {
cleanupTimer = setTimeout(cleanup, 400);
}
}
if (!cleanupTimer || particles.length > 0 || rockets.length > 0 || flashes.length > 0) {
requestAnimationFrame(mainLoop);
} else if (cleanupTimer && particles.length === 0 && rockets.length === 0 && flashes.length ===
0) {
// 已经触发清理,不再请求新帧
// 但再检查一次以防万一
if (!canvas.parentNode) return;
// 如果清理还没执行,继续循环
if (canvas.style.opacity !== '0') {
requestAnimationFrame(mainLoop);
}
}
}
// --- 启动 ---
scheduleFireworks();
lastTime = performance.now();
requestAnimationFrame(mainLoop);
// --- 安全超时:15秒后强制清理 ---
setTimeout(() => {
if (canvas.parentNode && !cleanupTimer) {
allFireworksLaunched = true;
// 快速衰减所有粒子
particles.forEach(p => { p.maxLife *= 0.3;
p.life = Math.min(p.life, 0.3); });
rockets.length = 0;
cleanupTimer = setTimeout(cleanup, 600);
if (!cleanupTimer._set) {
// 确保清理最终执行
setTimeout(cleanup, 2000);
}
}
}, 15000);
console.log('🎆 礼花绽放!欣赏表演吧~(约6-8秒)');
})();
这是Gpt-5.4的(没开思考)
image831×653 36.9 KB
(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
Object.assign(canvas.style, {
position: 'fixed',
left: '0',
top: '0',
width: '100vw',
height: '100vh',
pointerEvents: 'none',
zIndex: '999999'
});
let w = canvas.width = window.innerWidth;
let h = canvas.height = window.innerHeight;
const particles = [];
const colors = ['#ff4d4d', '#ffd24d', '#4dff88', '#4db8ff', '#b84dff', '#ffffff', '#ff7fd1'];
window.addEventListener('resize', () => {
w = canvas.width = window.innerWidth;
h = canvas.height = window.innerHeight;
});
function createFirework(x, y) {
const count = 80 + Math.random() * 40;
for (let i = 0; i < count; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 6 + 2;
particles.push({
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: 60 + Math.random() * 30,
maxLife: 90,
color: colors[Math.floor(Math.random() * colors.length)],
size: Math.random() * 3 + 1
});
}
}
function animate() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.18)';
ctx.fillRect(0, 0, w, h);
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += 0.05;
p.vx *= 0.99;
p.vy *= 0.99;
p.life--;
const alpha = Math.max(p.life / p.maxLife, 0);
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fillStyle = hexToRgba(p.color, alpha);
ctx.fill();
if (p.life <= 0) particles.splice(i, 1);
}
if (particles.length > 0 || running) {
requestAnimationFrame(animate);
} else {
setTimeout(() => canvas.remove(), 500);
}
}
function hexToRgba(hex, alpha) {
const c = hex.replace('#', '');
const bigint = parseInt(c, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return `rgba(${r},${g},${b},${alpha})`;
}
let running = true;
let times = 0;
const timer = setInterval(() => {
createFirework(
Math.random() * w * 0.8 + w * 0.1,
Math.random() * h * 0.5 + h * 0.1
);
times++;
if (times >= 10) {
clearInterval(timer);
running = false;
}
}, 500);
ctx.fillStyle = 'rgba(0,0,0,1)';
ctx.fillRect(0, 0, w, h);
animate();
})();
个人总结:deepseek思考时间长,效果不如gpt5.4
网友解答:--【壹】--:
你看看我刚刚发的glm5.1的,感觉比gpt优秀,也是透明的
--【贰】--:
对比一下GLM5.1
个人认为gpt5.4旗鼓相当,甚至更优秀
(function () {
/* ========== 创建画布 ========== */
const C = document.createElement('canvas');
C.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2147483647;pointer-events:none;';
document.body.appendChild(C);
const ctx = C.getContext('2d');
let W, H;
const resize = () => { W = C.width = innerWidth; H = C.height = innerHeight; };
resize();
addEventListener('resize', resize);
/* ========== 工具函数 ========== */
const rand = (a, b) => Math.random() * (b - a) + a;
const pick = arr => arr[Math.floor(rand(0, arr.length))];
/* ========== 调色板(避免蓝紫系) ========== */
const palettes = [
['#FF6B6B', '#FFE66D', '#FF8E53'], // 暖阳
['#00F5A0', '#00D9F5', '#00FFC6'], // 翡翠
['#FF3CAC', '#FFE66D', '#FF8E53'], // 玫瑰金
['#FF4500', '#FFD700', '#FF6347'], // 烈焰
['#00FF88', '#FFD700', '#FF6B6B'], // 圣诞
['#FF1493', '#FF69B4', '#FFD700'], // 霓虹粉
['#7FFF00', '#00FA9A', '#ADFF2F'], // 荧光绿
['#FF6B35', '#F7C59F', '#FFE66D'], // 沙漠落日
];
/* ========== 粒子 ========== */
class Particle {
constructor(x, y, vx, vy, color, size, life) {
this.x = x; this.y = y; this.vx = vx; this.vy = vy;
this.color = color; this.size = size;
this.life = this.maxLife = life;
this.trail = [];
this.flicker = Math.random() > 0.5;
}
update() {
this.trail.push({ x: this.x, y: this.y });
if (this.trail.length > 7) this.trail.shift();
this.vx *= 0.975; this.vy *= 0.975;
this.vy += 0.045;
this.x += this.vx; this.y += this.vy;
this.life--;
}
draw() {
const alpha = Math.max(0, this.life / this.maxLife);
// 拖尾
for (let i = 0; i < this.trail.length; i++) {
const t = this.trail[i], r = i / this.trail.length;
ctx.globalAlpha = alpha * r * 0.35;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(t.x, t.y, Math.max(0.3, this.size * r * 0.55), 0, Math.PI * 2);
ctx.fill();
}
// 本体
const a = this.flicker ? alpha * (0.6 + 0.4 * Math.sin(this.life * 0.6)) : alpha;
ctx.globalAlpha = a;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, Math.max(0.3, this.size * alpha), 0, Math.PI * 2);
ctx.fill();
// 发光
ctx.globalAlpha = a * 0.18;
ctx.beginPath();
ctx.arc(this.x, this.y, Math.max(0.3, this.size * alpha * 4), 0, Math.PI * 2);
ctx.fill();
}
get dead() { return this.life <= 0; }
}
/* ========== 礼花 ========== */
class Firework {
constructor(sx, tx, ty, palette) {
this.x = sx; this.y = H;
this.tx = tx; this.ty = ty;
this.palette = palette;
const angle = Math.atan2(ty - H, tx - sx);
const speed = rand(11, 15);
this.vx = Math.cos(angle) * speed;
this.vy = Math.sin(angle) * speed;
this.exploded = false;
this.particles = [];
this.trail = [];
}
update() {
if (!this.exploded) {
this.trail.push({ x: this.x + rand(-1, 1), y: this.y, a: 1 });
if (this.trail.length > 22) this.trail.shift();
this.x += this.vx; this.y += this.vy;
this.vy += 0.13;
if (Math.hypot(this.x - this.tx, this.y - this.ty) < 25 || this.vy > 0) {
this.explode();
}
}
for (let i = this.trail.length - 1; i >= 0; i--) {
this.trail[i].a -= 0.04;
if (this.trail[i].a <= 0) this.trail.splice(i, 1);
}
for (let i = this.particles.length - 1; i >= 0; i--) {
this.particles[i].update();
if (this.particles[i].dead) this.particles.splice(i, 1);
}
}
explode() {
this.exploded = true;
const n = rand(90, 170) | 0;
const type = rand(0, 5) | 0;
for (let i = 0; i < n; i++) {
const angle = Math.PI * 2 / n * i + rand(-0.08, 0.08);
let speed;
const color = pick(this.palette);
if (type === 0) speed = rand(2, 8); // 球形
else if (type === 1) speed = i % 2 ? rand(3, 5) : rand(7, 10); // 双环
else if (type === 2) speed = rand(1, 11); // 满天星
else if (type === 3) speed = rand(3, 7) * Math.pow(rand(0.4, 1), 2); // 浓缩
else speed = 4 + 4 * Math.abs(Math.sin(angle * 3)); // 花朵
this.particles.push(new Particle(
this.x, this.y,
Math.cos(angle) * speed, Math.sin(angle) * speed,
color, rand(1.5, 3.2), rand(50, 95) | 0
));
}
// 白色中心闪光
for (let i = 0; i < 10; i++) {
const a = rand(0, Math.PI * 2);
this.particles.push(new Particle(
this.x, this.y,
Math.cos(a) * rand(0.5, 2.5), Math.sin(a) * rand(0.5, 2.5),
'#FFFFFF', rand(3, 5.5), rand(8, 18) | 0
));
}
// 余烬火花
for (let i = 0; i < 20; i++) {
const a = rand(0, Math.PI * 2);
const s = rand(0.3, 1.5);
this.particles.push(new Particle(
this.x, this.y,
Math.cos(a) * s, Math.sin(a) * s,
'#FFD700', rand(0.8, 1.5), rand(70, 130) | 0
));
}
}
draw() {
if (!this.exploded) {
for (let i = 0; i < this.trail.length; i++) {
const t = this.trail[i], r = i / this.trail.length;
ctx.globalAlpha = t.a * r;
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(t.x, t.y, Math.max(0.3, 2 * r), 0, Math.PI * 2);
ctx.fill();
}
ctx.globalAlpha = 1;
ctx.fillStyle = '#FFF';
ctx.beginPath(); ctx.arc(this.x, this.y, 2.5, 0, Math.PI * 2); ctx.fill();
ctx.globalAlpha = 0.5;
ctx.beginPath(); ctx.arc(this.x, this.y, 7, 0, Math.PI * 2); ctx.fill();
}
for (const p of this.particles) p.draw();
ctx.globalAlpha = 1;
}
get done() { return this.exploded && this.particles.length === 0 && this.trail.length === 0; }
}
/* ========== 发射控制 ========== */
const fireworks = [];
const launch = (x) => {
const sx = x ?? rand(W * 0.15, W * 0.85);
fireworks.push(new Firework(sx, sx + rand(-60, 60), rand(H * 0.08, H * 0.35), pick(palettes)));
};
// 开场连发
for (let i = 0; i < 7; i++) setTimeout(() => launch(), i * 220);
// 点击页面任意位置额外发射
const onClick = (e) => { for (let i = 0; i < 2; i++) setTimeout(() => launch(e.clientX + rand(-40, 40)), i * 100); };
document.addEventListener('click', onClick);
/* ========== 主循环 ========== */
let frame = 0, animId;
const loop = () => {
// 用 destination-out 在透明画布上实现淡出拖尾
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0,0,0,0.14)';
ctx.fillRect(0, 0, W, H);
ctx.globalCompositeOperation = 'source-over';
frame++;
if (frame % 38 === 0) launch();
if (frame % 110 === 0) {
const n = rand(2, 5) | 0;
for (let i = 0; i < n; i++) setTimeout(() => launch(), i * 130);
}
for (let i = fireworks.length - 1; i >= 0; i--) {
fireworks[i].update();
fireworks[i].draw();
if (fireworks[i].done) fireworks.splice(i, 1);
}
animId = requestAnimationFrame(loop);
};
loop();
/* ========== 12秒后自动收尾 ========== */
setTimeout(() => {
cancelAnimationFrame(animId);
document.removeEventListener('click', onClick);
C.style.transition = 'opacity 1.5s ease-out';
C.style.opacity = '0';
setTimeout(() => C.remove(), 1600);
}, 12000);
console.log('%c🎆 礼花绽放中!点击页面可追加发射,12秒后自动结束', 'color:#FFD700;font-size:15px;font-weight:bold;');
})();
--【叁】--:
测试过了,GPT会把背景强行变成黑屏,页面内容都不可见,deepseek4不会改变背景,是在原有页面上出现烟花。烟花效果只能说各有各的喜好吧
--【肆】--:
既然都是最新的模型,应该用gpt5.5对比一下,更加合适

