Merge pull request #124 from mazznoer/conic-gradient
Add conic gradient
This commit is contained in:
commit
af4cd58078
@ -128,7 +128,7 @@ SetFillRule(fillRule FillRule)
|
||||
|
||||
## Gradients & Patterns
|
||||
|
||||
`gg` supports linear and radial gradients and surface patterns. You can also implement your own patterns.
|
||||
`gg` supports linear, radial and conic gradients and surface patterns. You can also implement your own patterns.
|
||||
|
||||
```go
|
||||
SetFillStyle(pattern Pattern)
|
||||
@ -136,6 +136,7 @@ SetStrokeStyle(pattern Pattern)
|
||||
NewSolidPattern(color color.Color)
|
||||
NewLinearGradient(x0, y0, x1, y1 float64)
|
||||
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
|
||||
NewConicGradient(cx, cy, deg float64)
|
||||
NewSurfacePattern(im image.Image, op RepeatOp)
|
||||
```
|
||||
|
||||
|
38
examples/gradient-conic.go
Normal file
38
examples/gradient-conic.go
Normal file
@ -0,0 +1,38 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"github.com/fogleman/gg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dc := gg.NewContext(400, 400)
|
||||
|
||||
grad1 := gg.NewConicGradient(200, 200, 0)
|
||||
grad1.AddColorStop(0.0, color.Black)
|
||||
grad1.AddColorStop(0.5, color.RGBA{255, 215, 0, 255})
|
||||
grad1.AddColorStop(1.0, color.RGBA{255, 0, 0, 255})
|
||||
|
||||
grad2 := gg.NewConicGradient(200, 200, 90)
|
||||
grad2.AddColorStop(0.00, color.RGBA{255, 0, 0, 255})
|
||||
grad2.AddColorStop(0.16, color.RGBA{255, 255, 0, 255})
|
||||
grad2.AddColorStop(0.33, color.RGBA{0, 255, 0, 255})
|
||||
grad2.AddColorStop(0.50, color.RGBA{0, 255, 255, 255})
|
||||
grad2.AddColorStop(0.66, color.RGBA{0, 0, 255, 255})
|
||||
grad2.AddColorStop(0.83, color.RGBA{255, 0, 255, 255})
|
||||
grad2.AddColorStop(1.00, color.RGBA{255, 0, 0, 255})
|
||||
|
||||
dc.SetStrokeStyle(grad1)
|
||||
dc.SetLineWidth(20)
|
||||
dc.DrawCircle(200, 200, 180)
|
||||
dc.Stroke()
|
||||
|
||||
dc.SetFillStyle(grad2)
|
||||
dc.DrawCircle(200, 200, 150)
|
||||
dc.Fill()
|
||||
|
||||
dc.SavePNG("gradient-conic.png")
|
||||
}
|
46
gradient.go
46
gradient.go
@ -164,6 +164,52 @@ func NewRadialGradient(x0, y0, r0, x1, y1, r1 float64) Gradient {
|
||||
return g
|
||||
}
|
||||
|
||||
// Conic Gradient
|
||||
type conicGradient struct {
|
||||
cx, cy float64
|
||||
rotation float64
|
||||
stops stops
|
||||
}
|
||||
|
||||
func (g *conicGradient) ColorAt(x, y int) color.Color {
|
||||
if len(g.stops) == 0 {
|
||||
return color.Transparent
|
||||
}
|
||||
a := math.Atan2(float64(y)-g.cy, float64(x)-g.cx)
|
||||
t := norm(a, -math.Pi, math.Pi) - g.rotation
|
||||
if t < 0 {
|
||||
t += 1
|
||||
}
|
||||
return getColor(t, g.stops)
|
||||
}
|
||||
|
||||
func (g *conicGradient) AddColorStop(offset float64, color color.Color) {
|
||||
g.stops = append(g.stops, stop{pos: offset, color: color})
|
||||
sort.Sort(g.stops)
|
||||
}
|
||||
|
||||
func NewConicGradient(cx, cy, deg float64) Gradient {
|
||||
g := &conicGradient{
|
||||
cx: cx,
|
||||
cy: cy,
|
||||
rotation: normalizeAngle(deg) / 360,
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
func normalizeAngle(t float64) float64 {
|
||||
t = math.Mod(t, 360)
|
||||
if t < 0 {
|
||||
t += 360
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Map value which is in range [a..b] to range [0..1]
|
||||
func norm(value, a, b float64) float64 {
|
||||
return (value - a) * (1.0 / (b - a))
|
||||
}
|
||||
|
||||
func getColor(pos float64, stops stops) color.Color {
|
||||
if pos <= 0.0 || len(stops) == 1 {
|
||||
return stops[0].color
|
||||
|
Loading…
Reference in New Issue
Block a user