You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
8.6 KiB
272 lines
8.6 KiB
// HikeMap Animation Definitions
|
|
// This file defines all available animations for monster and player icons
|
|
// Edit the keyframes to customize how animations look
|
|
|
|
// Player-specific animations (defaults used when no skill override is set)
|
|
const PLAYER_ANIMATIONS = {
|
|
// Default attack animation - lunge forward towards enemies
|
|
attack: {
|
|
name: 'Attack',
|
|
description: 'Lunge forward towards enemy',
|
|
duration: 500,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
keyframes: `
|
|
0% { transform: translateX(0); }
|
|
20% { transform: translateX(-20px) scale(0.9); }
|
|
50% { transform: translateX(30px) scale(1.15); }
|
|
70% { transform: translateX(5px) scale(1.05); }
|
|
100% { transform: translateX(0) scale(1); }
|
|
`
|
|
},
|
|
|
|
// Default skill animation - quick pulse/glow effect
|
|
skill: {
|
|
name: 'Skill',
|
|
description: 'Quick pulse effect for skills',
|
|
duration: 400,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(1.2); }
|
|
`
|
|
},
|
|
|
|
// Miss animation - attack motion then fall clockwise, hold, recover (mirrors monster miss)
|
|
miss: {
|
|
name: 'Miss',
|
|
description: 'Attack then fall over clockwise and recover',
|
|
duration: 2000,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
keyframes: `
|
|
0% { transform: translateX(0) rotate(0deg); }
|
|
10% { transform: translateX(-20px) scale(0.9) rotate(0deg); }
|
|
20% { transform: translateX(30px) scale(1.15) rotate(0deg); }
|
|
30% { transform: translateX(15px) rotate(90deg); }
|
|
70% { transform: translateX(15px) rotate(90deg); }
|
|
85% { transform: translateX(5px) rotate(30deg); }
|
|
100% { transform: translateX(0) rotate(0deg); }
|
|
`
|
|
},
|
|
|
|
// Death animation - fall over
|
|
death: {
|
|
name: 'Death',
|
|
description: 'Fall over permanently',
|
|
duration: 800,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
fillMode: 'forwards',
|
|
keyframes: `
|
|
0% { transform: rotate(0deg); opacity: 1; }
|
|
100% { transform: rotate(90deg); opacity: 0.5; }
|
|
`
|
|
}
|
|
};
|
|
|
|
const MONSTER_ANIMATIONS = {
|
|
// Default attack animation - rubber band snap towards player
|
|
attack: {
|
|
name: 'Attack',
|
|
description: 'Rubber band snap towards player',
|
|
duration: 500,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
keyframes: `
|
|
0% { transform: translateX(0); }
|
|
20% { transform: translateX(20px) scale(0.9); }
|
|
50% { transform: translateX(-30px) scale(1.15); }
|
|
70% { transform: translateX(-5px) scale(1.05); }
|
|
100% { transform: translateX(0) scale(1); }
|
|
`
|
|
},
|
|
|
|
// Default skill animation - quick shake back and forth
|
|
skill: {
|
|
name: 'Skill',
|
|
description: 'Quick shake back and forth',
|
|
duration: 400,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0%, 100% { transform: translateX(0); }
|
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-8px); }
|
|
20%, 40%, 60%, 80% { transform: translateX(8px); }
|
|
`
|
|
},
|
|
|
|
// Default miss animation - attack motion then fall counter-clockwise, hold, recover
|
|
miss: {
|
|
name: 'Miss',
|
|
description: 'Attack then fall over counter-clockwise and recover',
|
|
duration: 2000,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
keyframes: `
|
|
0% { transform: translateX(0) rotate(0deg); }
|
|
10% { transform: translateX(20px) scale(0.9) rotate(0deg); }
|
|
20% { transform: translateX(-30px) scale(1.15) rotate(0deg); }
|
|
30% { transform: translateX(-15px) rotate(-90deg); }
|
|
70% { transform: translateX(-15px) rotate(-90deg); }
|
|
85% { transform: translateX(-5px) rotate(-30deg); }
|
|
100% { transform: translateX(0) rotate(0deg); }
|
|
`
|
|
},
|
|
|
|
// Default death animation - fall over counter-clockwise permanently
|
|
death: {
|
|
name: 'Death',
|
|
description: 'Fall over permanently',
|
|
duration: 600,
|
|
loop: false,
|
|
easing: 'ease-out',
|
|
fillMode: 'forwards',
|
|
keyframes: `
|
|
0% { transform: rotate(0deg); opacity: 1; }
|
|
100% { transform: rotate(-90deg); opacity: 0.6; }
|
|
`
|
|
},
|
|
|
|
// Default idle animation - gentle dance/bob
|
|
idle: {
|
|
name: 'Idle',
|
|
description: 'Gentle dance/bob animation',
|
|
duration: 2000,
|
|
loop: true,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0%, 100% { transform: rotate(-3deg) scale(1); }
|
|
50% { transform: rotate(3deg) scale(0.95); }
|
|
`
|
|
},
|
|
|
|
// Bouncy dance - faster, more energetic idle
|
|
bouncy: {
|
|
name: 'Bouncy Dance',
|
|
description: 'Fast energetic bouncing dance',
|
|
duration: 600,
|
|
loop: true,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0%, 100% { transform: translateY(0) rotate(-5deg) scale(1); }
|
|
25% { transform: translateY(-8px) rotate(5deg) scale(1.1); }
|
|
50% { transform: translateY(0) rotate(-5deg) scale(0.9); }
|
|
75% { transform: translateY(-8px) rotate(5deg) scale(1.1); }
|
|
`
|
|
},
|
|
|
|
// Flip Y animation - spin 360 degrees around vertical axis (like opening a door)
|
|
flipy: {
|
|
name: 'Flip Y',
|
|
description: 'Horizontal flip around vertical axis',
|
|
duration: 600,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0% { transform: rotateY(0deg); }
|
|
100% { transform: rotateY(360deg); }
|
|
`
|
|
},
|
|
|
|
// Flip XY animation - tumbling diagonal flip (somersault + spin)
|
|
flipxy: {
|
|
name: 'Flip XY',
|
|
description: 'Tumbling diagonal flip',
|
|
duration: 800,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0% { transform: rotateX(0deg) rotateY(0deg); }
|
|
100% { transform: rotateX(360deg) rotateY(360deg); }
|
|
`
|
|
},
|
|
|
|
// Flip Z animation - spin like a top viewed from above
|
|
flipz: {
|
|
name: 'Flip Z',
|
|
description: 'Spin like a top',
|
|
duration: 600,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0% { transform: rotateZ(0deg); }
|
|
100% { transform: rotateZ(360deg); }
|
|
`
|
|
},
|
|
|
|
// Shrink and grow animation
|
|
shrink_grow: {
|
|
name: 'Shrink & Grow',
|
|
description: 'Shrink to 50% then grow back',
|
|
duration: 1000,
|
|
loop: false,
|
|
easing: 'ease-in-out',
|
|
keyframes: `
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(0.5); }
|
|
`
|
|
},
|
|
|
|
// Slow spinning with grow/shrink - loopable, smooth like a rotating plant
|
|
spin_grow: {
|
|
name: 'Spin & Grow',
|
|
description: 'Smooth slow spin with pulsing size',
|
|
duration: 4000,
|
|
loop: true,
|
|
easing: 'linear',
|
|
keyframes: `
|
|
0% { transform: rotateZ(0deg) scale(1); }
|
|
50% { transform: rotateZ(-180deg) scale(1.15); }
|
|
100% { transform: rotateZ(-360deg) scale(1); }
|
|
`
|
|
}
|
|
};
|
|
|
|
// Helper function to get animation list for dropdowns
|
|
function getAnimationList() {
|
|
return Object.entries(MONSTER_ANIMATIONS).map(([id, anim]) => ({
|
|
id,
|
|
name: anim.name,
|
|
description: anim.description
|
|
}));
|
|
}
|
|
|
|
// Helper function to get player animation list for dropdowns
|
|
function getPlayerAnimationList() {
|
|
// Player can use both player-specific and monster animations
|
|
const playerAnims = Object.entries(PLAYER_ANIMATIONS).map(([id, anim]) => ({
|
|
id,
|
|
name: anim.name,
|
|
description: anim.description,
|
|
source: 'player'
|
|
}));
|
|
const monsterAnims = Object.entries(MONSTER_ANIMATIONS).map(([id, anim]) => ({
|
|
id,
|
|
name: anim.name,
|
|
description: anim.description,
|
|
source: 'monster'
|
|
}));
|
|
return [...playerAnims, ...monsterAnims];
|
|
}
|
|
|
|
// Get an animation by ID, checking both player and monster animations
|
|
function getAnimation(animationId) {
|
|
if (PLAYER_ANIMATIONS[animationId]) {
|
|
return PLAYER_ANIMATIONS[animationId];
|
|
}
|
|
if (MONSTER_ANIMATIONS[animationId]) {
|
|
return MONSTER_ANIMATIONS[animationId];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Export for use in browser
|
|
if (typeof window !== 'undefined') {
|
|
window.MONSTER_ANIMATIONS = MONSTER_ANIMATIONS;
|
|
window.PLAYER_ANIMATIONS = PLAYER_ANIMATIONS;
|
|
window.getAnimationList = getAnimationList;
|
|
window.getPlayerAnimationList = getPlayerAnimationList;
|
|
window.getAnimation = getAnimation;
|
|
}
|