New Jan 5, 2025

Spin the wheel and stop at specific sector?

Libraries, Frameworks, etc. All from Newest questions tagged vue.js - Stack Overflow View Spin the wheel and stop at specific sector? on stackoverflow.com

I'm trying to create a wheelspin component in Vue.js but I have absolutely no clue on how to detect on what sector is currently indicator pointing at.

And how to stop at specific index after the spin is launched ?

WheelSpin component code https://playcode.io/2211878:

<template>
  <div class="wof-wrapper">
    <div class="wof-indicator"></div>
    <div class="wof-container">
      <div class="wof-sectors" :class="{ spinning }">
        <div
          class="sector"
          v-for="(item, index) in sectors"
          :class="item.code"
          :key="item.code"
          :style="{
            '--i': index,
          }"
        >
          <div class="content">
            <div class="inner">
              <div class="title">{{ item.code }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="wof-center" @click="onBtnSpin">SPIN!</div>
    </div>
  </div>
</template>

<script setup lang="ts"> import { ref } from 'vue';

/* prettier-ignore */ const sectors = ref([ { code: 'product1' }, { code: 'product2' }, { code: 'product3' }, { code: 'product4' }, { code: 'product5' }, { code: 'product6' }, { code: 'product7' }, { code: 'product8' }, { code: 'product9' }, { code: 'product10' }, { code: 'product11' }, { code: 'product12' }, ]);

const spinning = ref(false);

const onBtnSpin = () => { console.log('Start spinning the wheel'); const randomRotation = Math.floor(Math.random() * (10 - 3 + 1) + 5);

spinning.value = true;

const totalRotation = randomRotation * 360; let currentRotation = 0; const sectorElement = document.querySelector('.wof-sectors') as HTMLElement;

const rotateWheel = () => { if (currentRotation < totalRotation) { currentRotation += 360; sectorElement.style.transform = rotate(${currentRotation}deg); requestAnimationFrame(rotateWheel); } else { spinning.value = false; } };

rotateWheel(); }; </script>

<style> .wof-container { width: 400px; height: 400px; border: 2px solid #000; border-radius: 50%; position: relative; display: flex; justify-content: center; align-items: center; overflow: hidden; }

.wof-sectors { width: 100%; height: 100%; position: absolute; top: 0; left: 0; transition: transform 3s cubic-bezier(0.33, 1, 0.68, 1); }

.wof-sectors .sector { width: 200px; height: 200px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); background: #555; color: #fff; font-weight: bold; padding: 10px; transform: rotate(calc(360deg / 12 * var(--i))) skew(60deg); transform-origin: 100% 100%; position: absolute; top: 0; left: 0; position: absolute; display: flex; align-items: flex-end; justify-content: flex-end; border: 1px solid white; }

.content { width: 65%; transform: skew(-60deg); position: relative; left: 20px; }

.inner { rotate: 196deg; bottom: 8px; position: relative; display: flex; align-items: center; transform-origin: 35%; } .title { pointer-events: none; font-size: 14px; text-align: right; text-transform: uppercase; } .q-img { position: absolute; width: 30px; height: auto; } .wof-center { width: 100px; height: 100px; color: #fff; background-color: #000; background-repeat: no-repeat; background-position: 50% 50%; background-size: contain; border-radius: 50%; transition: 0.4s; position: relative; transition: 300ms all; box-shadow: 0 0 0 4px #fff; display: flex; align-items: center; justify-content: center; }

.wof-center:hover { box-shadow: 0 0 0 4px #fff, 0 0px 15px 5px rgba(255, 255, 255, 0.6); cursor: pointer; } .wof-center::after { content: ''; position: absolute; top: -13px; border: 10px solid transparent; border-bottom-color: #fff; border-top: none; left: 50%; margin-left: -10px; } </style>

I tried to rotate using css approach but I'm not sure if it's a good idea. I have no idea either how to stop the wheel at specific sector.

Scroll to top