JSFiddle - React, Tailwind, and code Playground

by thelevicole

HTML

<div class="wheel">
	<div class="wheel__inner">
	</div>
</div>

SCSS

$animation-duration: 6s;
$animation-reverse: false;

*, *:before, *:after { box-sizing: border-box; }

.wheel {
	perspective: 1000px;
	border: 1px solid #333;
	margin: 50px;
	
	.wheel__inner {
		background-color: red;
		position: relative;
		width: 200px;
		height: 350px;
		margin: 0 auto;
        transform-style: preserve-3d;
        animation-iteration-count: infinite;
        animation-timing-function: linear;
		animation-name: spin;
		animation-duration: $animation-duration;
		
		@if $animation-reverse {
			animation-direction: reverse;
		}
		
		.wheel__segment {
			display: flex;
			justify-content: center;
			align-items: center;
			width: 100%;
			height: 40px;
			position: absolute;
			top: 50%;
			background-color: #ccc;
			
			// Added transform origin
			transform-origin: 50% 0; // Top center
			
			&:nth-child(even) {
				background-color: #ddd;
			}
		}
	}
}

@-webkit-keyframes spin {
	0%    { transform: rotateX(360deg); }
	50%   { transform: rotateX(180deg); }
	100%  { transform: rotateX(0deg); }
}

JavaScript

( function( $ ) {

	const $wheel = $( '.wheel .wheel__inner' );
	const items = 28;
	const diameter = $wheel.height();
	const radius = diameter / 2;
	const angle = 360 / items;
	const circumference = Math.PI * diameter;
	const height = circumference / items;
	
	for ( let i = 0; i < items; i++ ) {
		var transform = `rotateX(${ angle * i }deg) translateZ(${ radius }px)`;

		$( '<div>', {
			class: 'wheel__segment'
		} ).css( {
			'transform': transform,
			'height': height,
		} ).html( `<span>Item ${ i }</span>` ).appendTo( $wheel );
	}
	
} )( jQuery );