edbit/application/canvas.go

66 lines
1.4 KiB
Go

package application
import (
"image"
"math"
"github.com/hajimehoshi/ebiten/v2"
)
type canvas struct {
x, y int
w, h int
vx, vy float64 // Viewport position
img *ebiten.Image
scale float64
op *ebiten.DrawImageOptions
}
func NewCanvas(w, h int) *canvas {
return &canvas{
x: uiWidth,
y: 0,
w: w,
h: h,
img: ebiten.NewImage(w, h),
scale: 1,
op: &ebiten.DrawImageOptions{},
}
}
func (c *canvas) pixelScreenRect(x, y int) image.Rectangle {
rx, ry := (float64(x)-c.vx)*c.scale, (float64(y)-c.vy)*c.scale
rx += float64(c.x)
ry += float64(c.y)
rxCorner, ryCorner := (float64(x+1)-c.vx)*c.scale, (float64(y+1)-c.vy)*c.scale
rxCorner += float64(c.x)
ryCorner += float64(c.y)
return image.Rect(int(math.Floor(rx)), int(math.Floor(ry)), int(math.Ceil(rxCorner)), int(math.Ceil(ryCorner)))
}
func (c *canvas) screenToCanvas(x, y int) (int, int) {
cx, cy := float64(x-c.x)/c.scale, float64(y-c.y)/c.scale
cx, cy = cx+c.vx, cy+c.vy
return int(cx), int(cy)
}
func (c *canvas) Draw(screen *ebiten.Image) {
// Draw canvas.
c.op.GeoM.Reset()
c.op.GeoM.Scale(c.scale, c.scale)
c.op.GeoM.Translate(float64(c.x), float64(c.y))
c.op.GeoM.Translate(-c.vx*c.scale, -c.vy*c.scale)
screen.DrawImage(c.img, c.op)
// Draw hover outline.
cx, cy := c.screenToCanvas(cursorX, cursorY)
p := c.pixelScreenRect(cx, cy)
c.op.GeoM.Reset()
c.op.GeoM.Translate(float64(p.Min.X), float64(p.Min.Y))
screen.DrawImage(hoverImg, c.op)
}