add pixel hole; move color to common folder

This commit is contained in:
Yongwei Xing 2021-03-11 17:35:03 +08:00
parent 3328f24db7
commit 3275179fc1
24 changed files with 386 additions and 233 deletions

View file

@ -4,7 +4,6 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/jdxyw/generativeart)](https://goreportcard.com/report/github.com/jdxyw/generativeart) [![Go Report Card](https://goreportcard.com/badge/github.com/jdxyw/generativeart)](https://goreportcard.com/report/github.com/jdxyw/generativeart)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jdxyw/generativeart/master/LICENSE) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jdxyw/generativeart/master/LICENSE)
`generativeart` is a `Go` package to generate many kinds of generative art. The goal is to collect some excellent generative art (implemented in `R` or `Processing`), and rewrite them in `Go` again. I would paste the original link at the end of this README(If I remember, you can also submit a PR if you found I missed something.). Currently, it supports the following type. `generativeart` is a `Go` package to generate many kinds of generative art. The goal is to collect some excellent generative art (implemented in `R` or `Processing`), and rewrite them in `Go` again. I would paste the original link at the end of this README(If I remember, you can also submit a PR if you found I missed something.). Currently, it supports the following type.
## Buy me a coffee ## Buy me a coffee
@ -36,6 +35,7 @@ This package is still working in progress. More types would be added. Welcome an
- Noise Line - Noise Line
- Ocean Fish - Ocean Fish
- Circle Loop2 - Circle Loop2
- Pixel Hole
For these kinds of art, the package provides as many parameters to control the appearance. For these kinds of art, the package provides as many parameters to control the appearance.
@ -68,6 +68,7 @@ NewCircleGrid(circleNumMin, circleNumMax int)
NewContourLine(lineNum int) NewContourLine(lineNum int)
NewNoiseLine(n int) NewNoiseLine(n int)
NewCircleLoop2(depth int) NewCircleLoop2(depth int)
NewPixelHole(dotN int)
``` ```
## Docs ## Docs
@ -77,6 +78,7 @@ You could find the docs in the [doc](./docs).
## Examples ## Examples
You could find examples for all types under [example](./example). You could find examples for all types under [example](./example).
## General Options ## General Options
```go ```go
@ -94,6 +96,7 @@ type Options struct {
The `Options` is a global option for the whole `canva`. It includes those general parameters used by different kinds of types, such as `background`, `lineColor`, and `colorScheme`. The `Options` is a global option for the whole `canva`. It includes those general parameters used by different kinds of types, such as `background`, `lineColor`, and `colorScheme`.
For those parameters specified for different kinds of art types, they have their own `struct`. For those parameters specified for different kinds of art types, they have their own `struct`.
## Usage and example ## Usage and example
### Junas ### Junas
@ -206,6 +209,30 @@ func main() {
![](images/colorloop2.png) ![](images/colorloop2.png)
## Pixel Hole
```go
func main() {
rand.Seed(time.Now().Unix())
colors := []color.RGBA{
{0xF9, 0xC8, 0x0E, 0xFF},
{0xF8, 0x66, 0x24, 0xFF},
{0xEA, 0x35, 0x46, 0xFF},
{0x66, 0x2E, 0x9B, 0xFF},
{0x43, 0xBC, 0xCD, 0xFF},
}
c := generativeart.NewCanva(800, 800)
c.SetBackground(common.Black)
c.FillBackground()
c.SetColorSchema(colors)
c.SetIterations(1200)
c.Draw(generativeart.NewPixelHole(60))
c.ToPNG("pixelhole.png")
}
```
![](images/pixelhole.png)
### Silk Smoke ### Silk Smoke
```go ```go
@ -330,7 +357,6 @@ func main() {
![](images/circleloop.png) ![](images/circleloop.png)
### Julia Set ### Julia Set
```go ```go
@ -417,19 +443,20 @@ func main() {
Thanks for the following sites and repos, I got lots of ideas, inspiration, code, and tricks from them. The list would be very long; sorry for forgetting some of them. Thanks for the following sites and repos, I got lots of ideas, inspiration, code, and tricks from them. The list would be very long; sorry for forgetting some of them.
- https://inconvergent.net/ - <https://inconvergent.net/>
- https://fronkonstin.com/ - <https://fronkonstin.com/>
- https://github.com/aschinchon/cyclic-cellular-automata - <https://github.com/aschinchon/cyclic-cellular-automata>
- https://github.com/armdz/ProcessingSketchs - <https://github.com/armdz/ProcessingSketchs>
- https://github.com/Mr-Slesser/Generative-Art-And-Fractals - <https://github.com/Mr-Slesser/Generative-Art-And-Fractals>
- https://github.com/cdr6934/Generative-Processing-Experiments - <https://github.com/cdr6934/Generative-Processing-Experiments>
- https://github.com/pkd2512/inktober2017 - <https://github.com/pkd2512/inktober2017>
- http://blog.dragonlab.de/2015/03/generative-art-week-1 - <http://blog.dragonlab.de/2015/03/generative-art-week-1>
- https://editor.p5js.org/kenekk1/sketches/Ly-5XYvKX - <https://editor.p5js.org/kenekk1/sketches/Ly-5XYvKX>
- http://paulbourke.net/fractals/peterdejong/ - <http://paulbourke.net/fractals/peterdejong/>
- https://editor.p5js.org/kenekk1/sketches/O44Dln5oo - <https://editor.p5js.org/kenekk1/sketches/O44Dln5oo>
- https://openprocessing.org/sketch/1071233 - <https://openprocessing.org/sketch/1071233>
- https://twitter.com/okazz_ - <https://twitter.com/okazz_>
- https://openprocessing.org/sketch/738638 - <https://openprocessing.org/sketch/738638>
- https://openprocessing.org/sketch/1102157 - <https://openprocessing.org/sketch/1102157>
- https://openprocessing.org/sketch/1071233 - <https://openprocessing.org/sketch/1071233>
- <https://openprocessing.org/user/139364>

View file

@ -1,6 +1,9 @@
package common package common
import "math" import (
"image/color"
"math"
)
// Constrain returns a value between a minimum and maximum value. // Constrain returns a value between a minimum and maximum value.
func Constrain(val, low, high float64) float64 { func Constrain(val, low, high float64) float64 {
@ -17,3 +20,13 @@ func Remap(n, start1, stop1, start2, stop2 float64) float64 {
return Constrain(newval, stop2, start2) return Constrain(newval, stop2, start2)
} }
} }
// LerpColor blends two colors to find a third color somewhere between them.
func LerpColor(c1, c2 color.RGBA, ratio float64) color.RGBA {
r := uint8(float64(c1.R)*ratio + float64(c2.R)*(1-ratio))
g := uint8(float64(c1.G)*ratio + float64(c2.G)*(1-ratio))
b := uint8(float64(c1.B)*ratio + float64(c2.B)*(1-ratio))
a := uint8(float64(c1.A)*ratio + float64(c2.A)*(1-ratio))
return color.RGBA{r, g, b, a}
}

View file

@ -1,4 +1,4 @@
package generativeart package common
import "image/color" import "image/color"

View file

@ -137,3 +137,17 @@ cl := generativeart.NewCircleLoop2(7)
``` ```
![](../images/colorloop2.png) ![](../images/colorloop2.png)
## Pixel Hole
`Pixel Hole` draws a hole with colored dots.
### parameters
- dotN: The number of point in each iteration.
```go
ph := generativeart.NewPixelHole(60)
```
![](../images/pixelhole.png)

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,9 +10,9 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Tan) c.SetBackground(common.Tan)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.LightPink) c.SetLineColor(common.LightPink)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2)) c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2))
c.ToPNG("circleline.png") c.ToPNG("circleline.png")

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,9 +10,9 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(common.Black)
c.SetLineWidth(1) c.SetLineWidth(1)
c.SetLineColor(generativeart.Orange) c.SetLineColor(common.Orange)
c.SetAlpha(30) c.SetAlpha(30)
c.SetIterations(1000) c.SetIterations(1000)
c.FillBackground() c.FillBackground()

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -20,7 +21,7 @@ func main() {
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
} }
c := generativeart.NewCanva(1000, 1000) c := generativeart.NewCanva(1000, 1000)
c.SetBackground(generativeart.White) c.SetBackground(common.White)
c.FillBackground() c.FillBackground()
c.SetColorSchema(colors) c.SetColorSchema(colors)
c.Draw(generativeart.NewColorCircle(500)) c.Draw(generativeart.NewColorCircle(500))

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -17,7 +18,7 @@ func main() {
{0xF4, 0x9F, 0x0A, 0xFF}, {0xF4, 0x9F, 0x0A, 0xFF},
} }
c := generativeart.NewCanva(800, 800) c := generativeart.NewCanva(800, 800)
c.SetBackground(generativeart.White) c.SetBackground(common.White)
c.FillBackground() c.FillBackground()
c.SetColorSchema(colors) c.SetColorSchema(colors)
c.Draw(generativeart.NewColorCircle2(30)) c.Draw(generativeart.NewColorCircle2(30))

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -13,7 +14,7 @@ func main() {
c.SetBackground(color.RGBA{230, 230, 230, 255}) c.SetBackground(color.RGBA{230, 230, 230, 255})
c.SetLineWidth(10) c.SetLineWidth(10)
c.SetIterations(15000) c.SetIterations(15000)
c.SetColorSchema(generativeart.Plasma) c.SetColorSchema(common.Plasma)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewDotLine(100, 20, 50, false)) c.Draw(generativeart.NewDotLine(100, 20, 50, false))
c.ToPNG("dotline.png") c.ToPNG("dotline.png")

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,8 +10,8 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.DarkPink[rand.Intn(5)]) c.SetBackground(common.DarkPink[rand.Intn(5)])
c.SetColorSchema(generativeart.DarkPink) c.SetColorSchema(common.DarkPink)
c.Draw(generativeart.NewGirdSquares(24, 10, 0.2)) c.Draw(generativeart.NewGirdSquares(24, 10, 0.2))
c.ToPNG("gsquare.png") c.ToPNG("gsquare.png")
} }

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,10 +10,10 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(common.Black)
c.FillBackground() c.FillBackground()
c.SetColorSchema(generativeart.DarkRed) c.SetColorSchema(common.DarkRed)
c.SetForeground(generativeart.LightPink) c.SetForeground(common.LightPink)
c.Draw(generativeart.NewJanus(10, 0.2)) c.Draw(generativeart.NewJanus(10, 0.2))
c.ToPNG("janus.png") c.ToPNG("janus.png")
} }

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -18,7 +19,7 @@ func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetIterations(800) c.SetIterations(800)
c.SetColorSchema(generativeart.Viridis) c.SetColorSchema(common.Viridis)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5)) c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5))
c.ToPNG("julia.png") c.ToPNG("julia.png")

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,9 +10,9 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Azure) c.SetBackground(common.Azure)
c.SetLineWidth(3) c.SetLineWidth(3)
c.SetLineColor(generativeart.Orange) c.SetLineColor(common.Orange)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewMaze(20)) c.Draw(generativeart.NewMaze(20))
c.ToPNG("maze.png") c.ToPNG("maze.png")

