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 ) %...