import {eq_vect, resolve_color, set_turtle_color, get_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] = get_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 = 0, maxY = 0, minX = 0, minY = 0 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) set_turtle_color([0, 0, 0, 150]) const view_width = Math.max((maxX - minX) * 1.2, 200) const view_height = Math.max((maxY - minY) * 1.2, 200) 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 ` ${path} ${turtle} ${escape_svg(code)} ` }