Skip to content

Camera

2D camera with zoom, pan and world/screen transforms.

Camera2D dataclass

Camera2D(
    world_width,
    world_height,
    viewport_width,
    viewport_height,
    initial_zoom=1.0,
    min_zoom=0.25,
    max_zoom=8.0,
    zoom_step=1.1,
    margin_x=1.0,
    margin_y=1.0,
)

world_width instance-attribute

world_width

world_height instance-attribute

world_height

viewport_width instance-attribute

viewport_width

viewport_height instance-attribute

viewport_height

initial_zoom class-attribute instance-attribute

initial_zoom = 1.0

min_zoom class-attribute instance-attribute

min_zoom = 0.25

max_zoom class-attribute instance-attribute

max_zoom = 8.0

zoom_step class-attribute instance-attribute

zoom_step = 1.1

margin_x class-attribute instance-attribute

margin_x = 1.0

margin_y class-attribute instance-attribute

margin_y = 1.0

compute_scale

compute_scale()
Source code in src/hivebr/engine/camera.py
def compute_scale(self):
    scale_x = self.viewport_width / self.world_width
    scale_y = self.viewport_height / self.world_height
    self.base_scale = min(scale_x, scale_y)
    self.scale = self.base_scale * self.zoom

resize

resize(viewport_width, viewport_height)
Source code in src/hivebr/engine/camera.py
def resize(self, viewport_width: int, viewport_height: int):
    self.viewport_width = max(1, int(viewport_width))
    self.viewport_height = max(1, int(viewport_height))
    self.compute_scale()

reset

reset()
Source code in src/hivebr/engine/camera.py
def reset(self):
    self.zoom = self.initial_zoom
    self.offset = np.array([-self.margin_x, -self.margin_y], dtype=float)
    self.compute_scale()

center_on_origin_with_margin

center_on_origin_with_margin()
Source code in src/hivebr/engine/camera.py
def center_on_origin_with_margin(self):
    self.offset = np.array([-self.margin_x, -self.margin_y], dtype=float)

zoom_at

zoom_at(mouse_pos, wheel_y)
Source code in src/hivebr/engine/camera.py
def zoom_at(self, mouse_pos, wheel_y: int):
    old_world = self.screen_to_world(*mouse_pos)
    factor = self.zoom_step if wheel_y > 0 else 1.0 / self.zoom_step
    self.zoom = float(np.clip(self.zoom * factor, self.min_zoom, self.max_zoom))
    self.compute_scale()
    new_world = self.screen_to_world(*mouse_pos)
    self.offset += old_world - new_world

pan_pixels

pan_pixels(dx, dy)
Source code in src/hivebr/engine/camera.py
def pan_pixels(self, dx: float, dy: float):
    self.offset[0] -= dx / self.scale
    self.offset[1] += dy / self.scale

world_to_screen

world_to_screen(px, py)
Source code in src/hivebr/engine/camera.py
def world_to_screen(self, px: float, py: float):
    ox, oy = self._display_offsets()
    px_cam = px - self.offset[0]
    py_cam = py - self.offset[1]
    sx = int(px_cam * self.scale + ox)
    sy = int(self.viewport_height - (py_cam * self.scale + oy))
    return sx, sy

screen_to_world

screen_to_world(sx, sy)
Source code in src/hivebr/engine/camera.py
def screen_to_world(self, sx: float, sy: float):
    ox, oy = self._display_offsets()
    px = (sx - ox) / self.scale + self.offset[0]
    py = ((self.viewport_height - sy) - oy) / self.scale + self.offset[1]
    return np.array([px, py], dtype=float)