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  }