Zoom around tile that is hovered.
Inversed zoom on projection (previously how much smaller the content would be, now it is the magnification).
This commit is contained in:
parent
5c0824bafb
commit
44aef25d34
6
point.go
6
point.go
@ -10,6 +10,8 @@ func (p Point) Add(q Point) Point { return Pt(p.X+q.X, p.Y+q.Y) }
|
||||
|
||||
func (p Point) In(r Rectangle) bool { return r.IsPointInsidePt(p) }
|
||||
|
||||
func (p Point) ToPtF() PointF { return PtF(float32(p.X), float32(p.Y)) }
|
||||
|
||||
type PointF struct {
|
||||
sdl.FPoint
|
||||
}
|
||||
@ -18,6 +20,10 @@ func (p PointF) Add(q PointF) PointF {
|
||||
return PtF(p.X+q.X, p.Y+q.Y)
|
||||
}
|
||||
|
||||
func (p PointF) Mul(f float32) PointF {
|
||||
return PtF(f*p.X, f*p.Y)
|
||||
}
|
||||
|
||||
func (p PointF) Sub(q PointF) PointF { return PtF(p.X-q.X, p.Y-q.Y) }
|
||||
|
||||
func Pt(x, y int32) Point { return Point{sdl.Point{X: x, Y: y}} }
|
||||
|
@ -30,7 +30,7 @@ func (p *projection) mapToScreen(x, y int32) Point {
|
||||
|
||||
func (p *projection) mapToScreenF(x, y float32) Point {
|
||||
translated := PtF(x-p.center.X, y-p.center.Y)
|
||||
return Pt(p.windowCenter.X+int32((translated.X-translated.Y)*64*p.zoomInv), p.windowCenter.Y+int32((translated.X+translated.Y)*32*p.zoomInv))
|
||||
return Pt(p.windowCenter.X+int32((translated.X-translated.Y)*64*p.zoom), p.windowCenter.Y+int32((translated.X+translated.Y)*32*p.zoom))
|
||||
}
|
||||
|
||||
func (p *projection) screenToMap(x, y int32) PointF {
|
||||
@ -39,8 +39,8 @@ func (p *projection) screenToMap(x, y int32) PointF {
|
||||
}
|
||||
|
||||
func (p *projection) screenToMapRel(x, y int32) PointF {
|
||||
normX := p.zoom * float32(x)
|
||||
normY := p.zoom * float32(y)
|
||||
normX := p.zoomInv * float32(x)
|
||||
normY := p.zoomInv * float32(y)
|
||||
return PtF(.5*(p.tileScreenDeltaInv.X*normX+p.tileScreenDeltaInv.Y*normY), .5*(-p.tileScreenDeltaInv.X*normX+p.tileScreenDeltaInv.Y*normY))
|
||||
}
|
||||
|
||||
@ -55,9 +55,9 @@ func (p *projection) screenToTileRect(pos Point) *sdl.Rect {
|
||||
func (p *projection) update(renderer *sdl.Renderer) {
|
||||
p.zoomInv = 1 / p.zoom
|
||||
|
||||
p.tileScreenOffset = Pt(int32(p.zoomInv*64), int32(p.zoomInv*112))
|
||||
p.tileScreenSize = Pt(int32(p.zoomInv*128), int32(p.zoomInv*160))
|
||||
p.tileFitScreenSize = Pt(int32(p.zoomInv*64), int32(p.zoomInv*32))
|
||||
p.tileScreenOffset = Pt(int32(p.zoom*64), int32(p.zoom*112))
|
||||
p.tileScreenSize = Pt(int32(p.zoom*128), int32(p.zoom*160))
|
||||
p.tileFitScreenSize = Pt(int32(p.zoom*64), int32(p.zoom*32))
|
||||
|
||||
windowW, windowH, err := renderer.GetOutputSize()
|
||||
if err != nil {
|
||||
|
@ -53,12 +53,17 @@ func (r *terrainRenderer) Handle(ctx *Context, event sdl.Event) {
|
||||
r.interact.mouseDrag = PtPtr(e.X, e.Y)
|
||||
}
|
||||
case *sdl.MouseWheelEvent:
|
||||
if r.project.windowRect.IsPointInside(e.X, e.Y) {
|
||||
if e.Y > 0 && r.project.zoom > .5 {
|
||||
r.project.zoom *= .5
|
||||
r.project.update(ctx.Renderer)
|
||||
} else if e.Y < 0 && r.project.zoom < 4 {
|
||||
r.project.zoom *= 2
|
||||
if r.hover != nil {
|
||||
zoom := r.project.zoom
|
||||
if e.Y < 0 && r.project.zoom > .25 {
|
||||
zoom *= .5
|
||||
} else if e.Y > 0 && r.project.zoom < 2 {
|
||||
zoom *= 2
|
||||
}
|
||||
if zoom != r.project.zoom {
|
||||
hover := r.hover.ToPtF()
|
||||
r.project.center = hover.Sub(hover.Sub(r.project.center).Mul(r.project.zoom / zoom))
|
||||
r.project.zoom = zoom
|
||||
r.project.update(ctx.Renderer)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user