Eventlistener "touchMove"

I’m looking for some documentation or pointers on how I can get a good replacement for a mousemove event that I can use for touch devices. So for mouse devices my 3D model moves on my mouse move events. I would like to have a similar effect happening for touch devices.

Here is my current setup but unfortunately no luck in creating the same effect for touch devices.

 // Model
    let myModel;
    let modelPath_MyModel = 'https://mywebsite/wp-content/uploads/2021/05/new_brain.glb';
    let isLoaded = false;

// Material
let texturePath_Enviroment = 'https://mywebsite/wp-content/uploads/2021/05/Matcap-test19-min.png';
let mat_Enviroment;
let mat_GlassMatCapBack;
let mat_GlassMatCapFront;


let mat_BrainCoreBlue;
let mat_BrainInnerOutterBlue;

let mat_BrainCoreRed;
let mat_BrainInnerOutterRed;

const statsEnabled = false;

let container, stats;

// three
let scene;
let camera;
let renderer;
let delta;

let mouseX = 0;
let mouseY = 0;
let touchX = 0;
let touchY = 0;

let targetX = 0;
let targetY = 0;

const windowHalfX = window.innerWidth / 2;
const windowHalfY = window.innerHeight / 2;

function initMainApp () {
	buildScene();
	buildLightEnviroment();
	buildMaterial();
	buildModel();
	watchLoadingManager();
}

function buildScene () {
	const container = document.querySelector('#mainCanvas');
	
	scene = new THREE.Scene();
	
	camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 100);
	camera.position.z = 14;
	camera.position.y = 0;

	const cameraHolder = new THREE.Group();
	cameraHolder.add(camera);
	scene.add(cameraHolder);

	renderer = new THREE.WebGLRenderer({ container, antialias: true, alpha: true });
  	renderer.setSize(window.innerWidth, window.innerHeight);
	renderer.setPixelRatio(1.5);
	renderer.shadowMap.enabled = true;
	renderer.shadowMap.type = THREE.PCFSoftShadowMap;
	renderer.shadowMap.needsUpdate = true;
        
					stats = new Stats();
	container.appendChild(renderer.domElement);

}

function buildLightEnviroment () {
	const light_Directional = new THREE.DirectionalLight(0xFFFFFF);
	light_Directional.position.set(3, 3, 3);
	light_Directional.intensity = 0.5;
	light_Directional.castShadow = true;
	light_Directional.shadow.bias = -0.00001;
	light_Directional.shadow.mapSize.width = 2048;
	light_Directional.shadow.mapSize.height = 2048;
	scene.add(light_Directional);

	const light_Ambient = new THREE.AmbientLight(0xFFFFFF);
	light_Ambient.intensity = 0.15;
	scene.add(light_Ambient);
  
  const lightpoint3 = new THREE.PointLight(0xFFFFFF,0.4);
  lightpoint3.position.set(100,200,500);
  scene.add(lightpoint3);

	mat_Enviroment = new THREE.TextureLoader().load(texturePath_Enviroment);
	mat_Enviroment.mapping = THREE.SphericalReflectionMapping;
}

function buildModel () {
	const loader_GLTF = new THREE.GLTFLoader();
	loader_GLTF.load(modelPath_MyModel, function (gltf) {

		myModel = gltf.scene;
		scene.add(myModel);


		myModel.position.y = -0.6;



		myModel.traverse(function (child) {
			if (child.isMesh) {



				child.frustumCulled = false;



				if ( child.name == 'brain_right_core') {
					child.material = mat_BrainCoreBlue;
					child.renderOrder = 1;

					child.castShadow = true;
					child.receiveShadow = true;

				} else if ( child.name == 'brain_right_inner'  ) {
					child.material = mat_BrainInnerOutterBlue;
					child.renderOrder = 2;

				} else if ( child.name == 'brain_right_outer' ) {
					child.material = mat_BrainInnerOutterBlue;
					child.renderOrder = 4;

				} else if ( child.name == 'brain_left_core') {
					child.material = mat_BrainCoreRed;
					child.renderOrder = 2;

				} else if ( child.name == 'brain_left_inner') {
					child.material = mat_BrainInnerOutterRed;
					child.renderOrder = 3;

					child.castShadow = true;
					child.receiveShadow = true;

				} else if ( child.name == 'brain_left_outer') {
					child.material = mat_BrainInnerOutterRed;
					child.renderOrder = 5;

				} else if ( child.name == 'bottle') {
					child.material = mat_GlassMatCapBack;
					child.renderOrder = 6;

					let bottleClone = child.clone();
					bottleClone.material = mat_GlassMatCapFront;

					scene.getObjectByName( "BrainBottle" ).add( bottleClone );

				}

				// console.log(myModel);


			}
		});});
}

