mirror of
https://github.com/anotherhadi/blog.git
synced 2026-05-20 05:32:32 +02:00
format
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
+79
-36
@@ -3,57 +3,85 @@
|
||||
(function oneko() {
|
||||
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
||||
|
||||
const SIZE = 32;
|
||||
const SIZE = 32;
|
||||
const SPEED = 10;
|
||||
|
||||
const spriteSets = {
|
||||
idle: [[-3, -3]],
|
||||
alert: [[-7, -3]],
|
||||
scratchSelf: [[-5, 0], [-6, 0], [-7, 0]],
|
||||
scratchWallE:[[-2, -2], [-2, -3]],
|
||||
scratchWallW:[[-4, 0], [-4, -1]],
|
||||
tired: [[-3, -2]],
|
||||
sleeping: [[-2, 0], [-2, -1]],
|
||||
E: [[-3, 0], [-3, -1]],
|
||||
W: [[-4, -2], [-4, -3]],
|
||||
idle: [[-3, -3]],
|
||||
alert: [[-7, -3]],
|
||||
scratchSelf: [
|
||||
[-5, 0],
|
||||
[-6, 0],
|
||||
[-7, 0],
|
||||
],
|
||||
scratchWallE: [
|
||||
[-2, -2],
|
||||
[-2, -3],
|
||||
],
|
||||
scratchWallW: [
|
||||
[-4, 0],
|
||||
[-4, -1],
|
||||
],
|
||||
tired: [[-3, -2]],
|
||||
sleeping: [
|
||||
[-2, 0],
|
||||
[-2, -1],
|
||||
],
|
||||
E: [
|
||||
[-3, 0],
|
||||
[-3, -1],
|
||||
],
|
||||
W: [
|
||||
[-4, -2],
|
||||
[-4, -3],
|
||||
],
|
||||
};
|
||||
|
||||
const track = document.getElementById("oneko-track");
|
||||
if (!track) return;
|
||||
|
||||
const el = document.createElement("div");
|
||||
el.id = "oneko";
|
||||
el.ariaHidden = "true";
|
||||
el.style.width = `${SIZE}px`;
|
||||
el.style.height = `${SIZE}px`;
|
||||
el.style.position = "absolute";
|
||||
el.style.bottom = "0";
|
||||
el.style.pointerEvents = "none";
|
||||
el.id = "oneko";
|
||||
el.ariaHidden = "true";
|
||||
el.style.width = `${SIZE}px`;
|
||||
el.style.height = `${SIZE}px`;
|
||||
el.style.position = "absolute";
|
||||
el.style.bottom = "0";
|
||||
el.style.pointerEvents = "none";
|
||||
el.style.imageRendering = "pixelated";
|
||||
el.style.zIndex = "2147483647";
|
||||
el.style.backgroundImage= "url(/oneko.gif)";
|
||||
el.style.zIndex = "2147483647";
|
||||
el.style.backgroundImage = "url(/oneko.gif)";
|
||||
track.appendChild(el);
|
||||
|
||||
function maxX() { return track.offsetWidth - SIZE; }
|
||||
function clamp(v,lo,hi) { return Math.max(lo, Math.min(hi, v)); }
|
||||
function randomTarget() { return Math.random() * maxX(); }
|
||||
function maxX() {
|
||||
return track.offsetWidth - SIZE;
|
||||
}
|
||||
function clamp(v, lo, hi) {
|
||||
return Math.max(lo, Math.min(hi, v));
|
||||
}
|
||||
function randomTarget() {
|
||||
return Math.random() * maxX();
|
||||
}
|
||||
|
||||
function setSprite(name, frame) {
|
||||
const s = spriteSets[name][frame % spriteSets[name].length];
|
||||
el.style.backgroundPosition = `${s[0] * SIZE}px ${s[1] * SIZE}px`;
|
||||
}
|
||||
|
||||
let posX = randomTarget();
|
||||
let targetX = posX;
|
||||
el.style.left = `${posX}px`;
|
||||
let posX = randomTarget();
|
||||
let targetX = posX;
|
||||
el.style.left = `${posX}px`;
|
||||
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnim = null;
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnim = null;
|
||||
let idleAnimFrame = 0;
|
||||
let lastTs = null;
|
||||
let lastTs = null;
|
||||
|
||||
function resetIdle() { idleAnim = null; idleAnimFrame = 0; }
|
||||
function resetIdle() {
|
||||
idleAnim = null;
|
||||
idleAnimFrame = 0;
|
||||
}
|
||||
|
||||
function idle() {
|
||||
idleTime++;
|
||||
@@ -65,16 +93,23 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (idleTime > 15 && idleAnim == null && Math.floor(Math.random() * 180) === 0) {
|
||||
if (
|
||||
idleTime > 15 &&
|
||||
idleAnim == null &&
|
||||
Math.floor(Math.random() * 180) === 0
|
||||
) {
|
||||
const opts = ["sleeping", "scratchSelf"];
|
||||
if (posX <= SIZE) opts.push("scratchWallW");
|
||||
if (posX <= SIZE) opts.push("scratchWallW");
|
||||
if (posX >= maxX() - SIZE) opts.push("scratchWallE");
|
||||
idleAnim = opts[Math.floor(Math.random() * opts.length)];
|
||||
}
|
||||
|
||||
switch (idleAnim) {
|
||||
case "sleeping":
|
||||
if (idleAnimFrame < 8) { setSprite("tired", 0); break; }
|
||||
if (idleAnimFrame < 8) {
|
||||
setSprite("tired", 0);
|
||||
break;
|
||||
}
|
||||
setSprite("sleeping", Math.floor(idleAnimFrame / 4));
|
||||
if (idleAnimFrame > 192) resetIdle();
|
||||
break;
|
||||
@@ -119,7 +154,10 @@
|
||||
function loop(ts) {
|
||||
if (!el.isConnected) return;
|
||||
if (!lastTs) lastTs = ts;
|
||||
if (ts - lastTs > 100) { lastTs = ts; frame(); }
|
||||
if (ts - lastTs > 100) {
|
||||
lastTs = ts;
|
||||
frame();
|
||||
}
|
||||
window.requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
@@ -128,14 +166,19 @@
|
||||
const newWidth = track.offsetWidth;
|
||||
if (lastTrackWidth > 0) {
|
||||
const ratio = newWidth / lastTrackWidth;
|
||||
posX = clamp(posX * ratio, 0, maxX());
|
||||
posX = clamp(posX * ratio, 0, maxX());
|
||||
targetX = clamp(targetX * ratio, 0, maxX());
|
||||
el.style.left = `${posX}px`;
|
||||
}
|
||||
lastTrackWidth = newWidth;
|
||||
});
|
||||
|
||||
setTimeout(() => { targetX = randomTarget(); }, 800 + Math.random() * 1500);
|
||||
setTimeout(
|
||||
() => {
|
||||
targetX = randomTarget();
|
||||
},
|
||||
800 + Math.random() * 1500,
|
||||
);
|
||||
|
||||
window.requestAnimationFrame(loop);
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user