Add conic gradient
This commit is contained in:
parent
ad4d1eafac
commit
c26555283c
@ -128,7 +128,7 @@ SetFillRule(fillRule FillRule)
|
|||||||
|
|
||||||
## Gradients & Patterns
|
## 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
|
```go
|
||||||
SetFillStyle(pattern Pattern)
|
SetFillStyle(pattern Pattern)
|
||||||
@ -136,6 +136,7 @@ SetStrokeStyle(pattern Pattern)
|
|||||||
NewSolidPattern(color color.Color)
|
NewSolidPattern(color color.Color)
|
||||||
NewLinearGradient(x0, y0, x1, y1 float64)
|
NewLinearGradient(x0, y0, x1, y1 float64)
|
||||||
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
|
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
|
||||||
|
NewConicGradient(cx, cy, deg float64)
|
||||||
NewSurfacePattern(im image.Image, op RepeatOp)
|
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
|
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 {
|
func getColor(pos float64, stops stops) color.Color {
|
||||||
if pos <= 0.0 || len(stops) == 1 {
|
if pos <= 0.0 || len(stops) == 1 {
|
||||||
return stops[0].color
|
return stops[0].color
|
||||||
|
Loading…
Reference in New Issue
Block a user