Tip of the day
Want to find something particular about the game and don't mind spoilers? Check the Wiki!
MediaWiki:Gadget-AnimatedCursorFollower.js: Difference between revisions
From Walkscape Walkthrough
Created page with "→* * Animated Cursor Follower * Clones the first WalkScape sprite on the page and makes it follow the cursor.: (function () { 'use strict'; const CONFIG = { scale: 1.5, speed: 0.5, offsetX: 30, offsetY: 30 }; const state = { targetX: window.innerWidth / 2, targetY: window.innerHeight / 2, currentX: window.innerWidth / 2, currentY: window.innerHeight / 2, facingRight: true, reqId: null, running: false }; let pet = null; let centerOffs..." |
mNo edit summary |
||
| Line 5: | Line 5: | ||
(function () { | (function () { | ||
'use strict'; | 'use strict'; | ||
console.log('AnimatedCursorFollower gadget loaded'); | |||
console.log('Sprites found:', document.querySelectorAll('span.ws-sprite').length); | |||
const CONFIG = { | const CONFIG = { | ||
scale: 1.5, | scale: 1.5, | ||
Revision as of 01:03, 23 May 2026
/**
* Animated Cursor Follower
* Clones the first WalkScape sprite on the page and makes it follow the cursor.
*/
(function () {
'use strict';
console.log('AnimatedCursorFollower gadget loaded');
console.log('Sprites found:', document.querySelectorAll('span.ws-sprite').length);
const CONFIG = {
scale: 1.5,
speed: 0.5,
offsetX: 30,
offsetY: 30
};
const state = {
targetX: window.innerWidth / 2,
targetY: window.innerHeight / 2,
currentX: window.innerWidth / 2,
currentY: window.innerHeight / 2,
facingRight: true,
reqId: null,
running: false
};
let pet = null;
let centerOffset = 36;
function render() {
if (!pet || !state.running) return;
state.currentX += (state.targetX - state.currentX) * CONFIG.speed;
state.currentY += (state.targetY - state.currentY) * CONFIG.speed;
if (state.targetX > state.currentX + 1) {
state.facingRight = true;
} else if (state.targetX < state.currentX - 1) {
state.facingRight = false;
}
const scaleX = state.facingRight ? 1 : -1;
pet.style.transform = `translate3d(${state.currentX - centerOffset}px, ${state.currentY - centerOffset}px, 0) scaleX(${scaleX})`;
state.reqId = requestAnimationFrame(render);
}
function start() {
if (state.running) return;
state.running = true;
state.reqId = requestAnimationFrame(render);
}
function stop() {
state.running = false;
if (state.reqId) {
cancelAnimationFrame(state.reqId);
state.reqId = null;
}
}
function mountPet(sourceNode) {
if (pet) return;
pet = sourceNode.cloneNode(true);
const styles = window.getComputedStyle(sourceNode);
const frameSize = parseInt(styles.getPropertyValue('--frame'), 10) || 48;
centerOffset = (frameSize * CONFIG.scale) / 2;
pet.classList.add('animated-cursor-follower');
pet.style.setProperty('--scale', CONFIG.scale);
Object.assign(pet.style, {
position: 'fixed',
top: '0',
left: '0',
pointerEvents: 'none',
zIndex: '99999',
margin: '0',
willChange: 'transform',
transition: 'none'
});
document.body.appendChild(pet);
document.addEventListener('mousemove', function (e) {
state.targetX = e.clientX + CONFIG.offsetX;
state.targetY = e.clientY + CONFIG.offsetY;
}, { passive: true });
document.addEventListener('mouseleave', stop);
document.addEventListener('mouseenter', start);
start();
}
function init() {
const sprite = document.querySelector('span.ws-sprite');
if (!sprite) return;
mountPet(sprite);
}
$(init);
}());
