Skip to content

Commit

Permalink
shadow_text: start working on path generation
Browse files Browse the repository at this point in the history
  • Loading branch information
unixpickle committed Jul 8, 2024
1 parent cd05007 commit eaee4b6
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
100 changes: 100 additions & 0 deletions examples/experiments/shadow_text/draw_path.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!--
Draw a path on a canvas and dump it as JSON.
This code was entirely written by ChatGPT.
-->

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Draw Shape with Cursor and Touch</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
height: 100vh;
justify-content: center;
background-color: #f0f0f0;
}
canvas {
border: 1px solid #000;
}
textarea {
margin-top: 10px;
width: 400px;
height: 100px;
}
</style>
</head>
<body>
<canvas id="drawingCanvas" width="500" height="500"></canvas>
<textarea id="coordinatesOutput" readonly></textarea>

<script>
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
const output = document.getElementById('coordinatesOutput');
let drawing = false;
let coordinates = [];

function getPointerPosition(e) {
if (e.touches) {
return { x: e.touches[0].clientX - canvas.offsetLeft, y: e.touches[0].clientY - canvas.offsetTop };
} else {
return { x: e.offsetX, y: e.offsetY };
}
}

function startDrawing(e) {
drawing = true;
coordinates = [];
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
const pos = getPointerPosition(e);
ctx.moveTo(pos.x, pos.y);
coordinates.push({ x: pos.x, y: pos.y });
}

function draw(e) {
if (drawing) {
const pos = getPointerPosition(e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
coordinates.push({ x: pos.x, y: pos.y });
}
}

function stopDrawing() {
if (drawing) {
drawing = false;
output.value = JSON.stringify(coordinates, null, 2);
}
}

canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseleave', stopDrawing);

canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
startDrawing(e);
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
draw(e);
});
canvas.addEventListener('touchend', (e) => {
e.preventDefault();
stopDrawing();
});
canvas.addEventListener('touchcancel', (e) => {
e.preventDefault();
stopDrawing();
});
</script>
</body>
</html>
45 changes: 45 additions & 0 deletions examples/experiments/shadow_text/main.go
Original file line number Diff line number Diff line change
@@ -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
}
Binary file added examples/experiments/shadow_text/path.json.gz
Binary file not shown.

0 comments on commit eaee4b6

Please sign in to comment.