forked from nyancrimew/maia.crimew.gay
		
	add maia oneko
This commit is contained in:
		
							parent
							
								
									9aaf6ac818
								
							
						
					
					
						commit
						54b001b6a7
					
				
					 4 changed files with 170 additions and 0 deletions
				
			
		|  | @ -8,6 +8,9 @@ | ||||||
|             {% endif %} |             {% endif %} | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
|     </div> |     </div> | ||||||
|  |     <div> | ||||||
|  |         <p>maia kitten art by <a href="https://twitter.com/vai5000_">vai5000</a>, pixel art maia kitten by <a href="https://twitter.com/_Anunnery">A. Marmot</a></p> | ||||||
|  |     </div> | ||||||
|     <div class="badges"> |     <div class="badges"> | ||||||
|         {% for item in footer.badges %} |         {% for item in footer.badges %} | ||||||
|             {% if item.link %}<a href="{{ item.link }}" target="_blank">{% endif %}<img src="/badges/{{ item.badge }}" alt="{{ item.alt }}" {% if item.title %}title="{{ item.title }}"{% endif %}>{% if item.link %}</a>{% endif %} |             {% if item.link %}<a href="{{ item.link }}" target="_blank">{% endif %}<img src="/badges/{{ item.badge }}" alt="{{ item.alt }}" {% if item.title %}title="{{ item.title }}"{% endif %}>{% if item.link %}</a>{% endif %} | ||||||
|  |  | ||||||
|  | @ -38,4 +38,5 @@ | ||||||
|     </div> |     </div> | ||||||
|     {% include "components/footer.njk" %} |     {% include "components/footer.njk" %} | ||||||
|   </body> |   </body> | ||||||
|  |   <script src="./oneko.js"></script> | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/static/img/maia_oneko.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/static/img/maia_oneko.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 6.4 KiB | 
							
								
								
									
										166
									
								
								src/static/oneko.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/static/oneko.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -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(); | ||||||
|  | })(); | ||||||
		Loading…
	
		Reference in a new issue