161 lines
3.3 KiB
Vue
161 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
import { containerEvents, delay } from "~/netcode/events";
|
|
import type { Container, PlayingTurn } from "~/netcode/interfaces";
|
|
|
|
export interface Props {
|
|
container: Container;
|
|
playingTurn?: PlayingTurn;
|
|
wrapped?: boolean;
|
|
hidden?: boolean;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
wrapped: () => false,
|
|
hidden: () => false,
|
|
});
|
|
|
|
const emit = defineEmits(["cardClick"]);
|
|
|
|
const settingsStore = useSettingsStore();
|
|
|
|
const cards = computed(() => {
|
|
if (props.hidden) {
|
|
return props.container.cards.map((_v, i) => ({
|
|
_id: i,
|
|
cardId: undefined,
|
|
}));
|
|
}
|
|
return props.container.cards;
|
|
});
|
|
|
|
const animationSpeed = computed(() => settingsStore.animationSpeed + "ms");
|
|
const shuffleAnimationSpeed = computed(
|
|
() => settingsStore.animationSpeed * 2 + "ms"
|
|
);
|
|
function populateContainer() {}
|
|
|
|
const rotate = ref(false);
|
|
async function shuffleContainer() {
|
|
rotate.value = true;
|
|
await delay(settingsStore.animationSpeed * 2);
|
|
rotate.value = false;
|
|
await delay(settingsStore.animationSpeed * 2);
|
|
}
|
|
|
|
function getCardsPosition(cards: string) {}
|
|
|
|
const animationCallbacks = ref<Array<() => void>>([]);
|
|
|
|
function startAnimation() {
|
|
animationCallbacks.value.forEach((p) => p());
|
|
animationCallbacks.value = [];
|
|
}
|
|
|
|
function endAnimation() {
|
|
animationCallbacks.value.forEach((p) => p());
|
|
}
|
|
|
|
watch(
|
|
props.container,
|
|
(newValue, oldValue) => {
|
|
if (oldValue) {
|
|
containerEvents.delete(oldValue._id);
|
|
}
|
|
if (newValue) {
|
|
containerEvents.set(newValue._id, {
|
|
populateContainer,
|
|
shuffleContainer,
|
|
getCardsPosition,
|
|
startAnimation,
|
|
endAnimation,
|
|
});
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
async function onEnter(_el: any, done: () => void) {
|
|
animationCallbacks.value.push(done);
|
|
}
|
|
|
|
async function onLeave(_el: any, done: () => void) {
|
|
animationCallbacks.value.push(done);
|
|
}
|
|
|
|
async function onBeforeEnter() {}
|
|
|
|
onUnmounted(() => {
|
|
containerEvents.delete(props.container._id);
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="cards_container" :class="{ wrapped, rotate }">
|
|
<TransitionGroup
|
|
name="list"
|
|
@enter="onEnter"
|
|
@leave="onLeave"
|
|
@before-enter="onBeforeEnter"
|
|
>
|
|
<CardPreview
|
|
@click="$emit('cardClick', c._id)"
|
|
v-for="c in cards"
|
|
:card_id="c.cardId"
|
|
:wrapped="wrapped"
|
|
:key="c._id"
|
|
:uuid="c._id.toString()"
|
|
:locked="
|
|
!playingTurn || playingTurn?.cardsLocked.includes(c._id.toString())
|
|
"
|
|
>
|
|
</CardPreview>
|
|
</TransitionGroup>
|
|
<!-- <img :class="`card_image`" :src="'/cards/background.png'" draggable="false"> -->
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.list-enter-active,
|
|
.list-leave-active {
|
|
transition: all v-bind("animationSpeed") ease;
|
|
}
|
|
|
|
.list-leave-to,
|
|
.list-enter-from {
|
|
opacity: 0;
|
|
transform: translateX(30px);
|
|
}
|
|
|
|
.rotate {
|
|
rotate: 360deg;
|
|
}
|
|
|
|
.cards_container {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: center;
|
|
min-width: 200px;
|
|
transition: rotate v-bind("shuffleAnimationSpeed") ease;
|
|
}
|
|
|
|
.cards_container.wrapped {
|
|
flex-direction: column-reverse;
|
|
}
|
|
|
|
.cards_container.wrapped:before {
|
|
height: calc(250px - 10px);
|
|
display: block;
|
|
content: "";
|
|
width: 0;
|
|
}
|
|
|
|
.empty {
|
|
max-height: 10px;
|
|
}
|
|
|
|
.empty > .card_image {
|
|
filter: brightness(0.5);
|
|
max-height: 250px;
|
|
}
|
|
</style>
|