status-go/protocol/identity/ring/ring.go

92 lines
2.5 KiB
Go

package ring
import (
"bytes"
"fmt"
"image"
"image/png"
"math"
"github.com/fogleman/gg"
"github.com/status-im/status-go/multiaccounts"
)
type Theme int
const (
LightTheme Theme = 1
DarkTheme Theme = 2
)
var (
lightThemeIdenticonRingColors = []string{
"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
"#C2FFFF", "#00F0B6"}
darkThemeIdenticonRingColors = []string{
"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
"#C2FFFF", "#00F0B6"}
)
type DrawRingParam struct {
Theme Theme `json:"theme"`
ColorHash multiaccounts.ColorHash `json:"colorHash"`
ImageBytes []byte `json:"imageBytes"`
Height int `json:"height"`
Width int `json:"width"`
}
func DrawRing(param *DrawRingParam) ([]byte, error) {
var colors []string
switch param.Theme {
case LightTheme:
colors = lightThemeIdenticonRingColors
case DarkTheme:
colors = darkThemeIdenticonRingColors
default:
return nil, fmt.Errorf("unknown theme")
}
dc := gg.NewContext(param.Width, param.Height)
img, _, err := image.Decode(bytes.NewReader(param.ImageBytes))
if err != nil {
return nil, err
}
dc.DrawImage(img, 0, 0)
ringPxSize := math.Max(2.0, float64(param.Width/16.0))
radius := (float64(param.Height) - ringPxSize) / 2
arcPos := 0.0
totalRingUnits := 0
for i := 0; i < len(param.ColorHash); i++ {
totalRingUnits += param.ColorHash[i][0]
}
unitRadLen := 2 * math.Pi / float64(totalRingUnits)
for i := 0; i < len(param.ColorHash); i++ {
dc.SetHexColor(colors[param.ColorHash[i][1]])
dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0]))
dc.SetLineWidth(ringPxSize)
dc.SetLineCapButt()
dc.Stroke()
arcPos += unitRadLen * float64(param.ColorHash[i][0])
}
buf := new(bytes.Buffer)
err = png.Encode(buf, dc.Image())
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}