function buildMaterial () {

	mat_GlassMatCapBack = new THREE.MeshMatcapMaterial({
		color: 0xFFFFFF,
		matcap: mat_Enviroment,
		side: THREE.BackSide,
		transparent: true,
		opacity: 0.35,
		blending: THREE.AdditiveBlending, // THREE.CustomBlending for normal look
	});

	mat_GlassMatCapFront = new THREE.MeshMatcapMaterial({
		color: 0xFFFFFF,
		matcap: mat_Enviroment,
		side: THREE.FrontSide,
		transparent: true,
		opacity: 1,
		blending: THREE.AdditiveBlending, // THREE.CustomBlending for normal look
	});

	mat_BrainCoreBlue = new THREE.MeshPhongMaterial({
		color: 0x25cdda,
		emissive: 0x000000,
    //transparant: true,
    //opacity: 0.05,
    blending: THREE.CustomBlending,
		side: THREE.FrontSide,
		depthWrite: false,
		depthTest: true,
		transparent: true,
		opacity: 0.60,
	});

	mat_BrainInnerOutterBlue = new THREE.MeshPhongMaterial({
		color: 0x25cdd,
		emissive: 0x00FFFF,
		blending: THREE.CustomBlending,
		side: THREE.FrontSide,
		depthWrite: false,
		depthTest: true,
		transparent: true,
		opacity: 0.20,
	});

	mat_BrainCoreRed = new THREE.MeshPhongMaterial({
		color: 0xcb5332,
		emissive: 0x000000,
    blending: THREE.CustomBlending,
		side: THREE.FrontSide,
		depthWrite: false,
		depthTest: true,
		transparent: true,
		opacity: 0.80,
	});

	mat_BrainInnerOutterRed = new THREE.MeshPhongMaterial({
		color: 0xcb5332,
		emissive: 0xFFFF00,
		blending: THREE.CustomBlending,
		side: THREE.FrontSide,
		depthWrite: false,
		depthTest: true,
		transparent: true,
		opacity: 0.20,
	});
}

// EVENTS

				document.addEventListener( 'mousemove', onDocumentMouseMove );
				window.addEventListener( 'resize', onWindowResize );
				document.addEventListener('touchmove', onDocumentTouchMove );
			
function onWindowResize() {

				renderer.setSize( window.innerWidth, window.innerHeight );

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
}

function onDocumentMouseMove( event ) {

				mouseX = ( event.clientX - windowHalfX );
				mouseY = ( event.clientY - windowHalfY );

			}

function onDocumentTouchMove(event){
  
 touchX = ( event.clientX - windowHalfX );
 touchY = ( event.clientY - windowHalfY );  
}

function animate () {
	requestAnimationFrame(animate);
	      render();
				if ( statsEnabled ) stats.update();

			}

			function render() {

				targetX = mouseX * .001;
				targetY = mouseY * .001;
        
        	if ( myModel ) {

					myModel.rotation.y += 0.05 * ( targetX - myModel.rotation.y );
					myModel.rotation.x += 0.05 * ( targetY - myModel.rotation.x );
        }
        
      function render(){
       targetX = onDocumentTouchMove.x * .001;
       targetY = onDocumentTouchMove.Y * .001;
      }

				if ( myModel ) {

					myModel.rotation.y += 0.05 * ( targetX - myModel.rotation.y );
					myModel.rotation.x += 0.05 * ( targetY - myModel.rotation.x );
        }
  

	renderer.render(scene, camera);

	}

function startApplication () {
	
	animate();
}

function watchLoadingManager () {
	THREE.DefaultLoadingManager.onStart = function ( url, itemsLoaded, itemsTotal ) {
		// console.log('Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.');

	};

	THREE.DefaultLoadingManager.onLoad = function () {
		console.log('Loading Complete!');
		isLoaded = true;
		startApplication();

	};

	THREE.DefaultLoadingManager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
		// console.log('Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.');

	};

	THREE.DefaultLoadingManager.onError = function ( url ) {
		// console.log('There was an error loading ' + url);

	};
}

initMainApp();

Have you already tried using pointermove? To make it work properly on touch devices, set the CCS property touch-action to none on the container that has the event listener.

Thanks @Mugen87 I will look into this.

So I decided to just use the orbitcontrols because the other option I can’t get to work. But I have a question regarding to it’s mobile settings. The Orbitcontrols are now active as soon as the canvas comes into the viewport. Is there a way to directly target the object instead of the canvas? My workaround is now to limit the maximum vh of the canvas but this is not an ideal solution. So when possible I would like to target the object instead of the canvas. Thanks again.