I have a SpriteKit scene in my iOS app that makes use of both pan and pinch gestures - panning for moving the view of the scene's camera, and and pinch gestures for zooming in and out of the scene by scaling the scene's camera.
Zooming works well:
@objc func pinchGestureAction(_ sender: UIPinchGestureRecognizer) {
guard let camera = canvasScene.camera else {
return
}
if sender.state == .began {
previousCameraScale = camera.xScale
} else if sender.state == .ended {
previousCameraScale = camera.xScale
return
}
camera.setScale(previousCameraScale * 1 / sender.scale)
print(camera.xScale)
print(camera.yScale)
}
The issue is with the panning, which is done using the pan gesture recognizer:
@objc func panGestureAction(_ sender: UIPanGestureRecognizer) {
if sender.state != .changed {
return
}
guard let camera = canvasScene.camera else {
return
}
// Get touch delta
let translation = sender.translation(in: sender.view!)
// Move camera
self.canvasScene.camera?.position.x -= translation.x
self.canvasScene.camera?.position.y = translation.y
// Reset
sender.setTranslation(CGPoint.zero, in: sender.view)
}
Panning works pretty well when the user is zoomed in really close to the objects on the canvas. When the camera is zoomed further out, it takes a considerably large amount of gestures to pan through the canvas scene than it did when the camera view was zoomed in at a closer view.
I tried scaling the values of the camera position by that of the camera's scaling factor like so:
self.canvasScene.camera?.position.x -= translation.x * camera.xScale
self.canvasScene.camera?.position.y = translation.y * camera.yScale
But that does not seem to work. Any ideas on how to best implement proper camera panning behavior based on that of how far a camera is zoomed in to a scene?
CodePudding user response:
To get the desired behavior, I had to apply an additional scaling factor to the SKScene
's camera position:
@objc func panGestureAction(_ sender: UIPanGestureRecognizer) {
if sender.state != .changed {
return
}
guard let camera = canvasScene.camera else {
return
}
// Get touch delta
let translation = sender.translation(in: sender.view!)
// Move camera
self.canvasScene.camera?.position.x -= translation.x * camera.xScale / 1.5
self.canvasScene.camera?.position.y = translation.y * camera.yScale / 1.5
// Reset
sender.setTranslation(CGPoint.zero, in: sender.view)
}