I created a dynamic fluid simulation with shaders (utilizing THREE.js) for my website. In order to ensure quick performance even on mobile devices, I opted to simulate at a lower resolution (4 times smaller than the Render Target). While I successfully implemented it for Mouse Events, I have been struggling to accurately scale Touch Events to correspond with actual touch positions.
function handleMove(evt) {
evt.preventDefault();
var touches = evt.targetTouches;
var x = 0, y = 0;
if (BufferBUniforms.iMouse.value.z === 1) {
var element = document.getElementById("container").getBoundingClientRect();
var bodyRect = document.body.getBoundingClientRect();
var h = (element.top - bodyRect.top);
var w = (element.left - bodyRect.left);
// One method I attempted.
x = (touches[0].pageX - w) / scaleMax;
y = height - (touches[0].pageY - h) / scaleMax;
// Another approach I experimented with.
x = (touches[0].pageX - w) / scaleMax;
y = height - (touches[0].pageY - h) / scaleMaxO;
BufferAUniforms.iMouse.value.x = x;
BufferAUniforms.iMouse.value.y = y;
}
}
Below is a snippet showcasing the initialization of some of the variables referenced above:
scale = window.devicePixelRatio;
renderer.setPixelRatio(scale);
container.appendChild(renderer.domElement);
height = window.innerHeight * 0.25;
height = THREE.Math.floorPowerOfTwo( height )
scaleMax = window.innerHeight / height;
width = window.innerWidth * 0.25;
width = THREE.Math.floorPowerOfTwo(width)
scaleRatio = width / height;
scaleMaxO = window.innerWidth / width;
renderer.setSize(width * scaleMax, height * scaleMaxO);
While the functionality works when utilizing Chrome Dev Tools in Mobile Emulator, I encountered issues when testing on a Samsung S9 Plus device.
View the entire project here