96 lines
2.6 KiB
Vue
96 lines
2.6 KiB
Vue
<template>
|
|
<motion.img
|
|
:src="props.card.image"
|
|
draggable="false"
|
|
class="h-[60cqh] max-h-[800px] w-[400px] origin-bottom rounded-lg object-cover hover:cursor-grab active:cursor-grabbing md:w-[600px]"
|
|
:style="{
|
|
zIndex: props.isFront ? 500 : props.z,
|
|
gridRow: 1,
|
|
gridColumn: 1,
|
|
transition: '0.125s transform',
|
|
x,
|
|
opacity,
|
|
rotate,
|
|
boxShadow: isFront
|
|
? '0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5)'
|
|
: undefined,
|
|
}"
|
|
alt="Picture of the author"
|
|
:drag="dragValue"
|
|
:drag-constraints="{ left: 0, right: 0 }"
|
|
:on-drag-end="handleDragEnd"
|
|
:animate="{
|
|
scale: props.isFront ? 1 : 0.98,
|
|
}"
|
|
/>
|
|
|
|
<div v-if="props.isFront" class="flex justify-between">
|
|
<!-- Pass Button -->
|
|
<button
|
|
class="mx-12 flex h-24 w-42 flex-col items-center justify-center rounded-xl bg-violet-500 text-4xl text-white shadow-lg transition-colors duration-150 hover:bg-violet-600 focus:ring-4 focus:ring-violet-300 focus:outline-none"
|
|
aria-label="Pass"
|
|
type="button"
|
|
@click="swipeLeft"
|
|
>
|
|
<span class="text-base font-semibold">Pass</span>
|
|
</button>
|
|
|
|
<!-- Smash Button -->
|
|
<button
|
|
class="mx-12 flex h-24 w-42 flex-col items-center justify-center rounded-xl bg-teal-500 text-4xl text-white shadow-lg transition-colors duration-150 hover:bg-teal-600 focus:ring-4 focus:ring-teal-300 focus:outline-none"
|
|
aria-label="Smash"
|
|
type="button"
|
|
@click="swipeRight"
|
|
>
|
|
<span class="text-base font-semibold">Smash</span>
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { animate, motion, useMotionValue, useTransform } from "motion-v";
|
|
import type { PropType } from "vue";
|
|
|
|
import { useCardStore } from "~/store/Card";
|
|
import type { Card } from "~/types/Card";
|
|
|
|
const cardStore = useCardStore();
|
|
|
|
const props = defineProps({
|
|
card: {
|
|
type: Object as PropType<Card>,
|
|
required: true,
|
|
},
|
|
isFront: {
|
|
type: Boolean,
|
|
required: true,
|
|
},
|
|
z: {
|
|
type: Number,
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
const dragValue = computed(() => (props.isFront ? "x" : false));
|
|
|
|
const x = useMotionValue(0);
|
|
const opacity = useTransform(x, [-150, 0, 150], [0, 1, 0]);
|
|
const rotate = useTransform(x, [-150, 150], [-18, 18]);
|
|
|
|
const handleDragEnd = () => {
|
|
if (Math.abs(x.get()) > 50) {
|
|
cardStore.removeCard(props.card.id);
|
|
}
|
|
};
|
|
|
|
async function swipeRight() {
|
|
console.log(props.card.id);
|
|
await animate(x, 300, { duration: 0.3 });
|
|
cardStore.removeCard(props.card.id);
|
|
}
|
|
async function swipeLeft() {
|
|
await animate(x, -300, { duration: 0.3 });
|
|
cardStore.removeCard(props.card.id);
|
|
}
|
|
</script>
|