github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/examples/ebiten/hover_shadow/main.go (about) 1 package main 2 3 import "os" 4 import "log" 5 import "fmt" 6 import "image" 7 import "image/color" 8 9 import "github.com/hajimehoshi/ebiten/v2" 10 import "github.com/Kintar/etxt" 11 import "golang.org/x/image/math/fixed" 12 13 const HoverText = "Hover me please!" 14 15 type Game struct { 16 txtRenderer *etxt.Renderer 17 focus float64 18 } 19 20 func (self *Game) Layout(w int, h int) (int, int) { return w, h } 21 func (self *Game) Update() error { 22 // calculate target area. in general you don't need to recalculate 23 // this at every frame, but we are being lazy and wasteful here 24 targetArea := self.txtRenderer.SelectionRect(HoverText) 25 w, h := ebiten.WindowSize() 26 tw, th := targetArea.Width.Ceil(), targetArea.Height.Ceil() 27 tRect := image.Rect(w/2-tw/2, h/2-th/2, w/2+tw/2, h/2+th/2) 28 29 // determine if we are inside or outside the hover 30 // area and adjust the "focus" level 31 if image.Pt(ebiten.CursorPosition()).In(tRect) { 32 self.focus += 0.06 33 if self.focus > 1.0 { 34 self.focus = 1.0 35 } 36 } else { 37 self.focus -= 0.06 38 if self.focus < 0.0 { 39 self.focus = 0.0 40 } 41 } 42 return nil 43 } 44 45 func (self *Game) Draw(screen *ebiten.Image) { 46 const MaxOffsetX = 4 // max shadow x offset 47 const MaxOffsetY = 4 // max shadow y offset 48 49 // dark background 50 screen.Fill(color.RGBA{0, 0, 0, 255}) 51 52 // draw text 53 w, h := screen.Size() 54 self.txtRenderer.SetTarget(screen) 55 if self.focus > 0 { 56 self.txtRenderer.SetColor(color.RGBA{255, 0, 255, 128}) // sharp shadow 57 hx := fixed.Int26_6((w/2)*64) + fixed.Int26_6(self.focus*MaxOffsetX*64) 58 hy := fixed.Int26_6((h/2)*64) + fixed.Int26_6(self.focus*MaxOffsetY*64) 59 self.txtRenderer.DrawFract(HoverText, hx, hy) 60 } 61 62 self.txtRenderer.SetColor(color.RGBA{255, 255, 255, 255}) // main color 63 self.txtRenderer.Draw(HoverText, w/2, h/2) 64 } 65 66 func main() { 67 // get font path 68 if len(os.Args) != 2 { 69 msg := "Usage: expects one argument with the path to the font to be used\n" 70 fmt.Fprint(os.Stderr, msg) 71 os.Exit(1) 72 } 73 74 // parse font 75 font, fontName, err := etxt.ParseFontFrom(os.Args[1]) 76 if err != nil { 77 log.Fatal(err) 78 } 79 fmt.Printf("Font loaded: %s\n", fontName) 80 81 // create cache 82 cache := etxt.NewDefaultCache(1024 * 1024 * 1024) // 1GB cache 83 84 // create and configure renderer 85 renderer := etxt.NewStdRenderer() 86 renderer.SetCacheHandler(cache.NewHandler()) 87 renderer.SetSizePx(64) 88 renderer.SetFont(font) 89 renderer.SetAlign(etxt.YCenter, etxt.XCenter) 90 91 // run the game 92 ebiten.SetWindowTitle("etxt/examples/ebiten/hover_shadow") 93 ebiten.SetWindowSize(640, 480) 94 err = ebiten.RunGame(&Game{renderer, 0.0}) 95 if err != nil { 96 log.Fatal(err) 97 } 98 }