// ==UserScript==
// @name 新年烟花背景(掘金适配)
// @version 1.1.3
// @description 修改页面的背景,使用 canvas 播放动画
// @match https://juejin.cn/**
// @run-at document-end
// @icon https://img2.baidu.com/it/u=4226010475,2406859093&fm=26&fmt=auto
// @namespace https://gf.qytechs.cn/users/8239221
// ==/UserScript==
{
let canvas = document.createElement('canvas');
canvas.id = 'jj-fire-canvas';
canvas.width = window.innerWidth
canvas.height = window.innerHeight
canvas.style.cssText = `background: #0001;
left: 0;
top: 0;
position: fixed;
z-index: -1;`
document.body.appendChild(canvas)
// 抓取页面元素,确定烟花可用区域
let bodyW = 960;//document.getElementById('juejin').getElementsByTagName('div')[0].offsetWidth;
let browerW = window.innerWidth;
function ramdonX(browerW, bodyW) {
let diff = parseInt((browerW - bodyW) / 2);
let x = Math.floor(Math.random() * diff);
return Math.random() > 0.5 ? x : (browerW - x);
}
let rgb = function() {
let str = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
return {
ramdon() {
let color = '#';
for (let i = 0; i < 6; i++) {
color += str[parseInt(Math.floor(Math.random() * 16))]
}
return color;
}
}
}();
let cx = document.getElementById('jj-fire-canvas').getContext('2d')
cx.strokeStyle = '#fff'
cx.fillStyle = '#fff'
cx.lineWidth = 10;
let hz = 1000 / 75;
let max = 8;
// cx.fillRect(100,100,100,100)
// drawLine(cx, 10, 10, 100, 20)
// drawArc(100, 100, 20)
// 等待一下dom 加载
setTimeout(init,500);
// init();
function init() {
setTimeout(() => {
init();
}, Math.random() * 2500 + 500);
fireUp(4);
}
// fireUp(3)
let cleanT = setInterval(() => clean(), hz * 1.2);
function fireUp(r) {
if (max <= 0) return;
let ys = Math.random() * 6 + 2;
let color = rgb.ramdon();
max--;
let x = ramdonX(browerW, bodyW)
let y = window.innerHeight;
ramdomTop = parseInt(Math.random() * 500) + 100;
let time = setInterval(() => {
if (y < ramdomTop) {
clearInterval(time);
drawFiresInRound(x, y);
fireUp(r);
}
y -= ys;
// drawArc(x, y, r)
drawPoint(new Point(x, y, r, color))
}, hz);
function drawFiresInRound(x, y) {
// 根据三角函数计算 x,y
let arrs = caculatePoints(x, y);
let time = setInterval(() => {
if (arrs.length <= 0) {
clearInterval(time);
max++;
return;
}
let p = arrs.shift();
p.forEach(n => drawPoint(n))
}, hz);
}
}
// 计算四周的点位数据
function caculatePoints(px, py) {
let maxR = parseInt(Math.random() * 40) + 20; // 扩散的半径
/**
* [p1-x]
* [p2-x]
*/
step = Math.floor(Math.random() * 5) + 10;
let arrs = [];
for (let i = step; i <= 360; i += step) {
arrs.push(new Point(Math.cos(Math.PI / 180 * i).toFixed(4),
Math.sin(Math.PI / 180 * i).toFixed(4),
2,
rgb.ramdon()));
}
let randomR = arrs.map(n => Number(Math.random() * 0.4 + 0.8).toFixed(2)).map(n => n ** 3)
let arrs2 = [];
for (let i = 1; i < maxR; i++) {
let j = 0;
arrs2.push(arrs.map(n => new Point(n.x * i * 1.8 + px,
n.y * i * 1.5 + py + parseInt(randomR[j++]) * (i ** 1.05),
n.r, n.color)));
}
return arrs2;
}
function Point(x, y, r = 2, color = '#fff') {
return {
x: x,
y: y,
r: r,
color: color
}
}
function clean() {
let max = 5000;
let defaultFillStyle = cx.fillStyle;
cx.fillStyle = '#0002'
cx.beginPath();
cx.fillRect(-max, -max, 2 * max, 2 * max);
cx.fillStyle = defaultFillStyle;
}
function drawPoint(p) {
let oldColor = cx.fillStyle;
cx.fillStyle = p.color;
cx.beginPath();
cx.arc(p.x, p.y, p.r, 0, 2 * Math.PI);
cx.fill();
cx.fillStyle = oldColor;
}
function drawArc(x, y, r) {
cx.beginPath();
cx.arc(x, y, r, 0, 2 * Math.PI);
cx.fill();
}
function drawLine(startX, startY, endX, endY) {
cx.beginPath();
cx.moveTo(startX, startY);
cx.lineTo(endX, endY);
cx.stroke();
cx.closePath()
}
}