JSFiddle - React, Tailwind, and code Playground
by neonDog
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<div class="d-md-flex mt-3">
<div class="options-container d-none">
<textarea class="form-control mb-2" v-model="items_str"></textarea>
<div>
<button class="btn btn-outline-secondary" @click="toggleItems">Check Other Spin Wheel</button>
<br>
<br>
<button class="btn btn-primary float-right" @click="spin">Spin The Wheel</button>
</div>
</div>
<div class="col wheel-col">
<div class="ticker"></div>
<div id="wheel_container">
<svg id="wheel" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" :transform="`rotate(${currDeg})`">
<defs>
<circle id="graph" r="15.9154943092" cx="16" cy="16" transform="rotate(-90 16 16)" />
<mask id="clip">
<use xlink:href="#graph" fill="#FFF" />
</mask>
</defs>
<g mask="url(#clip)" stroke-width="32" class="graph">
<use xlink:href="#graph" fill="none" stroke="#a94fca" stroke-dasharray="0 0 10 100" class="graph__percent graph__percent--0"></use>
<text dy=".60" x=".5" y="16" font-size="1.5" transform=" rotate(108,16,16)" class="text"> 🍕Pizza</text>
<use xlink:href="#graph" fill="none" stroke="#EE4266" stroke-dasharray="0 10 10 100" class="graph__percent graph__percent--1"></use>
<text dy=".60" x=".5" y="16" font-size="1.5" transform=" rotate(144,16,16)" class="text"> 🌮Mexican</text>
<use xlink:href="#graph" fill="none" stroke="#FFD23F" stroke-dasharray="0 20 10 100" class="graph__percent graph__percent--2"></use>
<text dy=".60" x=".5" y="16" font-size="1.5" transform=" rotate(180,16,16)" class="text"> 🍔Burgers</text>
<use xlink:href="#graph" fill="none" stroke="#3BCEAC" stroke-dasharray="0 30 10 100"...
SCSS
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed&display=swap');
html,body{
height: 100%;
}
textarea.form-control{
height:300px;
}
:root{
--border:#bfbfbf;
}
#wheel_container {
background:var(--border);
border:10px solid var(--border);
border-radius:50%;
box-shadow:0 0 8px #000000bd;
position:relative;
max-width:90vh;
//margin:auto;
transform: rotate(calc(var(--rotate, 25) * 1deg));
}
#wheel_container.spinning {
transition: transform 8s cubic-bezier(0.1, -0.01, 0, 1);
}
#wheel_container::after{
content: '';
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
border-left: 1vw solid transparent;
border-right: 1vw solid transparent;
border-top: 3vw solid var(--border);
z-index: 9;
top: 0;
border-top: 2vw solid var(--border);
}
#wheel .text {
fill:#252525;
font-family:'Roboto Condensed', sans-serif;
//font:bold 1 sans-serif;
z-index:55;
//transform-origin: center right;
}
/* Selected prize animation */
#wheel .selected{
color: white;
animation: selected 800ms ease;
}
.wheel-col {
overflow: hidden;
position: relative;
}
@keyframes selected {
25% {
transform: scale(1.25);
//text-shadow: 1vmin 1vmin 0 hsla(0 0% 0% / 0.1);
}
40% {
transform: scale(0.92);
//text-shadow: 0 0 0 hsla(0 0% 0% / 0.2);
}
60% {
transform: scale(1.02);
//text-shadow: 0.5vmin 0.5vmin 0 hsla(0 0% 0% / 0.1);
}
75% {
transform: scale(0.98);
}
85% {
transform: scale(1);
}
}
@keyframes tick {
40% {
transform: rotate(-16deg);
}
}
.ticker {
position: absolute;
--size: clamp(250px, 80vmin, 700px);
left: 0px;
top: 50%;
width: calc(var(--size) / 10);
height: calc(var(--size) / 20);
background: linear-gradient(#000 0 50%, #333 50% 100%);
z-index: 1;
clip-path: polygon(20% 0, 100% 50%, 20% 100%, 0% 50%);
transform-origin: center left;
}
.ticker.animate {
animation: tick 700ms cubic-bezier(0.34, 1.56, 0.64,...
JavaScript
const spinertia = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
};
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
class WheelSpin {
constructor() {
this.colors = ['#FFABE5', '#C7F5FF', '#D89FFF', '#F6FCAE']; //'hsl(197 30% 43%)', 'hsl(173 58% 39%)', 'hsl(43 74% 66%)', 'hsl(27 87% 67%)',
this.colors = ['#a94fca', '#EE4266', '#FFD23F', '#3BCEAC', '#2765d4'];
this.prizes = [{
text: "Shoutout",
//color: "hsl(197 30% 43%)",
reaction: "dancing"
},
{
text: "5x jumps",
//color: "hsl(173 58% 39%)",
reaction: "shocked"
},
{
text: "Jump",
//color: "hsl(43 74% 66%)",
reaction: "shocked"
},
{
text: "Hug",
//color: "hsl(27 87% 67%)",
reaction: "shocked"
},
{
text: "Shower 🚿",
//color: "hsl(12 76% 61%)",
reaction: "dancing"
},
{
text: "Eternal Damnation",
//color: "hsl(350 60% 52%)",
reaction: "laughing"
},
{
text: "Yoga pose",
//color: "hsl(91 43% 54%)",
reaction: "laughing"
},
{
text: "Shoutout 💬",
//color: "hsl(140 36% 74%)",
reaction: "dancing"
}
];
this.currentColorIndex = 0;
this.wheelEl = document.getElementById('wheel_container');
this.ticker = document.getElementsByClassName('ticker')[0];
this.runTickerAnimation = this.runTickerAnimation.bind(this);
this.spinnerStyles = window.getComputedStyle(this.wheelEl);
}
tickSound() {
spin_sound.mozPreservesPitch = false;
spin_sound.playbackRate = randomNumber(1.5,1.6);
spin_sound.play();
}
runTickerAnimation() {
// https://css-tricks.com/get-value-of-css-rotation-through-javascript/
const values =...