diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/gifServer.iml b/.idea/gifServer.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/gifServer.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..13a08d3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..b8d4c1d
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module gifServer
+
+go 1.18
diff --git a/lissajous.go b/lissajous.go
new file mode 100644
index 0000000..09c1ee4
--- /dev/null
+++ b/lissajous.go
@@ -0,0 +1,38 @@
+package main
+
+import (
+ "image"
+ "image/color"
+ "image/gif"
+ "io"
+ "math"
+ "math/rand"
+ "time"
+)
+
+var palette = []color.Color{color.White, color.Black}
+
+const (
+ whiteIndex = 0
+ blackIndex = 1
+)
+
+func Lissajous(out io.Writer, cycles int, size int, nframes int, delay int, res float64) {
+ rand.Seed(time.Now().UTC().UnixNano())
+ freq := rand.Float64() * 3.0
+ anim := gif.GIF{LoopCount: nframes}
+ phase := 0.0
+ for i := 0; i < nframes; i++ {
+ rect := image.Rect(0, 0, 2*size+1, 2*size+1)
+ img := image.NewPaletted(rect, palette)
+ for t := 0.0; t < float64(cycles)*2*math.Pi; t += res {
+ x := math.Sin(t)
+ y := math.Sin(t*freq + phase)
+ img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5), blackIndex)
+ }
+ phase += 0.1
+ anim.Delay = append(anim.Delay, delay)
+ anim.Image = append(anim.Image, img)
+ }
+ gif.EncodeAll(out, &anim)
+}
diff --git a/server.go b/server.go
new file mode 100644
index 0000000..07bd3cf
--- /dev/null
+++ b/server.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+ "log"
+ "net/http"
+ "strconv"
+)
+
+var cycles, size, nframes, delay = 5, 100, 64, 8
+var res = 0.001
+
+func main() {
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ cycles, size, nframes, delay, res = parse(r)
+ Lissajous(w, cycles, size, nframes, delay, res)
+ })
+ log.Fatal(http.ListenAndServe("localhost:8000", nil))
+}
+
+func parse(r *http.Request) (int, int, int, int, float64) {
+ q := r.URL.Query()
+ if q.Has("cycles") {
+ var err error
+ cycles, err = strconv.Atoi(q["cycles"][0])
+ if err != nil {
+ panic(err)
+ }
+ }
+ if q.Has("size") {
+ var err error
+ size, err = strconv.Atoi(q["size"][0])
+ if err != nil {
+ panic(err)
+ }
+ }
+ if q.Has("nframes") {
+ var err error
+ nframes, err = strconv.Atoi(q["nframes"][0])
+ if err != nil {
+ panic(err)
+ }
+ }
+ if q.Has("delay") {
+ var err error
+ delay, err = strconv.Atoi(q["delay"][0])
+ if err != nil {
+ panic(err)
+ }
+ }
+ if q.Has("res") {
+ var err error
+ res, err = strconv.ParseFloat(q["res"][0], 64)
+ if err != nil {
+ panic(err)
+ }
+ }
+ return cycles, size, nframes, delay, res
+}