3,382
个编辑
MCBBS Wiki欢迎您共同参与编辑!在参与编辑之前请先阅读Wiki方针。
如果在编辑的过程中遇到了什么问题,可以去讨论板提问。
为了您能够无阻碍地参与编辑 未验证/绑定过邮箱的用户,请尽快绑定/验证。
MCBBS Wiki GitHub群组已上线!
您可以在回声洞中发表吐槽!
服务器状态监控。点击进入
本站由MCBBS用户自行搭建,与MCBBS及东银河系漫游指南(北京)科技有限公司没有从属关系。点此了解 MCBBS Wiki 不是什么>>
Salt lovely(留言 | 贡献) 小 (添加了自定义烟花颜色色相,颜色波动范围,粒子数量三种自定义参数) |
Salt lovely(留言 | 贡献) 小 (使用TS重写,开源在 github.com/mcbbs-wiki/mcbbs-wiki-widget-repo,换了一种烟花粒子扩散的算法,现在粒子不会聚集成一个环了) |
||
* Inspired By: https://codepen.io/jackrugile/pen/acAgx Author Jack Rugile
*/
"use strict";
(() => {
// src/utils/utils.ts
function docReady(fn) {
if (document.readyState === "loading") {
window.addEventListener("DOMContentLoaded", fn);
} else {
}
}
if (arr.length < 1) {
return null;
}
return arr[Math.floor(Math.random() * arr.length)];
}
// widget/SaltFirework/widget.ts
if (document.getElementById("saltFireWorkCanvas"))
throw new Error("同一页面中只能有一个烟花");
//! 颜色范围
var hueRange;
//! 颜色变化区间
var hueDiff;
//! 粒子效果数量
var count;
var baseRange = [1, 4];
var baseSpeed = [0.3, 2, 3];
var fallSpeed = 1.1 / 60;
var fadeSpeed = 0.65;
var tail = 15;
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var particles = [];
var lastLength = 0;
var zeroFrame = 0;
docReady(init);
function init() {
const getValue = (id, defaultValue, min, max) => {
const e = document.getElementById(id);
if (!e)
return defaultValue;
const c = parseInt(e.textContent || "");
if (isNaN(c) || c < min || c > max)
return defaultValue;
return c;
};
hueRange = (() => {
const defaultValue = (() => {
var x = [];
for (let i = 1; i < 361; i++)
x.push(i);
return x;
})();
const e = document.getElementById("saltFireworkHueRange");
if (!e)
return defaultValue;
const c = (e.textContent || "").replace(/[\s\n_]+/g, "").replace(/[\;\/\|\/\\,;、\-]+/g, ",").split(",").map((v) => parseInt(v)).filter(Boolean).filter((v) => v > 0 && v < 361);
if (!c || c.length < 1 || c.length > 360)
return defaultValue;
return c;
})();
hueDiff = getValue("saltFireworkHueDiff", 30, 0, 180);
count = getValue("saltFireworkCount", 110, 1, 500);
canvas.id = "saltFireWorkCanvas";
canvas.style.left = "0";
canvas.style.top = "0";
canvas.style.position = "fixed";
canvas.style.pointerEvents = "none";
canvas.style.zIndex = "99999";
document.body.appendChild(canvas);
resizeCanvas();
window.addEventListener("resize", resizeCanvas, false);
tick();
document.addEventListener("mousedown", function(e) {
createFireworks(e.clientX, e.clientY);
});
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function rightRandom(base, size) {
return base + (Math.random() * size - Math.random() * size) / 2;
}
function createFireworks(x, y) {
let hue = randomChoice(hueRange);
for (let i = 0; i < count; i++) {
const spd = rightRandom((baseSpeed[1] + baseSpeed[0]) / 2, baseSpeed[1] - baseSpeed[0]);
const rad = Math.random() * 2 * Math.PI;
particles.push({
x,
y,
spdX: Math.cos(rad) * spd,
spdY: Math.sin(rad) * spd,
spdFall: baseSpeed[2],
size: rightRandom((baseRange[1] + baseRange[0]) / 2, baseRange[1] - baseRange[0]),
hue: hueRandom(),
bright: rightRandom(72, 16),
alpha: rightRandom(75, 30)
});
}
function hueRandom() {
let h = Math.floor(rightRandom(hue, hueDiff));
if (h
else
h += 360;
return
}
}
return;
context.globalCompositeOperation = "lighter";
for (let i = 0; i < particles.length; i++)
if (!p)
continue;
p.x
p.y += p.spdY *
p.spdY += fallSpeed;
p.spdFall *=
p.alpha -= fadeSpeed;
context.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
context.closePath();
context.fillStyle = `hsla(${p.hue},100%,${p.bright}%,${p.alpha / 100})`;
context.fill();
//! 标记已经透明到看不见的粒子
if (p.alpha < fadeSpeed)
particles[i] = null;
}
if (lastLength === 0 && particles.length === 0) {
zeroFrame += 1;
if (zeroFrame === 30)
} else {
zeroFrame = 0;
}
lastLength = particles.length;
}
function drawTail() {
//! 保留前一刻的图案作为尾迹
context.globalCompositeOperation = "destination-out";
context.fillStyle = `rgba(0,0,0,${1 / tail})`;
context.fillRect(0, 0, canvas.width, canvas.height);
}
function clearParticles() {
if (!particles.length)
return;
let cp = [];
for (let p of particles)
if (p)
cp.push(p);
if (cp.length !== particles.length)
particles = cp;
}
function tick() {
//! 画尾迹 -> 画这一帧的粒子 -> 删除运算完毕的粒子
drawTail();
drawParticles();
clearParticles();
if (false) {
const el = document.getElementById("saltFWInfo");
if (el) {
el.innerHTML = particles.map((p) => JSON.stringify(p)).join("<br/>");
}
}
requestAnimationFrame(tick);
}
})();
</script></includeonly>
|