<?phpnamespace App\View;use JumPHP\Input\TouchControls;use JumPHP\Renderer\Renderer;/** * Watches the fingers on the screen (the engine only follows one): two fingers moving apart or together are a pinch. * Installed as the input's touch observer; what was there before (the phone app's own controls) still gets everything. */final class Pinch extends TouchControls{ /** @var array<string, array{0: float, 1: float}> finger id => position, 0..1 of the screen */ private array $fingers = []; private float $factor = 1.0; private ?float $last = null; public function __construct(private ?TouchControls $inner = null) { } public function beforeEvents(): void { $this->inner?->beforeEvents(); } public function handle($event, Renderer $renderer): bool { $f = $event->tfinger; $id = (string)$f->fingerId; if ($event->type === \SDL_FINGERUP) { unset($this->fingers[$id]); $this->last = null; } else { $this->fingers[$id] = [(float)$f->x, (float)$f->y]; } if (count($this->fingers) > 2) { // a third finger: start again with the newest two $this->fingers = array_slice($this->fingers, -2, null, true); $this->last = null; } if (count($this->fingers) === 2) { [$a, $b] = array_values($this->fingers); $d = hypot(($a[0] - $b[0]) * 16, ($a[1] - $b[1]) * 9); if ($this->last !== null && $this->last > 0.01 && $d > 0.01) { $this->factor *= $d / $this->last; } $this->last = $d; } return $this->inner?->handle($event, $renderer) ?? false; } public function draw(Renderer $r): void { $this->inner?->draw($r); } /** Forgets every finger (a lost finger-up must not leave a pinch on forever). */ public function reset(): void { $this->fingers = []; $this->factor = 1.0; $this->last = null; } /** Two fingers are down. */ public function active(): bool { return count($this->fingers) >= 2; } /** How much the fingers spread since the last call (1: nothing), and where their middle is (0..1). @return array{0: float, 1: float, 2: float} */ public function take(): array { $factor = $this->factor; $this->factor = 1.0; $pts = array_values($this->fingers); $n = max(1, count($pts)); return [$factor, array_sum(array_column($pts, 0)) / $n, array_sum(array_column($pts, 1)) / $n]; }}