View file

@ -0,0 +1,28 @@
package main
import (
"github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
colors := []color.RGBA{
{0xF9, 0xC8, 0x0E, 0xFF},
{0xF8, 0x66, 0x24, 0xFF},
{0xEA, 0x35, 0x46, 0xFF},
{0x66, 0x2E, 0x9B, 0xFF},
{0x43, 0xBC, 0xCD, 0xFF},
}
c := generativeart.NewCanva(800, 800)
c.SetBackground(common.Black)
c.FillBackground()
c.SetColorSchema(colors)
c.SetIterations(1200)
c.Draw(generativeart.NewPixelHole(60))
c.ToPNG("pixelhole.png")
}

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,7 +10,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Lavender) c.SetBackground(common.Lavender)
c.SetLineWidth(2) c.SetLineWidth(2)
c.SetIterations(150000) c.SetIterations(150000)
c.FillBackground() c.FillBackground()

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -10,7 +11,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(common.MistyRose)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(color.RGBA{ c.SetLineColor(color.RGBA{
R: 122, R: 122,
@ -18,7 +19,7 @@ func main() {
B: 122, B: 122,
A: 30, A: 30,
}) })
c.SetColorSchema(generativeart.Plasma) c.SetColorSchema(common.Plasma)
c.SetIterations(4) c.SetIterations(4)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true))

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -10,7 +11,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.White) c.SetBackground(common.White)
c.FillBackground() c.FillBackground()
c.SetColorSchema([]color.RGBA{ c.SetColorSchema([]color.RGBA{
{0xCF, 0x2B, 0x34, 0xFF}, {0xCF, 0x2B, 0x34, 0xFF},

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,11 +10,11 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(common.Black)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.MediumAquamarine) c.SetLineColor(common.MediumAquamarine)
c.SetAlpha(30) c.SetAlpha(30)
c.SetColorSchema(generativeart.Plasma) c.SetColorSchema(common.Plasma)
c.SetIterations(4) c.SetIterations(4)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false))

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
"time" "time"
) )
@ -9,11 +10,11 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(common.MistyRose)
c.SetLineWidth(10) c.SetLineWidth(10)
c.SetLineColor(generativeart.Orange) c.SetLineColor(common.Orange)
c.SetColorSchema(generativeart.Plasma) c.SetColorSchema(common.Plasma)
c.SetForeground(generativeart.Tomato) c.SetForeground(common.Tomato)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true)) c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true))
c.ToPNG("spiralsquare.png") c.ToPNG("spiralsquare.png")

