Files
front/components/CardsGrouped.vue
T

204 lines
4.4 KiB
Vue

<script setup lang="ts">
import { delay } from "~/netcode/events";
import type { Card, Container, PlayingTurn } from "~/netcode/interfaces";
export interface Props {
container: Container;
playingTurn?: PlayingTurn;
wrapped?: boolean;
hidden?: boolean;
noEffects?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
wrapped: () => false,
hidden: () => false,
noEffects: () => false,
});
const emit = defineEmits(["cardClick", "effectClick"]);
const settingsStore = useSettingsStore();
const cards = computed(() => {
if (props.hidden) {
return props.container.cards.map((_v, i) => ({
_id: i,
cardId: undefined,
})) as unknown as Card[];
}
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);
// }
onUnmounted(() => {
// containerEvents.delete(props.container._id);
});
const interval = ref<ReturnType<typeof setInterval>>();
function startMove() {
interval.value = setInterval(() => {
props.container.cards.sort((a, b) => Math.random() - 0.5);
}, 1000);
}
function stopMove() {
clearInterval(interval.value);
}
</script>
<template>
<div
class="cards_container"
:class="{ wrapped, rotate: container.shuffling }"
>
<TransitionGroup name="list">
<CardPreview
@click="$emit('cardClick', c._id)"
@effectClick="$emit('effectClick', c._id, $event)"
@startMove="startMove"
@stopMove="stopMove"
v-for="c in cards"
:card_id="c.cardId"
:wrapped="wrapped"
:key="c._id"
:card="c"
:locked="
!playingTurn || playingTurn?.cardsLocked.includes(c._id.toString())
"
:used_effects_indexes="c.effects?.reduce( (prev,e, i)=>{
if(playingTurn?.lockedEffects.includes(e._id)){
prev.push(i)
}
return prev
},[] as number[])"
:noEffects="noEffects"
>
</CardPreview>
</TransitionGroup>
<!-- <img :class="`card_image`" :src="'/cards/background.png'" draggable="false"> -->
</div>
</template>
<style scoped>
.list-move,
.list-enter-active,
.list-leave-active {
transition: all v-bind("animationSpeed") ease;
}
/* .list-leave-to, */
.list-enter-from {
opacity: 0;
/* transform: translateX(30px); */
}
.list-leave-active {
position: absolute;
height: unset;
}
.rotate {
rotate: 360deg;
}
.cards_container {
display: flex;
flex-direction: row;
justify-content: space-evenly;
min-width: 200px;
flex-wrap: wrap;
transition: rotate v-bind("shuffleAnimationSpeed") ease;
}
.cards_container.wrapped {
flex-direction: column-reverse;
justify-content: center;
}
.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>
<style>
use * use[data-effect-id="0"] {
opacity: 0;
}
.cards_container .card #background rect:first-child {
stroke-width: 0;
}
.cards_container .card.wrapped #background rect:first-child {
stroke-width: 1px;
}
.cards_container .card.card.wrapped:nth-child(5n) #background rect:first-child {
stroke-width: 2px;
}
</style>