JSFiddle - React, Tailwind, and code Playground
by thelevicole
HTML
<div class="app">
<textarea id="log"></textarea>
<div class="wheel">
<div class="wheel__inner">
</div>
</div>
</div>
SCSS
*, *:before, *:after { box-sizing: border-box; }
.app {
display: flex;
flex-direction: row;
padding: 15px;
}
textarea#log {
width: 300px;
}
.wheel {
perspective: 1000px;
border: 1px solid #333;
margin: 0 25px;
flex-grow: 1;
&:after {
content: '';
display: block;
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 2px;
background-color: red;
transform: translateY(-50%);
}
.wheel__inner {
//background-color: red;
position: relative;
width: 200px;
height: 350px;
margin: 0 auto;
transform-style: preserve-3d;
.wheel__segment {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 40px;
position: absolute;
top: 50%;
background-color: #ccc;
&:nth-child(even) {
background-color: #ddd;
}
}
}
}
JavaScript
( function( $ ) {
// Settings
const items = 28; // Segments on wheel
const spinSpeed = randNumber( 1, 10 ); // Spin speed multiplier
const spinDuration = randNumber( 2, 5 ); // In seconds
const spinDirection = randNumber( 0, 1 ) ? 'up' : 'down'; // Animate up or down
// Vars
const $wheel = $( '.wheel .wheel__inner' );
const diameter = $wheel.height();
const radius = diameter / 2;
const angle = 360 / items;
const circumference = Math.PI * diameter;
const height = circumference / items;
// Trackers
let wheelAngle = 0;
const wheelStarted = new Date();
// Add segments to the wheel
for ( let i = 0; i < items; i++ ) {
var startAngle = angle * i;
var endAngle = angle * ( i + 1 );
var transform = `rotateX(${ startAngle }deg) translateZ(${ radius }px)`;
var $segment = $( '<div>', {
class: 'wheel__segment',
html: `<span>Item ${ i }</span>`
} ).css( {
'transform': transform,
'height': height,
} );
// Add start and end angles for this segment
$segment.attr( 'data-start-angle', startAngle );
$segment.attr( 'data-end-angle', endAngle );
$segment.appendTo( $wheel );
}
/**
* Print debug info to DOM
*
* @param {object}
*/
function logInfo( data ) {
const $log = $( 'textarea#log' );
let logString = '';
logString += '-----' + "\n";
for ( var key in data ) {
logString += `${ key }: ${ data[ key ] }` + "\n";
}
logString += "\n";
// Prepend log to last value
logString += $log.val();
// Update field value
$log.val( logString );
}
/**
* Get random number between min & max (inclusive)
*
* @param {number} min
* @param {number} max
* @returns {number}
*/
function randNumber( min, max ) {
min = Math.ceil( min );
max = Math.floor( max );
return Math.floor( Math.random() * ( max - min + 1 ) ) + min;
}
/**
* Limit angles to 0 - 360
*
* @param {number}
* @returns {number}
*/
function normaliseAngle( angle ) {
angle = Math.abs( angle ) %...