enhancement(lint): Fix lint errors for lib/jsscripts/oneko.ts

Co-authored-by: NeonGamerBot-QK <neon@saahild.com>
Signed-off-by: zeon-neon[bot] <136533918+zeon-neon[bot]@users.noreply.github.com>
This commit is contained in:
zeon-neon[bot] 2025-07-14 21:41:58 +00:00 committed by GitHub
parent 3d5d7d0d02
commit b0ac19a4f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,287 +1,288 @@
// oneko.js: https://github.com/tylxr59/oneko.js/blob/main/oneko.js // oneko.js: https://github.com/tylxr59/oneko.js/blob/main/oneko.js
// modified by @NeonGamerBot-QK // modified by @NeonGamerBot-QK
// oneko.js: https://github.com/adryd325/oneko.js // oneko.js: https://github.com/adryd325/oneko.js
export function injectOneko() { export function injectOneko() {
const isReducedMotion = window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true; const isReducedMotion =
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
if (isReducedMotion) return;
if (isReducedMotion) return;
const nekoEl = document.createElement("div");
const nekoEl = document.createElement("div");
let nekoPosX = 32;
let nekoPosY = 32; let nekoPosX = 32;
let nekoPosY = 32;
let mousePosX = 0;
let mousePosY = 0; let mousePosX = 0;
let mousePosY = 0;
let frameCount = 0;
let idleTime = 0; let frameCount = 0;
let idleAnimation:any = null; let idleTime = 0;
let idleAnimationFrame = 0; let idleAnimation: any = null;
let idleAnimationFrame = 0;
const nekoSpeed = 10;
const spriteSets = { const nekoSpeed = 10;
idle: [[-3, -3]], const spriteSets = {
alert: [[-7, -3]], idle: [[-3, -3]],
scratchSelf: [ alert: [[-7, -3]],
[-5, 0], scratchSelf: [
[-6, 0], [-5, 0],
[-7, 0], [-6, 0],
], [-7, 0],
scratchWallN: [ ],
[0, 0], scratchWallN: [
[0, -1], [0, 0],
], [0, -1],
scratchWallS: [ ],
[-7, -1], scratchWallS: [
[-6, -2], [-7, -1],
], [-6, -2],
scratchWallE: [ ],
[-2, -2], scratchWallE: [
[-2, -3], [-2, -2],
], [-2, -3],
scratchWallW: [ ],
[-4, 0], scratchWallW: [
[-4, -1], [-4, 0],
], [-4, -1],
tired: [[-3, -2]], ],
sleeping: [ tired: [[-3, -2]],
[-2, 0], sleeping: [
[-2, -1], [-2, 0],
], [-2, -1],
N: [ ],
[-1, -2], N: [
[-1, -3], [-1, -2],
], [-1, -3],
NE: [ ],
[0, -2], NE: [
[0, -3], [0, -2],
], [0, -3],
E: [ ],
[-3, 0], E: [
[-3, -1], [-3, 0],
], [-3, -1],
SE: [ ],
[-5, -1], SE: [
[-5, -2], [-5, -1],
], [-5, -2],
S: [ ],
[-6, -3], S: [
[-7, -2], [-6, -3],
], [-7, -2],
SW: [ ],
[-5, -3], SW: [
[-6, -1], [-5, -3],
], [-6, -1],
W: [ ],
[-4, -2], W: [
[-4, -3], [-4, -2],
], [-4, -3],
NW: [ ],
[-1, 0], NW: [
[-1, -1], [-1, 0],
], [-1, -1],
}; ],
};
function init() {
nekoEl.id = "oneko"; function init() {
nekoEl.ariaHidden = "true"; nekoEl.id = "oneko";
nekoEl.style.width = "32px"; nekoEl.ariaHidden = "true";
nekoEl.style.height = "32px"; nekoEl.style.width = "32px";
nekoEl.style.position = "fixed"; nekoEl.style.height = "32px";
nekoEl.style.pointerEvents = "auto"; nekoEl.style.position = "fixed";
nekoEl.style.imageRendering = "pixelated"; nekoEl.style.pointerEvents = "auto";
nekoEl.style.left = `${nekoPosX - 16}px`; nekoEl.style.imageRendering = "pixelated";
nekoEl.style.top = `${nekoPosY - 16}px`; nekoEl.style.left = `${nekoPosX - 16}px`;
nekoEl.style.zIndex = "99999999"; nekoEl.style.top = `${nekoPosY - 16}px`;
nekoEl.style.zIndex = "99999999";
let nekoFile = "https://saahild.com/oneko.gif"
const curScript = document.currentScript let nekoFile = "https://saahild.com/oneko.gif";
if (curScript && curScript.dataset.cat) { const curScript = document.currentScript;
nekoFile = curScript.dataset.cat if (curScript && curScript.dataset.cat) {
} nekoFile = curScript.dataset.cat;
nekoEl.style.backgroundImage = `url(${nekoFile})`; }
nekoEl.style.backgroundImage = `url(${nekoFile})`;
document.body.appendChild(nekoEl);
document.body.appendChild(nekoEl);
document.addEventListener("mousemove", function (event) {
mousePosX = event.clientX; document.addEventListener("mousemove", function (event) {
mousePosY = event.clientY; mousePosX = event.clientX;
}); mousePosY = event.clientY;
});
window.requestAnimationFrame(onAnimationFrame);
} window.requestAnimationFrame(onAnimationFrame);
}
let lastFrameTimestamp: any ;
let lastFrameTimestamp: any;
function onAnimationFrame(timestamp: any) {
// Stops execution if the neko element is removed from DOM function onAnimationFrame(timestamp: any) {
if (!nekoEl.isConnected) { // Stops execution if the neko element is removed from DOM
return; if (!nekoEl.isConnected) {
} return;
if (!lastFrameTimestamp) { }
lastFrameTimestamp = timestamp; if (!lastFrameTimestamp) {
} lastFrameTimestamp = timestamp;
if (timestamp - lastFrameTimestamp > 100) { }
lastFrameTimestamp = timestamp if (timestamp - lastFrameTimestamp > 100) {
frame() lastFrameTimestamp = timestamp;
} frame();
window.requestAnimationFrame(onAnimationFrame); }
} window.requestAnimationFrame(onAnimationFrame);
}
function setSprite(name: any, frame: any) {
//@ts-ignore function setSprite(name: any, frame: any) {
const sprite = spriteSets[name][frame % spriteSets[name].length]; //@ts-ignore
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`; const sprite = spriteSets[name][frame % spriteSets[name].length];
} nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
}
function resetIdleAnimation() {
idleAnimation = null; function resetIdleAnimation() {
idleAnimationFrame = 0; idleAnimation = null;
} idleAnimationFrame = 0;
}
function idle() {
idleTime += 1; function idle() {
idleTime += 1;
// every ~ 20 seconds
if ( // every ~ 20 seconds
idleTime > 10 && if (
Math.floor(Math.random() * 200) == 0 && idleTime > 10 &&
idleAnimation == null Math.floor(Math.random() * 200) == 0 &&
) { idleAnimation == null
let avalibleIdleAnimations = ["sleeping", "scratchSelf"]; ) {
if (nekoPosX < 32) { let avalibleIdleAnimations = ["sleeping", "scratchSelf"];
avalibleIdleAnimations.push("scratchWallW"); if (nekoPosX < 32) {
} avalibleIdleAnimations.push("scratchWallW");
if (nekoPosY < 32) { }
avalibleIdleAnimations.push("scratchWallN"); if (nekoPosY < 32) {
} avalibleIdleAnimations.push("scratchWallN");
if (nekoPosX > window.innerWidth - 32) { }
avalibleIdleAnimations.push("scratchWallE"); if (nekoPosX > window.innerWidth - 32) {
} avalibleIdleAnimations.push("scratchWallE");
if (nekoPosY > window.innerHeight - 32) { }
avalibleIdleAnimations.push("scratchWallS"); if (nekoPosY > window.innerHeight - 32) {
} avalibleIdleAnimations.push("scratchWallS");
idleAnimation = }
avalibleIdleAnimations[ idleAnimation =
Math.floor(Math.random() * avalibleIdleAnimations.length) avalibleIdleAnimations[
]; Math.floor(Math.random() * avalibleIdleAnimations.length)
} ];
}
switch (idleAnimation) {
case "sleeping": switch (idleAnimation) {
if (idleAnimationFrame < 8) { case "sleeping":
setSprite("tired", 0); if (idleAnimationFrame < 8) {
break; setSprite("tired", 0);
} break;
setSprite("sleeping", Math.floor(idleAnimationFrame / 4)); }
if (idleAnimationFrame > 192) { setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
resetIdleAnimation(); if (idleAnimationFrame > 192) {
} resetIdleAnimation();
break; }
case "scratchWallN": break;
case "scratchWallS": case "scratchWallN":
case "scratchWallE": case "scratchWallS":
case "scratchWallW": case "scratchWallE":
case "scratchSelf": case "scratchWallW":
setSprite(idleAnimation, idleAnimationFrame); case "scratchSelf":
if (idleAnimationFrame > 9) { setSprite(idleAnimation, idleAnimationFrame);
resetIdleAnimation(); if (idleAnimationFrame > 9) {
} resetIdleAnimation();
break; }
default: break;
setSprite("idle", 0); default:
return; setSprite("idle", 0);
} return;
idleAnimationFrame += 1; }
} idleAnimationFrame += 1;
}
function explodeHearts() {
const parent = nekoEl.parentElement; function explodeHearts() {
const rect = nekoEl.getBoundingClientRect(); const parent = nekoEl.parentElement;
const scrollLeft = window.scrollX || document.documentElement.scrollLeft; const rect = nekoEl.getBoundingClientRect();
const scrollTop = window.scrollY || document.documentElement.scrollTop; const scrollLeft = window.scrollX || document.documentElement.scrollLeft;
const centerX = rect.left + rect.width / 2 + scrollLeft; const scrollTop = window.scrollY || document.documentElement.scrollTop;
const centerY = rect.top + rect.height / 2 + scrollTop; const centerX = rect.left + rect.width / 2 + scrollLeft;
const centerY = rect.top + rect.height / 2 + scrollTop;
for (let i = 0; i < 10; i++) {
const heart = document.createElement('div'); for (let i = 0; i < 10; i++) {
heart.className = 'heart'; const heart = document.createElement("div");
heart.textContent = '❤'; heart.className = "heart";
const offsetX = (Math.random() - 0.5) * 50; heart.textContent = "❤";
const offsetY = (Math.random() - 0.5) * 50; const offsetX = (Math.random() - 0.5) * 50;
heart.style.left = `${centerX + offsetX - 16}px`; const offsetY = (Math.random() - 0.5) * 50;
heart.style.top = `${centerY + offsetY - 16}px`; heart.style.left = `${centerX + offsetX - 16}px`;
heart.style.transform = `translate(-50%, -50%) rotate(${Math.random() * 360}deg)`; heart.style.top = `${centerY + offsetY - 16}px`;
parent?.appendChild(heart); heart.style.transform = `translate(-50%, -50%) rotate(${Math.random() * 360}deg)`;
parent?.appendChild(heart);
setTimeout(() => {
parent?.removeChild(heart); setTimeout(() => {
}, 1000); parent?.removeChild(heart);
} }, 1000);
} }
}
const style = document.createElement('style');
style.innerHTML = ` const style = document.createElement("style");
@keyframes heartBurst { style.innerHTML = `
0% { transform: scale(0); opacity: 1; } @keyframes heartBurst {
100% { transform: scale(1); opacity: 0; } 0% { transform: scale(0); opacity: 1; }
} 100% { transform: scale(1); opacity: 0; }
.heart { }
position: absolute; .heart {
font-size: 2em; position: absolute;
animation: heartBurst 1s ease-out; font-size: 2em;
animation-fill-mode: forwards; animation: heartBurst 1s ease-out;
color: var(--mauve); animation-fill-mode: forwards;
} color: var(--mauve);
`; }
`;
document.head.appendChild(style);
nekoEl.addEventListener('click', explodeHearts); document.head.appendChild(style);
nekoEl.addEventListener("click", explodeHearts);
function frame() {
frameCount += 1; function frame() {
const diffX = nekoPosX - mousePosX; frameCount += 1;
const diffY = nekoPosY - mousePosY; const diffX = nekoPosX - mousePosX;
const distance = Math.sqrt(diffX ** 2 + diffY ** 2); const diffY = nekoPosY - mousePosY;
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
if (distance < nekoSpeed || distance < 48) {
idle(); if (distance < nekoSpeed || distance < 48) {
return; idle();
} return;
}
idleAnimation = null;
idleAnimationFrame = 0; idleAnimation = null;
idleAnimationFrame = 0;
if (idleTime > 1) {
setSprite("alert", 0); if (idleTime > 1) {
// count down after being alerted before moving setSprite("alert", 0);
idleTime = Math.min(idleTime, 7); // count down after being alerted before moving
idleTime -= 1; idleTime = Math.min(idleTime, 7);
return; idleTime -= 1;
} return;
}
let direction;
direction = diffY / distance > 0.5 ? "N" : ""; let direction;
direction += diffY / distance < -0.5 ? "S" : ""; direction = diffY / distance > 0.5 ? "N" : "";
direction += diffX / distance > 0.5 ? "W" : ""; direction += diffY / distance < -0.5 ? "S" : "";
direction += diffX / distance < -0.5 ? "E" : ""; direction += diffX / distance > 0.5 ? "W" : "";
setSprite(direction, frameCount); direction += diffX / distance < -0.5 ? "E" : "";
setSprite(direction, frameCount);
nekoPosX -= (diffX / distance) * nekoSpeed;
nekoPosY -= (diffY / distance) * nekoSpeed; nekoPosX -= (diffX / distance) * nekoSpeed;
nekoPosY -= (diffY / distance) * nekoSpeed;
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16); nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
nekoEl.style.left = `${nekoPosX - 16}px`;
nekoEl.style.top = `${nekoPosY - 16}px`; nekoEl.style.left = `${nekoPosX - 16}px`;
} nekoEl.style.top = `${nekoPosY - 16}px`;
}
init();
} init();
}
export function stopOneko() {
return document.getElementById('oneko')?.remove() export function stopOneko() {
} return document.getElementById("oneko")?.remove();
}