import {eq_vect, resolve_color, turtle_color, turtle_radius, rotate, turn_to_deg, command_to_state, turtle_init, background_color, turtle_angle, last} from "./turtle_geometry.js"
function hex (n) {
return n.toString(16).padStart(2, "0")
}
function svg_render_line (prev, curr) {
if (!prev.pendown) return ""
if (eq_vect(prev.position, curr.position)) return ""
const {position: [x1, y1], pencolor, penwidth} = prev
const {position: [x2, y2]} = curr
const [r, g, b, a] = resolve_color(pencolor)
return `
`
}
function escape_svg (svg) {
return svg
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
}
export function extract_ludus (svg) {
const code = svg.split("")[1]?.split("")[0] ?? ""
return code
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, `"`)
.replace(/'/g, `'`)
}
function svg_render_path (states) {
const path = []
for (let i = 1; i < states.length; ++i) {
const prev = states[i - 1]
const curr = states[i]
path.push(svg_render_line(prev, curr))
}
return path.join("")
}
function svg_render_turtle (state) {
if (!state.visible) return ""
const [fr, fg, fb, fa] = turtle_color
const fill_alpha = fa/255
const {heading, pencolor, position: [x, y], pendown, penwidth} = state
const origin = [0, turtle_radius]
const [x1, y1] = origin
const [x2, y2] = rotate(origin, turtle_angle)
const [x3, y3] = rotate(origin, -turtle_angle)
const [pr, pg, pb, pa] = resolve_color(pencolor)
const pen_alpha = pa/255
const ink = pendown ? `` : ""
return `
${ink}
`
}
// TODO: update this to match the new `p5` function
export function svg (commands, code) {
const all_states = {}
for (const command of commands) {
const [turtle_id, _, this_command] = command
let stack = all_states[turtle_id]
if (!stack) {
const new_stack = [turtle_init]
all_states[turtle_id] = new_stack
stack = new_stack
}
const prev_state = last(all_states[turtle_id])
const new_state = command_to_state(prev_state, this_command)
all_states[turtle_id].push(new_state)
}
let maxX = -Infinity, maxY = -Infinity, minX = Infinity, minY = Infinity
for (const states of Object.values(all_states)) {
for (const {position: [x, y]} of states) {
maxX = Math.max(maxX, x)
maxY = Math.max(maxY, y)
minX = Math.min(minX, x)
minY = Math.min(minY, y)
}
}
const [r, g, b] = resolve_color(background_color)
if ((r+g+b)/3 > 128) turtle_color = [0, 0, 0, 150]
const view_width = (maxX - minX) * 1.2
const view_height = (maxY - minY) * 1.2
const margin = Math.max(view_width, view_height) * 0.1
const x_origin = minX - margin
const y_origin = -maxY - margin
let path = ""
let turtle = ""
for (const states of Object.values(all_states)) {
path = path + svg_render_path(states)
turtle = svg_render_turtle(last(states))
}
return `
`
}