-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcamera.go
More file actions
37 lines (32 loc) · 1.12 KB
/
Copy pathcamera.go
File metadata and controls
37 lines (32 loc) · 1.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main
// Camera defines the visible viewport in world pixels (screen = world*zoom - offset).
type Camera struct {
X, Y float64 // top-left of the view in world pixel space
Zoom float64
}
func NewCamera(x, y, zoom float64) Camera {
return Camera{X: x, Y: y, Zoom: zoom}
}
// ScreenToWorld converts screen pixel coordinates into world pixel coordinates.
func (c *Camera) ScreenToWorld(sx, sy float64) (float64, float64) {
return c.X + sx/c.Zoom, c.Y + sy/c.Zoom
}
// Move pans the camera by world-space deltas.
func (c *Camera) Move(dx, dy float64) {
c.X += dx
c.Y += dy
}
// ZoomAt zooms the camera by factor, keeping the world point under the given
// screen coordinate fixed (zoom toward the cursor). There is no zoom limit:
// the renderer swaps to a pre-rendered overview sprite when zoomed out far
// enough, so arbitrary zoom-out stays fast. Only non-positive zoom is guarded
// against, since it would break the projection math.
func (c *Camera) ZoomAt(factor float64, sx, sy float64) {
wx, wy := c.ScreenToWorld(sx, sy)
c.Zoom *= factor
if c.Zoom < 1e-6 {
c.Zoom = 1e-6
}
c.X = wx - sx/c.Zoom
c.Y = wy - sy/c.Zoom
}