Files
pobounty/gradient.go

80 lines
2.0 KiB
Go

package main
import (
"image"
"image/color"
"github.com/hajimehoshi/ebiten/v2"
)
const (
GRAD_IDX_TOP = 0
GRAD_IDX_BOTTOM = 1
)
func HexToRGBA(hexcolor int) color.RGBA {
return color.RGBA{
R: uint8(hexcolor >> 0x10 & 0xff),
G: uint8(hexcolor >> 0x08 & 0xff),
B: uint8(hexcolor >> 0x00 & 0xff),
A: 0xff,
}
}
type Gradient struct {
Scene *ebiten.Image //our resultant image
target *image.RGBA //raw pixel array
width int
height int
colors []color.RGBA //gradient boundary colors
}
func NewGradient(width, height int) *Gradient {
return &Gradient{
Scene: ebiten.NewImage(width, height),
target: image.NewRGBA(image.Rect(0, 0, width, height)),
width: width,
height: height,
colors: []color.RGBA{HexToRGBA(0xFFFFFF), HexToRGBA(0x000000)},
}
}
func (g *Gradient) SetColors(top, bottom color.RGBA) {
g.colors[GRAD_IDX_TOP] = top
g.colors[GRAD_IDX_BOTTOM] = bottom
g.fillCurrent()
}
// performs linear fill on the currently set gradient values, top to bottom (0 to 1)
func (g *Gradient) fill(top, bottom color.RGBA) {
for y := 0; y < g.height; y++ {
//the percent of our transition informs our blending
percentIn := float64(y) / float64(g.height)
//compute top and bottom blend values as factor of percentage
pTopR := float64(top.R) * (1 - percentIn)
pTopG := float64(top.G) * (1 - percentIn)
pTopB := float64(top.B) * (1 - percentIn)
pBottomR := float64(bottom.R) * (percentIn)
pBottomG := float64(bottom.G) * (percentIn)
pBottomB := float64(bottom.B) * (percentIn)
//perform blending on per pixel row basis
for x := 0; x < g.width; x++ {
pixelIndex := 4 * (g.width*y + x)
g.target.Pix[pixelIndex] = uint8(pTopR + pBottomR)
g.target.Pix[pixelIndex+1] = uint8(pTopG + pBottomG)
g.target.Pix[pixelIndex+2] = uint8(pTopB + pBottomB)
g.target.Pix[pixelIndex+3] = 0xff
}
}
g.Scene.WritePixels(g.target.Pix)
}
// gradient on currently set colors
func (g *Gradient) fillCurrent() {
g.fill(g.colors[GRAD_IDX_TOP], g.colors[GRAD_IDX_BOTTOM])
}