Panning as it’s calculated right now requires two touches, here is a simpler form of panning on the XZ axis that retains pinch zooming with two touches (and gets rid of orbiting).
You will have to expand this script if you would like panning to be relative to the camera angle and not in world space, but I think it’s a good start.
var TouchInput = pc.createScript('touchInput');
TouchInput.attributes.add('orbitSensitivity', {
type: 'number',
default: 0.4,
title: 'Orbit Sensitivity',
description: 'How fast the camera moves around the orbit. Higher is faster'
});
TouchInput.attributes.add('distanceSensitivity', {
type: 'number',
default: 0.2,
title: 'Distance Sensitivity',
description: 'How fast the camera moves in and out. Higher is faster'
});
// initialize code called once per entity
TouchInput.prototype.initialize = function() {
this.orbitCamera = this.entity.script.orbitCamera;
// Store the position of the touch so we can calculate the distance moved
this.lastTouchPoint = new pc.Vec2();
this.lastPinchMidPoint = new pc.Vec2();
this.lastPinchDistance = 0;
if (this.orbitCamera && this.app.touch) {
// Use the same callback for the touchStart, touchEnd and touchCancel events as they
// all do the same thing which is to deal the possible multiple touches to the screen
this.app.touch.on(pc.EVENT_TOUCHSTART, this.onTouchStartEndCancel, this);
this.app.touch.on(pc.EVENT_TOUCHEND, this.onTouchStartEndCancel, this);
this.app.touch.on(pc.EVENT_TOUCHCANCEL, this.onTouchStartEndCancel, this);
this.app.touch.on(pc.EVENT_TOUCHMOVE, this.onTouchMove, this);
this.on('destroy', function() {
this.app.touch.off(pc.EVENT_TOUCHSTART, this.onTouchStartEndCancel, this);
this.app.touch.off(pc.EVENT_TOUCHEND, this.onTouchStartEndCancel, this);
this.app.touch.off(pc.EVENT_TOUCHCANCEL, this.onTouchStartEndCancel, this);
this.app.touch.off(pc.EVENT_TOUCHMOVE, this.onTouchMove, this);
});
}
};
TouchInput.prototype.getPinchDistance = function (pointA, pointB) {
// Return the distance between the two points
var dx = pointA.x - pointB.x;
var dy = pointA.y - pointB.y;
return Math.sqrt((dx * dx) + (dy * dy));
};
TouchInput.prototype.calcMidPoint = function (pointA, pointB, result) {
result.set(pointB.x - pointA.x, pointB.y - pointA.y);
result.scale(0.5);
result.x += pointA.x;
result.y += pointA.y;
};
TouchInput.prototype.onTouchStartEndCancel = function(event) {
// We only care about the first touch for camera rotation. As the user touches the screen,
// we stored the current touch position
var touches = event.touches;
if (touches.length == 1) {
this.lastTouchPoint.set(touches[0].x, touches[0].y);
} else if (touches.length == 2) {
// If there are 2 touches on the screen, then set the pinch distance
this.lastPinchDistance = this.getPinchDistance(touches[0], touches[1]);
this.calcMidPoint(touches[0], touches[1], this.lastPinchMidPoint);
}
};
TouchInput.worldDiff = new pc.Vec3();
TouchInput.prototype.pan = function(pointA, pointB) {
var worldDiff = TouchInput.worldDiff;
worldDiff.z = -(pointA.x - pointB.x);
worldDiff.x = pointA.y - pointB.y;
this.orbitCamera.pivotPoint.add(worldDiff.scale(0.01));
};
TouchInput.pinchMidPoint = new pc.Vec2();
TouchInput.prototype.onTouchMove = function(event) {
var pinchMidPoint = TouchInput.pinchMidPoint;
// We only care about the first touch for camera rotation. Work out the difference moved since the last event
// and use that to update the camera target position
var touches = event.touches;
if (touches.length == 1) {
var touch = touches[0];
this.pan(touches[0], this.lastTouchPoint);
this.lastTouchPoint.set(touch.x, touch.y);
}if (touches.length == 2) {
// Calculate the difference in pinch distance since the last event
var currentPinchDistance = this.getPinchDistance(touches[0], touches[1]);
var diffInPinchDistance = currentPinchDistance - this.lastPinchDistance;
this.lastPinchDistance = currentPinchDistance;
this.orbitCamera.distance -= (diffInPinchDistance * this.distanceSensitivity * 0.1) * (this.orbitCamera.distance * 0.1);
}
};