View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math/rand" "math/rand"
"time" "time"
@ -10,7 +11,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(1600, 1600) c := generativeart.NewCanva(1600, 1600)
c.SetBackground(generativeart.Azure) c.SetBackground(common.Azure)
c.FillBackground() c.FillBackground()
c.SetForeground(color.RGBA{113, 3, 0, 140}) c.SetForeground(color.RGBA{113, 3, 0, 140})
c.SetIterations(4000000) c.SetIterations(4000000)

View file

@ -1,6 +1,7 @@
package generativeart package generativeart
import ( import (
"github.com/jdxyw/generativeart/common"
"image" "image"
"image/color" "image/color"
"image/draw" "image/draw"
@ -37,11 +38,11 @@ func NewCanva(h, w int) *canva {
img: image.NewRGBA(image.Rect(0, 0, h, w)), img: image.NewRGBA(image.Rect(0, 0, h, w)),
// Set some defaults value // Set some defaults value
opts: Options{ opts: Options{
background: Azure, background: common.Azure,
foreground: MistyRose, foreground: common.MistyRose,
lineColor: Tomato, lineColor: common.Tomato,
lineWidth: 3, lineWidth: 3,
colorSchema: Plasma, colorSchema: common.Plasma,
nIters: 20, nIters: 20,
alpha: 255, alpha: 255,
}, },

BIN
images/pixelhole.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

View file

@ -23,7 +23,7 @@ func (nl *noiseLine) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img) ctex := gg.NewContextForRGBA(c.img)
noise := common.NewPerlinNoise() noise := common.NewPerlinNoise()
ctex.SetColor(Black) ctex.SetColor(common.Black)
for i := 0; i < 80; i++ { for i := 0; i < 80; i++ {
x := rand.Float64() * float64(c.width) x := rand.Float64() * float64(c.width)
y := rand.Float64() * float64(c.height) y := rand.Float64() * float64(c.height)

55
pixelhole.go Normal file
View file

@ -0,0 +1,55 @@
package generativeart
import (
"github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math"
"math/rand"
)
type pixelHole struct {
dotN int
noise *common.PerlinNoise
}
// NewPixelHole returns a pixelHole object.
func NewPixelHole(dotN int) *pixelHole {
return &pixelHole{
dotN: dotN,
noise: common.NewPerlinNoise(),
}
}
// Generative draws a pixel hole images.
func (p *pixelHole) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img)
//ctex.Translate(float64(c.width)/2, float64(c.height)/2)
for i := 0.0; i < float64(c.opts.nIters); i += 1.0 {
ctex.Push()
ctex.Translate(float64(c.width)/2, float64(c.height)/2)
p.draw(ctex, c, i)
ctex.Pop()
}
}
func (p *pixelHole) draw(ctex *gg.Context, c *canva, frameCount float64) {
ctex.SetLineWidth(2.0)
c1 := int(frameCount/100.0) % len(c.opts.colorSchema)
c2 := (int(frameCount/100.0) + 1) % len(c.opts.colorSchema)
ratio := frameCount/100 - math.Floor(frameCount/100)
cl := common.LerpColor(c.opts.colorSchema[c1], c.opts.colorSchema[c2], ratio)
for i := 0.0; i < float64(p.dotN); i += 1.0 {
ctex.Push()
ctex.SetColor(cl)
ctex.Rotate(frameCount/(50+10*math.Log(frameCount+1)) + i/20)
dd := frameCount/(5+i) + frameCount/5 + math.Sin(i)*50
ctex.Translate(common.RandomRangeFloat64(dd/2, dd), 0)
x := p.noise.Noise2D(frameCount/50+i/50, 5000)*float64(c.width)/10 + rand.Float64()*float64(c.width)/20
y := p.noise.Noise2D(frameCount/50+i/50, 10000)*float64(c.height)/10 + rand.Float64()*float64(c.height)/20
rr := common.RandomRangeFloat64(1.0, 6-math.Log(frameCount+1)/10)
ctex.DrawEllipse(x, y, rr, rr)
ctex.Fill()
ctex.Pop()
}
}