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"
		}
	}
</script>

CSS

body {
	  margin: 0;
}

JavaScript

import * as THREE from 'three';

import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
import { ParametricGeometry } from 'https://unpkg.com/[email protected]/examples/jsm/geometries/ParametricGeometry.js';

const params = {
  enableWind: true,
  showBall: false,
  togglePins: togglePins
};

const DAMPING = 0.03;
const DRAG = 1 - DAMPING;
const MASS = 0.1;
const restDistance = 25;

const xSegs = 10;
const ySegs = 10;

const clothFunction = plane( restDistance * xSegs, restDistance * ySegs );

const GRAVITY = 981 * 1.4;
const gravity = new THREE.Vector3( 0, - GRAVITY, 0 ).multiplyScalar( MASS );


const TIMESTEP = 18 / 1000;
const TIMESTEP_SQ = TIMESTEP * TIMESTEP;

let pins = [];

const windForce = new THREE.Vector3( 0, 0, 0 );

const ballPosition = new THREE.Vector3( 0, - 45, 0 );
const ballSize = 60; //40

const tmpForce = new THREE.Vector3();
const diff = new THREE.Vector3();

class Particle {

  constructor( x, y, z, mass ) {

    this.position = new THREE.Vector3();
    this.previous = new THREE.Vector3();
    this.original = new THREE.Vector3();
    this.a = new THREE.Vector3( 0, 0, 0 ); // acceleration
    this.mass = mass;
    this.invMass = 1 / mass;
    this.tmp = new THREE.Vector3();
    this.tmp2 = new THREE.Vector3();

    // init

    clothFunction( x, y, this.position ); // position
    clothFunction( x, y, this.previous ); // previous
    clothFunction( x, y, this.original );

  }

  // Force -> Acceleration

  addForce( force ) {

    this.a.add(
      this.tmp2.copy( force ).multiplyScalar( this.invMass )
    );

  }

  // Performs Verlet integration

  integrate( timesq ) {

    const newPos = this.tmp.subVectors( this.position, this.previous );
    newPos.multiplyScalar( DRAG ).add( this.position );
    newPos.add( this.a.multiplyScalar( timesq ) );

    this.tmp = this.previous;
    this.previous = this.position;
    this.position = newPos;

    this.a.set( 0, 0, 0 );

  }

}

class Cloth {

 ...