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],...