input
packageAPI reference for the input
package.
Imports
(4)Camera
Camera represents a simple 2D camera state.
type Camera struct
Fields
| Name | Type | Description |
|---|---|---|
| Position | math.Vec2 | |
| Zoom | float32 | |
| Rotation | float32 |
Manager
Manager handles input bindings and state.
type Manager struct
Methods
BindKey associates a keyboard key with an action.
Parameters
func (*Manager) BindKey(action, key string)
{ m.keyBindings[key] = action }
RebindKey changes the key mapped to an action.
Parameters
func (*Manager) RebindKey(action, key string)
{
for k, a := range m.keyBindings {
if a == action {
delete(m.keyBindings, k)
break
}
}
m.keyBindings[key] = action
}
BindMouse associates a mouse button with an action.
Parameters
func (*Manager) BindMouse(action string, button int)
{ m.mouseBindings[button] = action }
RebindMouse changes the button mapped to an action.
Parameters
func (*Manager) RebindMouse(action string, button int)
{
for b, a := range m.mouseBindings {
if a == action {
delete(m.mouseBindings, b)
break
}
}
m.mouseBindings[button] = action
}
IsActive reports whether an action is currently engaged.
Parameters
Returns
func (*Manager) IsActive(action string) bool
{ return m.active[action] }
DragRect returns the start and end of the current drag along with its state.
func (*Manager) DragRect() (start, end math.Vec2, dragging bool)
{
return m.dragStart, m.dragEnd, m.dragging
}
Camera returns a copy of the current camera state.
Returns
func (*Manager) Camera() Camera
{ return m.camera }
Pan translates the camera by dx, dy.
Parameters
func (*Manager) Pan(dx, dy float32)
{
m.camera.Position = m.camera.Position.Add(math.Vec2{X: dx, Y: dy})
}
Zoom adjusts the camera zoom level.
Parameters
func (*Manager) Zoom(delta float32)
{ m.camera.Zoom += delta }
Rotate adjusts the camera rotation.
Parameters
func (*Manager) Rotate(delta float32)
{ m.camera.Rotation += delta }
Parameters
func (*Manager) handleKeyDown(key string)
{
if action, ok := m.keyBindings[key]; ok {
m.active[action] = true
}
}
Parameters
func (*Manager) handleKeyUp(key string)
{
if action, ok := m.keyBindings[key]; ok {
delete(m.active, action)
}
}
Parameters
func (*Manager) handleMouseDown(button int, x, y float32)
{
if action, ok := m.mouseBindings[button]; ok {
m.active[action] = true
}
if button == 0 {
m.dragging = true
m.dragStart = math.Vec2{X: x, Y: y}
m.dragEnd = m.dragStart
}
m.lastPos = math.Vec2{X: x, Y: y}
}
Parameters
func (*Manager) handleMouseUp(button int, x, y float32)
{
if action, ok := m.mouseBindings[button]; ok {
delete(m.active, action)
}
if button == 0 {
m.dragging = false
}
m.lastPos = math.Vec2{X: x, Y: y}
}
Parameters
func (*Manager) handleMouseMove(x, y float32)
{
pos := math.Vec2{X: x, Y: y}
if m.dragging {
m.dragEnd = pos
}
dx := pos.X - m.lastPos.X
dy := pos.Y - m.lastPos.Y
if m.IsActive("pan") {
m.Pan(dx, dy)
}
if m.IsActive("rotate") {
m.Rotate(dx)
}
m.lastPos = pos
}
Parameters
func (*Manager) handleWheel(delta float32)
{ m.Zoom(-delta / 100) }
Fields
Uses
newManager
Returns
func newManager() *Manager
{
return &Manager{
keyBindings: make(map[string]string),
mouseBindings: make(map[int]string),
active: make(map[string]bool),
camera: Camera{Zoom: 1},
}
}
New
New creates a Manager and wires browser event listeners.
Returns
func New() *Manager
{
m := newManager()
events.OnKeyDown(func(evt js.Value) {
m.handleKeyDown(evt.Get("key").String())
})
events.OnKeyUp(func(evt js.Value) {
m.handleKeyUp(evt.Get("key").String())
})
events.On("mousedown", js.Document(), func(evt js.Value) {
m.handleMouseDown(evt.Get("button").Int(), float32(evt.Get("clientX").Float()), float32(evt.Get("clientY").Float()))
})
events.On("mouseup", js.Document(), func(evt js.Value) {
m.handleMouseUp(evt.Get("button").Int(), float32(evt.Get("clientX").Float()), float32(evt.Get("clientY").Float()))
})
events.On("mousemove", js.Document(), func(evt js.Value) {
m.handleMouseMove(float32(evt.Get("clientX").Float()), float32(evt.Get("clientY").Float()))
})
events.On("wheel", js.Document(), func(evt js.Value) {
m.handleWheel(float32(evt.Get("deltaY").Float()))
})
return m
}
New
New creates a Manager without wiring event listeners.
Returns
func New() *Manager
{ return newManager() }
TestKeyBinding
Parameters
func TestKeyBinding(t *testing.T)
{
m := New()
m.BindKey("jump", "Space")
m.handleKeyDown("Space")
if !m.IsActive("jump") {
t.Fatalf("action not active on key down")
}
m.handleKeyUp("Space")
if m.IsActive("jump") {
t.Fatalf("action still active after key up")
}
}
TestDragRect
Parameters
func TestDragRect(t *testing.T)
{
m := New()
m.handleMouseDown(0, 10, 20)
m.handleMouseMove(30, 40)
start, end, dragging := m.DragRect()
if !dragging {
t.Fatalf("expected dragging state")
}
if start != (math.Vec2{X: 10, Y: 20}) || end != (math.Vec2{X: 30, Y: 40}) {
t.Fatalf("unexpected drag rect %v %v", start, end)
}
m.handleMouseUp(0, 30, 40)
_, _, dragging = m.DragRect()
if dragging {
t.Fatalf("drag state not cleared")
}
}
TestCameraControls
Parameters
func TestCameraControls(t *testing.T)
{
m := New()
m.BindMouse("pan", 1)
m.handleMouseDown(1, 0, 0)
m.handleMouseMove(5, -5)
cam := m.Camera()
if cam.Position != (math.Vec2{X: 5, Y: -5}) {
t.Fatalf("pan not applied, got %v", cam.Position)
}
m.handleWheel(-120)
cam = m.Camera()
if cam.Zoom <= 1 {
t.Fatalf("zoom not applied, got %v", cam.Zoom)
}
m.BindMouse("rotate", 2)
m.handleMouseDown(2, 0, 0)
m.handleMouseMove(10, 0)
cam = m.Camera()
if cam.Rotation == 0 {
t.Fatalf("rotation not applied")
}
}