JSFiddle - React, Tailwind, and code Playground

CSS

body{
  overflow: hidden;
  margin: 0;
}

JavaScript

import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import * as d3 from 'https://cdn.skypack.dev/d3';
const imgUrl = "https://i.ibb.co/KVbF40w/mesh-texture.png"

// INIT
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 20);

let renderer = new THREE.WebGLRenderer();
let view = d3.select(renderer.domElement)
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

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

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

// TEXTURE
const textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = "Anonymous";
const myTexture = textureLoader.load(imgUrl);
const material = new THREE.MeshBasicMaterial({
  map: myTexture,
});
const geometry = new THREE.PlaneGeometry( 10, 10 );
const mesh = new THREE.Mesh( geometry, material );

scene.add(mesh);

// d3 zoom INIT
const d3Zoom = d3.zoom().on("zoom", (event) => {
  if (event.sourceEvent) {
    onZoom(event);
  }
});
d3Zoom.scaleTo(view, 20);
view.call(d3Zoom);


// ZOOM handler
const onZoom = (event) => {
	const zoomDelta = event.sourceEvent.deltaY;
  const zoomLevel = camera.position.z + zoomDelta * 0.1;
	const vector = new THREE.Vector3(
    ( event.sourceEvent.clientX / window.innerWidth ) * 2 - 1, 
    -( event.sourceEvent.clientY / window.innerHeight ) * 2 + 1,
    0.5
  );

  const distanceBefore = camera.position.distanceTo(vector);
  const distanceAfter = new THREE.Vector3(
  	camera.position.x,
    camera.position.y,
    0,5
  ).distanceTo(vector);
  const ratio = distanceAfter/distanceBefore;
	
  // add P to the camera position
  camera.position.clone().add(vector).normalize();
  // then zoom
  camera.position.set(camera.position.x, camera.position.y, zoomLevel);
  // then subtract P *...