randomLang
by mcoirad
HTML
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js"></script>
<div id="canvas"></div>
CSS
body { background: #f5f5f5; }
#canvas { margin: 20px auto; width: 600px; height: 600px; border: 1px solid #ccc; }
JavaScript
const draw = SVG().addTo("#canvas").size(600, 600)
const gridSize = 6
const cellSize = 100
const glyphs = []
function perturbPoint([x, y]) {
return [x + Math.random() * 20 - 10, y + Math.random() * 20 - 10]
}
function midPoint([x1, y1], [x2, y2]) {
return [(x1 + x2) / 2, (y1 + y2) / 2]
}
function pickTwoPoints(points) {
const a = points[Math.floor(Math.random() * points.length)]
let b = points[Math.floor(Math.random() * points.length)]
while (a === b) b = points[Math.floor(Math.random() * points.length)]
return [a, b]
}
function pickTwoPointsFromSegments(segments) {
const flat = segments.flat()
return pickTwoPoints(flat)
}
function generateBaseShape(width = 60, height = 60) {
const options = ["circle", "square", "triangle", "line"]
const choice = options[Math.floor(Math.random() * options.length)]
const halfW = width / 2
const halfH = height / 2
switch (choice) {
case "circle": {
const r = Math.min(halfW, halfH)
return {
type: "arcCircle",
segments: [
{ start: [0, -r], end: [r, 0], visible: true },
{ start: [r, 0], end: [0, r], visible: true },
{ start: [0, r], end: [-r, 0], visible: true },
{ start: [-r, 0], end: [0, -r], visible: true },
],
}
}
case "square":
return {
type: "polygon",
points: [
[-halfW, -halfH],
[halfW, -halfH],
[halfW, halfH],
[-halfW, halfH],
],
edges: [true, true, true, true],
}
case "triangle":
return {
type: "polygon",
points: [
[0, -halfH],
[halfW, halfH],
[-halfW, halfH],
],
edges: [true, true, true],
}
case "line":
return {
type: "lines",
segments: [
[
[-halfW, 0],
[halfW, 0],
],
],
}
...