|
<script lang="ts"> |
|
import { fade } from 'svelte/transition'; |
|
|
|
export let effects: Array<{type: string, emoji: string, duration: number}> = []; |
|
export let flash: boolean = false; |
|
</script> |
|
|
|
|
|
{#if flash} |
|
<div class="flash-overlay" transition:fade={{ duration: 200 }}></div> |
|
{/if} |
|
|
|
|
|
{#each effects as effect (effect)} |
|
<div class="effect-particle {effect.type}" style="animation-duration: {effect.duration}ms"> |
|
<span class="effect-emoji">{effect.emoji}</span> |
|
</div> |
|
{/each} |
|
|
|
<style> |
|
.flash-overlay { |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
right: 0; |
|
bottom: 0; |
|
background: rgba(255, 255, 255, 0.8); |
|
z-index: 10; |
|
pointer-events: none; |
|
} |
|
|
|
.effect-particle { |
|
position: absolute; |
|
pointer-events: none; |
|
z-index: 5; |
|
animation-fill-mode: forwards; |
|
} |
|
|
|
.effect-emoji { |
|
font-size: 24px; |
|
display: block; |
|
filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.3)); |
|
} |
|
|
|
|
|
.effect-particle.burn, |
|
.effect-particle.poison, |
|
.effect-particle.paralyze, |
|
.effect-particle.sleep, |
|
.effect-particle.freeze { |
|
top: 20%; |
|
left: 50%; |
|
animation: statusEffect linear; |
|
} |
|
|
|
|
|
.effect-particle.attackUp, |
|
.effect-particle.defenseUp, |
|
.effect-particle.speedUp, |
|
.effect-particle.accuracyUp { |
|
bottom: 30%; |
|
left: 50%; |
|
animation: statIncrease ease-out; |
|
} |
|
|
|
.effect-particle.attackDown, |
|
.effect-particle.defenseDown, |
|
.effect-particle.speedDown, |
|
.effect-particle.accuracyDown { |
|
top: 30%; |
|
left: 50%; |
|
animation: statDecrease ease-out; |
|
} |
|
|
|
|
|
.effect-particle.critical, |
|
.effect-particle.superEffective { |
|
top: 10%; |
|
left: 50%; |
|
animation: criticalEffect ease-out; |
|
} |
|
|
|
.effect-particle.notVeryEffective, |
|
.effect-particle.miss { |
|
top: 40%; |
|
left: 50%; |
|
animation: missEffect ease-out; |
|
} |
|
|
|
.effect-particle.heal { |
|
bottom: 20%; |
|
left: 50%; |
|
animation: healEffect ease-out; |
|
} |
|
|
|
|
|
@keyframes statusEffect { |
|
0% { |
|
transform: translate(-50%, 0) scale(0.5); |
|
opacity: 0; |
|
} |
|
20% { |
|
transform: translate(-50%, -10px) scale(1.2); |
|
opacity: 1; |
|
} |
|
40% { |
|
transform: translate(-50%, -5px) scale(1); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: translate(-50%, -20px) scale(0.8); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes statIncrease { |
|
0% { |
|
transform: translate(-50%, 0) scale(0.5); |
|
opacity: 0; |
|
} |
|
30% { |
|
transform: translate(-50%, -30px) scale(1.3); |
|
opacity: 1; |
|
} |
|
70% { |
|
transform: translate(-50%, -40px) scale(1.1); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: translate(-50%, -60px) scale(0.7); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes statDecrease { |
|
0% { |
|
transform: translate(-50%, 0) scale(0.5); |
|
opacity: 0; |
|
} |
|
30% { |
|
transform: translate(-50%, 20px) scale(1.3); |
|
opacity: 1; |
|
} |
|
70% { |
|
transform: translate(-50%, 30px) scale(1.1); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: translate(-50%, 50px) scale(0.7); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes criticalEffect { |
|
0% { |
|
transform: translate(-50%, 0) scale(0.3) rotate(-10deg); |
|
opacity: 0; |
|
} |
|
20% { |
|
transform: translate(-50%, -20px) scale(1.5) rotate(5deg); |
|
opacity: 1; |
|
} |
|
40% { |
|
transform: translate(-50%, -15px) scale(1.3) rotate(-2deg); |
|
opacity: 1; |
|
} |
|
60% { |
|
transform: translate(-50%, -25px) scale(1.4) rotate(1deg); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: translate(-50%, -40px) scale(0.8) rotate(0deg); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes missEffect { |
|
0% { |
|
transform: translate(-50%, 0) scale(1); |
|
opacity: 0; |
|
} |
|
20% { |
|
transform: translate(-50%, 0) scale(1.2); |
|
opacity: 0.7; |
|
} |
|
80% { |
|
transform: translate(-50%, 0) scale(1.1); |
|
opacity: 0.3; |
|
} |
|
100% { |
|
transform: translate(-50%, 0) scale(1); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes healEffect { |
|
0% { |
|
transform: translate(-50%, 20px) scale(0.5); |
|
opacity: 0; |
|
} |
|
30% { |
|
transform: translate(-50%, -10px) scale(1.2); |
|
opacity: 1; |
|
} |
|
70% { |
|
transform: translate(-50%, -30px) scale(1); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: translate(-50%, -50px) scale(0.6); |
|
opacity: 0; |
|
} |
|
} |
|
</style> |