From 54b001b6a78df7a1f16e3233fd4704e5e9233241 Mon Sep 17 00:00:00 2001 From: maia arson crimew Date: Fri, 3 Mar 2023 17:14:19 +0100 Subject: [PATCH] add maia oneko --- src/_includes/components/footer.njk | 3 + src/_includes/layouts/default.njk | 1 + src/static/img/maia_oneko.gif | Bin 0 -> 6512 bytes src/static/oneko.js | 166 ++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 src/static/img/maia_oneko.gif create mode 100644 src/static/oneko.js diff --git a/src/_includes/components/footer.njk b/src/_includes/components/footer.njk index bc77a96..88995af 100644 --- a/src/_includes/components/footer.njk +++ b/src/_includes/components/footer.njk @@ -8,6 +8,9 @@ {% endif %} {% endfor %} +
+

maia kitten art by vai5000, pixel art maia kitten by A. Marmot

+
{% for item in footer.badges %} {% if item.link %}{% endif %}{{ item.alt }}{% if item.link %}{% endif %} diff --git a/src/_includes/layouts/default.njk b/src/_includes/layouts/default.njk index ac3c7e5..992c2f4 100644 --- a/src/_includes/layouts/default.njk +++ b/src/_includes/layouts/default.njk @@ -38,4 +38,5 @@
{% include "components/footer.njk" %} + diff --git a/src/static/img/maia_oneko.gif b/src/static/img/maia_oneko.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d264d87d0b9106914df8d1475d80b978a87e609 GIT binary patch literal 6512 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 literal 0 HcmV?d00001 diff --git a/src/static/oneko.js b/src/static/oneko.js new file mode 100644 index 0000000..934af63 --- /dev/null +++ b/src/static/oneko.js @@ -0,0 +1,166 @@ +// based on: https://www.cssscript.com/cat-follow-cursor-oneko/ (licensed under MIT) and edited for maia kitten support with art from https://twitter.com/_Anunnery + +(function oneko() { + const nekoEl = document.createElement("div"); + let nekoPosX = 32; + let nekoPosY = 32; + let mousePosX = 0; + let mousePosY = 0; + let frameCount = 0; + let idleTime = 0; + let idleAnimation = null; + let idleAnimationFrame = 0; + const nekoSpeed = 10; + const spriteSets = { + idle: [[-3, -3]], + alert: [[-7, -3]], + scratch: [ + [-5, 0], + [-6, 0], + [-7, 0], + ], + tired: [[-3, -2]], + sleeping: [ + [-2, 0], + [-2, -1], + ], + N: [ + [-1, -2], + [-1, -3], + ], + NE: [ + [0, -2], + [0, -3], + ], + E: [ + [-3, 0], + [-3, -1], + ], + SE: [ + [-5, -1], + [-5, -2], + ], + S: [ + [-6, -3], + [-7, -2], + ], + SW: [ + [-5, -3], + [-6, -1], + ], + W: [ + [-4, -2], + [-4, -3], + ], + NW: [ + [-1, 0], + [-1, -1], + ], + }; + function create() { + nekoEl.id = "oneko"; + nekoEl.style.width = "32px"; + nekoEl.style.height = "32px"; + nekoEl.style.position = "fixed"; + nekoEl.style.backgroundImage = "url('/img/maia_oneko.gif')"; + nekoEl.style.imageRendering = "pixelated"; + nekoEl.style.left = "16px"; + nekoEl.style.top = "16px"; + + document.body.appendChild(nekoEl); + + document.onmousemove = (event) => { + mousePosX = event.clientX; + mousePosY = event.clientY; + }; + + window.onekoInterval = setInterval(frame, 100); + } + + function setSprite(name, frame) { + const sprite = spriteSets[name][frame % spriteSets[name].length]; + nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${ + sprite[1] * 32 + }px`; + } + + function resetIdleAnimation() { + idleAnimation = null; + idleAnimationFrame = 0; + } + + function idle() { + idleTime += 1; + + // every ~ 20 seconds + if ( + idleTime > 10 && + Math.floor(Math.random() * 200) == 0 && + idleAnimation == null + ) { + idleAnimation = ["sleeping", "scratch"][ + Math.floor(Math.random() * 2) + ]; + } + + switch (idleAnimation) { + case "sleeping": + if (idleAnimationFrame < 8) { + setSprite("tired", 0); + break; + } + setSprite("sleeping", Math.floor(idleAnimationFrame / 4)); + if (idleAnimationFrame > 192) { + resetIdleAnimation(); + } + break; + case "scratch": + setSprite("scratch", idleAnimationFrame); + if (idleAnimationFrame > 9) { + resetIdleAnimation(); + } + break; + default: + setSprite("idle", 0); + return; + } + idleAnimationFrame += 1; + } + + function frame() { + frameCount += 1; + const diffX = nekoPosX - mousePosX; + const diffY = nekoPosY - mousePosY; + const distance = Math.sqrt(diffX ** 2 + diffY ** 2); + + if (distance < nekoSpeed || distance < 48) { + idle(); + return; + } + + idleAnimation = null; + idleAnimationFrame = 0; + + if (idleTime > 1) { + setSprite("alert", 0); + // count down after being alerted before moving + idleTime = Math.min(idleTime, 7); + idleTime -= 1; + return; + } + + direction = diffY / distance > 0.5 ? "N" : ""; + direction += diffY / distance < -0.5 ? "S" : ""; + direction += diffX / distance > 0.5 ? "W" : ""; + direction += diffX / distance < -0.5 ? "E" : ""; + setSprite(direction, frameCount); + + nekoPosX -= (diffX / distance) * nekoSpeed; + nekoPosY -= (diffY / distance) * nekoSpeed; + + nekoEl.style.left = `${nekoPosX - 16}px`; + nekoEl.style.top = `${nekoPosY - 16}px`; + } + + create(); +})();