変な蜘蛛に噛まれた。 明日スパイダーマンになってるかも。
oneko.js
ソースを読んでいたら Obsidian と関係ない部分があったので整理しました。 まだ削れるかもしれないけど、 現状の覚え書きとして残しておきます。
neko.md
Templater の Startup templates に登録してください。
<%* // https://github.com/adryd325/oneko.js を参照 var nekoGIF = "url('https://raw.githubusercontent.com/adryd325/oneko.js/refs/heads/main/oneko.gif')" var nekoEl = document.createElement("div") var nekoPosX = 32 var nekoPosY = 32 var mousePosX = 0 var mousePosY = 0 var frameCount = 0 var idleTime = 0 var idleAnimation = null var idleAnimationFrame = 0 var direction var nekoSpeed = 10 var spriteSets = { idle: [[-3, -3]], alert: [[-7, -3]], scratchSelf: [[-5, 0],[-6, 0],[-7, 0]], scratchWallN: [[0, 0],[0, -1]], scratchWallS: [[-7, -1],[-6, -2]], scratchWallE: [[-2, -2],[-2, -3]], scratchWallW: [[-4, 0],[-4, -1]], 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 init() { nekoEl.id = "oneko" nekoEl.ariaHidden = true nekoEl.style.width = "32px" nekoEl.style.height = "32px" nekoEl.style.position = "absolute" nekoEl.style.pointerEvents = "none" nekoEl.style.backgroundImage = nekoGIF nekoEl.style.imageRendering = "pixelated" nekoEl.style.left = nekoPosX - 16 + "px" nekoEl.style.top = nekoPosY - 16 + "px" nekoEl.style.zIndex = 99 document.body.appendChild(nekoEl) document.onmousemove = (e) => { mousePosX = e.clientX mousePosY = e.clientY - 16 } window.onekoInterval = setInterval(frame, 100) } function setSprite(name, frame) { var length = spriteSets[name].length var sprite = spriteSets[name][frame % length] nekoEl.style.backgroundPosition = sprite[0] * 32 + "px " + sprite[1] * 32 + "px" } function resetIdleAnimation() { idleAnimation = null idleAnimationFrame = 0 } function idle() { idleTime = idleTime + 1 // every ~ 20 seconds if( idleTime > 10 && Math.floor(Math.random() * 200) == 0 && idleAnimation == null ) { var avalibleIdleAnimations = ["sleeping", "scratchSelf"] if(nekoPosX < 32) { avalibleIdleAnimations.push("scratchWallW") } if(nekoPosY < 32) { avalibleIdleAnimations.push("scratchWallN") } if(nekoPosX > window.innerWidth - 32) { avalibleIdleAnimations.push("scratchWallE") } if(nekoPosY > window.innerHeight - 32) { avalibleIdleAnimations.push("scratchWallS") } idleAnimation = avalibleIdleAnimations[ Math.floor(Math.random() * avalibleIdleAnimations.length) ] } switch(idleAnimation) { case "sleeping": if(idleAnimationFrame < 8) { setSprite("tired", 0) break } setSprite("sleeping", Math.floor(idleAnimationFrame / 4)) if(idleAnimationFrame > 192) resetIdleAnimation() break case "scratchWallN": case "scratchWallS": case "scratchWallE": case "scratchWallW": case "scratchSelf": setSprite(idleAnimation, idleAnimationFrame) if(idleAnimationFrame > 9) resetIdleAnimation() break default: setSprite("idle", 0) return } idleAnimationFrame = idleAnimationFrame + 1 } function frame() { frameCount = frameCount + 1 var diffX = nekoPosX - mousePosX var diffY = nekoPosY - mousePosY var distance = Math.sqrt(Math.pow(diffX, 2) + Math.pow(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 = idleTime - 1 return } direction = "" if(diffY / distance > 0.5) { direction = "N" } else if(diffY / distance < -0.5) { direction = "S" } if(diffX / distance > 0.5) { direction = direction + "W" } else if(diffX / distance < -0.5) { direction = direction + "E" } setSprite(direction, frameCount) if(distance > nekoSpeed) { nekoPosX = nekoPosX - (diffX / distance) * nekoSpeed nekoPosY = nekoPosY - (diffY / distance) * nekoSpeed } else { nekoPosX = mousePosX nekoPosY = mousePosY } nekoPosX = Math.min( Math.max(16, nekoPosX), document.body.clientWidth - 16 ) nekoPosY = Math.min( Math.max(16, nekoPosY), document.body.clientHeight - 16 ) nekoEl.style.left = nekoPosX - 16 + "px" nekoEl.style.top = nekoPosY - 16 + "px" } init() %>
nekoGIF で画像の変更ができます。
エディタ画面でもカーソルを追いかけます。
まとめ
サッカーまであと3時間。 起きてられるかなあ。