mirror of
https://github.com/remko/waforth
synced 2025-01-13 08:01:32 +01:00
thurtle: Batch draw
This commit is contained in:
parent
108de077c9
commit
bc6d68c447
2 changed files with 48 additions and 46 deletions
|
@ -137,8 +137,8 @@ PENUP -500 -180 SETXY PENDOWN
|
|||
name: "Snowflake",
|
||||
isExample: true,
|
||||
program: `
|
||||
850 CONSTANT LENGTH
|
||||
4 CONSTANT DEPTH
|
||||
730 CONSTANT LENGTH
|
||||
6 CONSTANT DEPTH
|
||||
|
||||
: SIDE ( length depth -- )
|
||||
DUP 0= IF
|
||||
|
@ -163,6 +163,7 @@ PENUP -500 -180 SETXY PENDOWN
|
|||
LOOP
|
||||
;
|
||||
|
||||
1 SETPENSIZE
|
||||
SNOWFLAKE
|
||||
`,
|
||||
},
|
||||
|
@ -171,7 +172,7 @@ SNOWFLAKE
|
|||
isExample: true,
|
||||
program: `
|
||||
450 CONSTANT SIZE
|
||||
6 CONSTANT BRANCHES
|
||||
7 CONSTANT BRANCHES
|
||||
|
||||
VARIABLE RND
|
||||
HERE RND !
|
||||
|
@ -186,7 +187,7 @@ HERE RND !
|
|||
;
|
||||
|
||||
: PLANT ( size angle -- )
|
||||
OVER 20 < IF 2DROP EXIT THEN
|
||||
OVER 10 < IF 2DROP EXIT THEN
|
||||
DUP RIGHT
|
||||
OVER FORWARD
|
||||
BRANCHES 0 DO
|
||||
|
@ -199,6 +200,7 @@ HERE RND !
|
|||
;
|
||||
|
||||
PENUP 0 SIZE NEGATE SETXY PENDOWN
|
||||
1 SETPENSIZE
|
||||
SIZE 0 PLANT
|
||||
`,
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
saveProgram,
|
||||
} from "./programs";
|
||||
import Editor from "./Editor";
|
||||
import path from "path";
|
||||
|
||||
function About() {
|
||||
return (
|
||||
|
@ -284,74 +285,46 @@ enum PenState {
|
|||
Down = 1,
|
||||
}
|
||||
|
||||
type Path = {
|
||||
strokeWidth?: number;
|
||||
d: string[];
|
||||
};
|
||||
|
||||
let rotation = 0;
|
||||
let position = { x: 0, y: 0 };
|
||||
let pen = PenState.Down;
|
||||
let visible = true;
|
||||
|
||||
function newPathEl() {
|
||||
pathEl = (
|
||||
<path xmlns="http://www.w3.org/2000/svg" stroke-width="5" d="M 0 0" />
|
||||
);
|
||||
patshEl.appendChild(pathEl);
|
||||
}
|
||||
let paths: Array<Path> = [{ d: [`M${position.x} ${position.y}`] }];
|
||||
|
||||
function reset() {
|
||||
position.x = position.y = 0;
|
||||
rotation = 270;
|
||||
pen = PenState.Down;
|
||||
patshEl.innerHTML = "";
|
||||
newPathEl();
|
||||
outputEl.innerHTML = "";
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
function updateTurtle() {
|
||||
turtleEl.style.display = visible ? "block" : "none";
|
||||
turtleEl.setAttribute(
|
||||
"transform",
|
||||
`rotate(${rotation} ${position.x} ${position.y}) translate(${
|
||||
position.x - 25
|
||||
} ${position.y - 25})`
|
||||
);
|
||||
paths = [{ d: [`M ${position.x} ${position.y}`] }];
|
||||
}
|
||||
|
||||
function rotate(deg: number) {
|
||||
rotation = rotation + deg;
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
function setRotation(deg: number) {
|
||||
rotation = deg;
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
function forward(d: number) {
|
||||
const dx = d * Math.cos((rotation * Math.PI) / 180.0);
|
||||
const dy = d * Math.sin((rotation * Math.PI) / 180.0);
|
||||
pathEl.setAttribute(
|
||||
"d",
|
||||
pathEl.getAttribute("d")! +
|
||||
" " +
|
||||
[pen === PenState.Down ? "l" : "m", dx, dy].join(" ")
|
||||
paths[paths.length - 1].d.push(
|
||||
[pen === PenState.Down ? "l" : "m", dx, dy].join(" ")
|
||||
);
|
||||
|
||||
position.x += dx;
|
||||
position.y += dy;
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
function setXY(x: number, y: number) {
|
||||
pathEl.setAttribute(
|
||||
"d",
|
||||
pathEl.getAttribute("d")! +
|
||||
" " +
|
||||
[pen === PenState.Down ? "l" : "M", x, y].join(" ")
|
||||
paths[paths.length - 1].d.push(
|
||||
[pen === PenState.Down ? "l" : "M", x, y].join(" ")
|
||||
);
|
||||
|
||||
position.x = x;
|
||||
position.y = y;
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
function setPen(s: PenState) {
|
||||
|
@ -359,13 +332,37 @@ function setPen(s: PenState) {
|
|||
}
|
||||
|
||||
function setPenSize(s: number) {
|
||||
newPathEl();
|
||||
pathEl.setAttribute("stroke-width", s + "");
|
||||
paths.push({ d: [`M ${position.x} ${position.y}`], strokeWidth: s });
|
||||
}
|
||||
|
||||
function setVisible(b: boolean) {
|
||||
visible = b;
|
||||
updateTurtle();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Drawing
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function draw() {
|
||||
patshEl.innerHTML = "";
|
||||
for (const path of paths) {
|
||||
const pathEl = (
|
||||
<path
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
d={path.d.join(" ")}
|
||||
stroke-width={(path.strokeWidth ?? 5) + ""}
|
||||
/>
|
||||
);
|
||||
patshEl.appendChild(pathEl);
|
||||
}
|
||||
|
||||
turtleEl.style.display = visible ? "block" : "none";
|
||||
turtleEl.setAttribute(
|
||||
"transform",
|
||||
`rotate(${rotation} ${position.x} ${position.y}) translate(${
|
||||
position.x - 25
|
||||
} ${position.y - 25})`
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -471,6 +468,8 @@ async function run() {
|
|||
forth.onEmit = (c) => outputEl.appendChild(document.createTextNode(c));
|
||||
forth.interpret(editor.getValue());
|
||||
editor.focus();
|
||||
|
||||
draw();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
|
@ -486,5 +485,6 @@ document.addEventListener("keydown", (ev) => {
|
|||
});
|
||||
|
||||
reset();
|
||||
draw();
|
||||
|
||||
loadProgram(DEFAULT_PROGRAM);
|
||||
|
|
Loading…
Reference in a new issue