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();