JSFiddle - React, Tailwind, and code Playground
JavaScript
document.body.innerHTML = `
<h1>Remote Art</h1>
<canvas id="art-canvas" width="300" height="300"></canvas
`;
var c = document.getElementById("art-canvas");
var ctx = c.getContext("2d");
function onMessageV6(instruction) {
const variables = {};
const fns = {
drawLine(start, end, color) {
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.lineTo(end.x, end.y);
ctx.color = color;
ctx.stroke();
},
drawCircle(center, radius, color) {
ctx.beginPath();
ctx.arc(center.x, center.y, radius, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
},
lineTo: (...args) => ctx.lineTo(...args),
stroke: () => ctx.stroke(),
do: (...args) => args[args.length - 1],
def: (name, v) => {
variables[name] = v;
}
};
const mapArgsWithValues = (args, values) => {
return args.reduce((res, k, idx) => {
res[k] = values[idx];
return res;
}, {});
};
const parseFnInstruction = (args, body, oldVariables) => {
return (...values) => {
const newVariables = {
...oldVariables,
...mapArgsWithValues(args, values)
};
return parseInstruction(body, newVariables);
};
};
const parseInstruction = (ins, variables) => {
if (variables[ins]) {
// this must be some kind of variable
return variables[ins];
}
if (!Array.isArray(ins)) {
// this must be a primitive argument, like {x: 0 y: 0}
return ins;
}
const [fName, ...args] = ins;
if (fName === "fn") {
return parseFnInstruction(...args, variables);
}
console.log(ins);
const fn = fns[fName] || variables[fName];
return fn(...args.map((arg) => parseInstruction(arg, variables)));
};
console.log(instruction);
parseInstruction(instruction, variables);
}
onMessageV6([
"do",
["drawLine", { x: 0, y: 0 }, { x: 100, y: 100 }, "black"],
["drawCircle", { x: 150, y: 150 }, 50, "red"],
["drawLine", { x: 300, y: 0 }, { x: 200,...