You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.9 KiB
Vue

<script setup lang="ts">
import { useHead } from '@vueuse/head'
import { useStorage } from '@vueuse/core'
import { useRoute } from 'vue-router'
const route = useRoute()
const raffleId = route.params.id as string
const raffleStore = useStorage<Raffle[]>('', [])
const raffle = $computed(() => raffleStore.value.find(r => r.id === raffleId))
useHead({ title: raffle ? raffle.title : 'Lets Go' })
const items = $computed(() => {
return raffle ? raffle.participants : []
})
let rollRot = $ref(0)
const sliceRot = 360 / items.length
const sliceSkew = sliceRot + 90
const labelShift = 90 - sliceRot / 2
const pieRot = $computed(() => `${(-90 + sliceRot / 2) + rollRot}deg`)
function roll() {
if (rollRot) rollRot = 0
else {
const winner = Math.round(Math.random() * items.length)
rollRot = 3600 + sliceRot * winner
}
}
</script>
<template>
<template v-if="raffle">
<div class="w-full h-full">
<div class="flex flex-col justify-between items-center w-1/2 h-full">
<header>
<h1 class="my-8 text-2xl">{{ raffle.title }}</h1>
</header>
<button @click="roll" class="text-4xl">{{ rollRot === 0 ? 'Roll!' : 'Reset' }}</button>
<footer>
<p class="my-4">Some raffle description</p>
</footer>
</div>
</div>
<ol
class="pie w-96 h-96 border-2 border-black rounded-full bg-white/10 overflow-hidden transition-transform"
:style="`transition-duration: ${rollRot ? 30 : 1}s`"
>
<li v-for="item,i in items"
class="slice"
:style="`transform: rotate(${sliceRot * i}deg) skewY(${sliceSkew}deg)`"
>
</li>
<li v-for="item,i in items"
class="label"
:style="`transform: rotate(${sliceRot * i + labelShift}deg)`"
>
{{ item }}
</li>
</ol>
</template>
<template v-else>
<div class="flex flex-col justify-center items-center">
<strong>Sorry, I cannot find this raffle.</strong>
<router-link to="/">go back</router-link>
</div>
</template>
</template>
<style scoped>
.pie {
position: absolute;
right: -12rem;
transform: rotate(v-bind(pieRot)) scale(3);
transition: transform 30s cubic-bezier(.38,.16,.67,.89);
}
.label {
position: absolute;
top: calc(50% - .5em);
left: 0;
width: 50%;
height: 1em;
padding-left: 1em;
line-height: 1em;
transform-origin: center right;
}
.slice {
position: absolute;
top: -50%;
right: -50%;
width: 100%;
height: 100%;
transform-origin: 0% 100%;
display: flex;
justify-content: flex-start;
align-items: flex-end;
border: 1px solid black;
}
.slice:nth-child(n) { background-color: #555; }
.slice:nth-child(2n) { background-color: #55A; }
.slice:nth-child(3n) { background-color: #A55; }
.slice:nth-child(4n) { background-color: #AA5; }
.slice:nth-child(5n) { background-color: #A5A; }
.slice:nth-child(6n) { background-color: #5AA; }
.slice:nth-child(7n) { background-color: #999; }
</style>