randomLang4
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 = []
DEFAULT_SIZE = 60
class GlyphPrimitive {
constructor(type, options = {}) {
this.type = type // 'polygon', 'arcCircle', 'lines', 'starburst'
this.points = options.points || []
this.segments = options.segments || []
this.edges = options.edges || [] // also used to track visibility of segments
this.visible = options.visible !== false
this.transform = {
rotate: 0,
center: [0, 0],
translate: [0, 0],
scale: [1, 1]
}
// Apply edges to segments for arcCircle and starburst
if ((type === 'arcCircle' || type === 'starburst') && this.edges.length) {
for (let i = 0; i < this.edges.length && i < this.segments.length; i++) {
this.segments[i].visible = this.edges[i] !== false
}
}
}
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.type === 'polygon' && index < this.edges.length) {
this.edges[index] = false
} else if ((this.type === 'arcCircle' || this.type === 'starburst') && index < this.segments.length) {
this.segments[index].visible = false
this.edges[index] = false
}
}
clone() {
const copy = new GlyphPrimitive(this.type, {
points: JSON.parse(JSON.stringify(this.points)),
segments: JSON.parse(JSON.stringify(this.segments)),
edges: [...this.edges],
visible: this.visible
})
copy.transform = JSON.parse(JSON.stringify(this.transform))
return copy
}
render(group) {
const g = group.group()
g.translate(this.transform.translate[0],...