JSFiddle - React, Tailwind, and code Playground

HTML

<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
    
<script type="importmap">
	{
		"imports": {
			"three": "https://unpkg.com/[email protected]/build/three.module.js",
      "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
		}
	}
</script>

CSS

body {
	  margin: 0;
}

JavaScript

// https://discourse.threejs.org/t/3d-horizontal-caoursel/73484/6
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

import { mergeGeometries } from "three/addons/utils/BufferGeometryUtils.js";

console.clear();

let scene = new THREE.Scene();
scene.background = new THREE.Color(0xaaaaaa);
let camera = new THREE.PerspectiveCamera(30, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0.125, 1).setLength(16);
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

window.addEventListener("resize", (event) => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

let division = { x: 5, y: 5 };
let totalAmount = division.x * division.y;

let len = totalAmount * 1.1;
let r = len / (Math.PI * 2);
let segAngle = (Math.PI * 2) / len / 1.1;

let seg = new THREE.CylinderGeometry(r, r, 1, 10, 1, true, 0, segAngle);
let gs = [];
for (let i = 0; i < totalAmount; i++) {
  let x = i % division.x;
  let y = Math.floor(i / division.x);

  let g = seg.clone();
  let gUV = g.attributes.uv;
  for (let j = 0; j < gUV.count; j++) {
    let u = (gUV.getX(j) + x) / division.x;
    let v = (gUV.getY(j) + y) / division.y;
    gUV.setXY(j, u, v);
  }
  g.rotateY(((Math.PI * 2) / totalAmount) * i);
  gs.push(g);
}

let g = mergeGeometries(gs);
let m = new THREE.MeshBasicMaterial({
  side: THREE.DoubleSide,
  //wireframe: true,
  map: drawCarouselTexture(totalAmount)
});
let carousel = new THREE.Mesh(g, m);
scene.add(carousel);

renderer.setAnimationLoop(() => {
  controls.update();
  renderer.render(scene, camera);
});

function drawCarouselTexture(totalImages = 25, resolution = 512) {
    const gridSize =...