Anmelden
DE
games/satisfying-bounce / src / Render / ZoomView.php · commit 8bdd6e4
<?phpnamespace App\Render;/** * A camera for the 2D drawing: a point of the world at the centre of the screen and a scale. The physics never sees it (bodies keep * their own coordinates); the scene asks x() / y() / len() when it draws. zoomTo() glides to a new scale in log space (the same * speed feeling from x1 to x2 as from x8 to x16) with a smooth ease in and out. rebase() keeps an endless zoom bounded. */final class ZoomView{    public float $scale = 1.0;    private float $from = 1.0;    private float $to = 1.0;    private float $time = 0.0;    private float $duration = 0.0;    private bool $moving = false;    public function __construct(public float $cx = 0.0, public float $cy = 0.0, public float $sx = 0.0, public float $sy = 0.0)    {    }    public function reset(float $scale = 1.0): void    {        $this->scale = $this->from = $this->to = $scale;        $this->moving = false;    }    public function zoomTo(float $target, float $seconds): void    {        $this->from = $this->scale;        $this->to = $target;        $this->time = 0.0;        $this->duration = max(0.001, $seconds);        $this->moving = true;    }    public function isZooming(): bool    {        return $this->moving;    }    public function target(): float    {        return $this->to;    }    public function update(float $dt): void    {        if (!$this->moving) {            return;        }        $this->time += $dt;        $k = min(1.0, $this->time / $this->duration);        $this->scale = exp(log($this->from) + (log($this->to) - log($this->from)) * self::ease($k));        if ($k >= 1.0) {            $this->scale = $this->to;            $this->moving = false;        }    }    /** Smooth in and out (cubic). */    public static function ease(float $k): float    {        $k = max(0.0, min(1.0, $k));        return $k < 0.5 ? 4 * $k ** 3 : 1 - (-2 * $k + 2) ** 3 / 2;    }    public function x(float $wx): float    {        return $this->sx + ($wx - $this->cx) * $this->scale;    }    public function y(float $wy): float    {        return $this->sy + ($wy - $this->cy) * $this->scale;    }    public function len(float $l): float    {        return $l * $this->scale;    }}