How to zoom with camera on android.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By SDGN16

How can I make the 3D camera zoom to the phone for the touchscreen?

What do you mean by “zoom”?

Ertain | 2022-04-21 05:01

Two-finger zoom in and out function.

SDGN16 | 2022-04-21 07:57

I want to zoom in and out the camera by enlarging and shrinking with finger. Is there anyone who can help? :frowning:

SDGN16 | 2022-04-21 16:22

:bust_in_silhouette: Reply From: rakkarage

they are working on official godot gestures… or talking about it anyway
something like this can maybe work till
can pinch zoom on android
and can hold alt to simulate pinch with mouse, creates virtual mirror click on opposite side
can test it here

extends Node2D

const _max := 2
var _alt := false
var _touch := []
var _zoomLast := 0.0
var _zoomCurrent := 0.0
var _rotateLast := 0.0
var _rotateCurrent := 0.0

signal onZoom(at, value)
signal onRotate(at, value)

func _ready() -> void:
	z_index = 999
	for _i in range(_max):
		_touch.append({ p = Vector2.ZERO, start = Vector2.ZERO, state = false })

func _mid(a: Vector2, b: Vector2) -> Vector2:
	return (a + b) / 2.0

func _opposite(center: Vector2, p: Vector2) -> Vector2:
	return center - (p - center)

func _mirrorClear() -> void:
	_touch[1].state = Vector2.ZERO
	_touch[1].p = Vector2.ZERO
	_touch[1].start = false

func _mirror() -> void:
	_touch[1].state = _touch[0].state
	_touch[1].p = _opposite(_touch[0].start, _touch[0].p)
	_touch[1].start = _touch[0].start

func _mirrorDrag() -> void:
	_touch[1].p = _opposite(_touch[0].start, _touch[0].p)

func _mirrorTouch(event: InputEvent) -> void:
	_touch[1].state = _touch[0].state
	_touch[1].p = _opposite(_touch[0].start, _touch[0].p)
	if event.pressed:
		_touch[1].start = _touch[0].start

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventKey and event.keycode == KEY_ALT:
		_mirrorClear()
		_alt = event.pressed
		if _alt:
			_mirror()
	if event is InputEventScreenDrag:
		_touch[event.index].p = event.position
		if _alt:
			_mirrorDrag()
	if event is InputEventScreenTouch:
		_touch[event.index].state = event.pressed
		_touch[event.index].p = event.position
		if event.pressed:
			_touch[event.index].start = event.position
		if _alt:
			_mirrorTouch(event)
	var count := 0
	for touch in _touch:
		if touch.state:
			count += 1
	if event is InputEventScreenTouch:
		if not event.pressed and count < 2:
			_zoomLast = 0
			_zoomCurrent = 0
			_rotateLast = 0
			_rotateCurrent = 0
	if count == 2:
		_zoom(event)
		_rotate(event)
	# update() TODO: !?

func _zoom(event: InputEvent) -> void:
	if event is InputEventScreenDrag:
		var zoom : float = _touch[0].p.distance_to(_touch[1].p)
		_zoomCurrent = _zoomLast - zoom
		_zoomLast = zoom
		onZoom.emit(_mid(_touch[0].p, _touch[1].p), _zoomCurrent)

func _rotate(event: InputEvent) -> void:
	if event is InputEventScreenDrag:
		var r : float = _touch[0].p.angle_to_point(_touch[1].p)
		_rotateCurrent = _rotateLast - r
		_rotateLast = r
		onRotate.emit(_mid(_touch[0].p, _touch[1].p), _rotateCurrent)

const _colorA := Color(0.25, 0.25, 0.25)
const _colorB := Color(0.5, 0.5, 0.5)
const _colorC := Color(0.75, 0.75, 0.75)

func _draw() -> void:
	if _alt:
		for touch in _touch:
			if touch.state:
				draw_circle(touch.p, 16, _colorC )
				draw_circle(touch.start, 16, _colorA)
				draw_line(touch.start, touch.p, _colorB, 2)
				draw_arc(touch.start, touch.start.distance_to(touch.p), 0, TAU, 32, _colorC, 2)