Rainbow trail that actually emits from center dot
// ==UserScript==
// @name Center Dot Rainbow Trail
// @namespace http://tampermonkey.net/
// @version 1.1
// @author ArhamZeeshan
// @license MIT
// @description Rainbow trail that actually emits from center dot
// @match *://shellshock.io/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const trailCount = 20;
const trail = [];
// =========================
// CREATE TRAIL
// =========================
for (let i = 0; i < trailCount; i++) {
const dot = document.createElement('div');
dot.className = 'rainbow-trail-dot';
document.body.appendChild(dot);
trail.push({
element: dot,
x: window.innerWidth / 2,
y: window.innerHeight / 2
});
}
// =========================
// STYLE
// =========================
const style = document.createElement('style');
style.innerHTML = `
.rainbow-trail-dot {
position: fixed;
pointer-events: none;
width: 8px;
height: 8px;
border-radius: 50%;
z-index: 9998;
transform: translate(-50%, -50%);
}
`;
document.head.appendChild(style);
// =========================
// MOVEMENT DELTA (IMPORTANT)
// =========================
let velX = 0;
let velY = 0;
document.addEventListener('mousemove', (e) => {
if (document.pointerLockElement) {
velX = e.movementX;
velY = e.movementY;
} else {
velX = 0;
velY = 0;
}
});
// =========================
// ANIMATION
// =========================
function updateTrail() {
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
// shift trail
for (let i = trail.length - 1; i > 0; i--) {
trail[i].x = trail[i - 1].x;
trail[i].y = trail[i - 1].y;
}
// head ALWAYS at center dot
trail[0].x = centerX;
trail[0].y = centerY;
// apply movement influence (this creates trailing effect)
for (let i = 1; i < trail.length; i++) {
trail[i].x -= velX * 0.6;
trail[i].y -= velY * 0.6;
}
// draw
trail.forEach((dot, index) => {
const hue = (Date.now() / 20 + index * 10) % 360;
dot.element.style.left = dot.x + 'px';
dot.element.style.top = dot.y + 'px';
dot.element.style.backgroundColor = `hsl(${hue}, 100%, 50%)`;
const size = 8 - (index * 0.3);
if (size > 0) {
dot.element.style.width = size + 'px';
dot.element.style.height = size + 'px';
dot.element.style.opacity = 1 - (index / trail.length);
}
});
// smooth velocity decay
velX *= 0.85;
velY *= 0.85;
requestAnimationFrame(updateTrail);
}
updateTrail();
})();