randomLang3

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 = []

class GlyphPrimitive {
  constructor(type, options = {}) {
    this.type = type // 'polygon', 'arcCircle', 'lines', 'starburst'
    this.points = options.points || []
    this.segments = options.segments || []
    this.edges = options.edges || [] // for polygons
    this.visible = options.visible !== false
    this.transform = {
      rotate: 0,
      center: [0, 0],
      translate: [0, 0],
      scale: [1, 1]
    }
  }

  rotate(angle, cx = 0, cy = 0) {
    this.transform.rotate += angle
    this.transform.center = [cx, cy]
  }

  translate(dx, dy) {
    this.transform.translate[0] += dx
    this.transform.translate[1] += dy
  }

  scale(sx, sy) {
    this.transform.scale[0] *= sx
    this.transform.scale[1] *= sy
  }

  hideEdge(index) {
    if (this.edges && index < this.edges.length) {
      this.edges[index] = false
    }
  }

  render(group) {
    const g = group.group()
    g.translate(this.transform.translate[0], this.transform.translate[1])
    g.scale(this.transform.scale[0], this.transform.scale[1])
    g.rotate(this.transform.rotate, this.transform.center[0], this.transform.center[1])

    if (!this.visible) return

    const strokeAttrs = { width: 2, color: "#000" }
    const strokeOpts = { ...strokeAttrs, "vector-effect": "non-scaling-stroke" }

    if (this.type === "polygon") {
      for (let i = 0; i < this.points.length; i++) {
        const p1 = this.points[i]
        const p2 = this.points[(i + 1) % this.points.length]
        const visible = this.edges[i] !== false
        g.line(p1[0], p1[1], p2[0], p2[1])
          .stroke({ width: 2, color: visible ? "#000" : "transparent" })
          .attr({ 'vector-effect': 'non-scaling-stroke' })
      }
    }

    if (this.type === "lines") {
      this.segments.forEach(([p1, p2]) => {
        g.line(p1[0], p1[1], p2[0],...