diff --git a/examples/experiments/shadow_text/draw_path.html b/examples/experiments/shadow_text/draw_path.html
new file mode 100644
index 0000000..29cafe8
--- /dev/null
+++ b/examples/experiments/shadow_text/draw_path.html
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+ Draw Shape with Cursor and Touch
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/experiments/shadow_text/main.go b/examples/experiments/shadow_text/main.go
new file mode 100644
index 0000000..f2c0a9e
--- /dev/null
+++ b/examples/experiments/shadow_text/main.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+ "compress/gzip"
+ "encoding/json"
+ "io"
+ "os"
+
+ "github.com/unixpickle/essentials"
+ "github.com/unixpickle/model3d/model2d"
+)
+
+func main() {
+ path := LoadPath()
+ path = path.Decimate(100)
+ path.SmoothSq(20)
+ path.SavePathSVG("path.svg")
+}
+
+func LoadPath() *model2d.Mesh {
+ f, err := os.Open("path.json.gz")
+ essentials.Must(err)
+ defer f.Close()
+ r, err := gzip.NewReader(f)
+ essentials.Must(err)
+ data, err := io.ReadAll(r)
+ essentials.Must(err)
+
+ var path []struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ }
+ essentials.Must(json.Unmarshal(data, &path))
+
+ res := model2d.NewMesh()
+ for i, point := range path {
+ if i > 0 {
+ res.Add(&model2d.Segment{
+ model2d.XY(path[i-1].X, path[i-1].Y),
+ model2d.XY(point.X, point.Y),
+ })
+ }
+ }
+ return res
+}
diff --git a/examples/experiments/shadow_text/path.json.gz b/examples/experiments/shadow_text/path.json.gz
new file mode 100644
index 0000000..bd6ef15
Binary files /dev/null and b/examples/experiments/shadow_text/path.json.gz differ