lib/BasicShapes.js
import * as BC from './BasicCanvas.js';
export const rectangle = (point, w, h = null, fill = null, stroke = null) => shape => {
const f = fill || shape.canvas.fill;
const s = stroke || shape.canvas.stroke;
shape.rect(point, w, h ? h : w, f, s);
shape.center = point;
};
export const ellipse = (point, w, h = null, fill = null, stroke = null) => shape => {
const f = fill || shape.canvas.fill;
const s = stroke || shape.canvas.stroke;
shape.ellipse(point, w, h ? h : w, f, s);
shape.center = point;
};
export const line = (origin, position) => shape => {
shape.hollow = true;
shape.vertex(origin);
shape.vertex(position);
};
export const polygon = (centre, sides, radius) => shape => {
sides = Math.abs(sides);
const exterior = 2 * Math.PI / sides;
for (let partial = -Math.HALF_PI; partial <= Math.TAU - Math.HALF_PI; partial += exterior) {
shape.vertex(
centre.x + radius * Math.cos(partial),
centre.y + radius * Math.sin(partial)
);
}
shape.center = centre;
};
export const star = (point, inner, outer, points) => shape => {
const angle_frac = Math.TAU / points;
const half_angle = angle_frac / 2;
for (let theta = 0; theta < Math.TAU; theta += angle_frac) {
shape.vertex(BC.Polar(outer, theta, point));
shape.vertex(BC.Polar(inner, theta + half_angle, point));
}
shape.close();
shape.center = point;
};
export const polar_line = (mag, angle, origin = BC.Point(0, 0)) => shape => {
shape.vertex(origin);
shape.vertex(BC.Polar(mag, angle, origin));
};
export const arrow = (mag, angle, origin = BC.Point(0, 0), headsize = 1 / 5) => shape => {
shape.hollow = true;
polar_line(mag, angle, origin)(shape);
const arrow_angle = 2.4;
const point = BC.Polar(mag, angle, origin);
shape.vertex(point);
shape.vertex(BC.Polar(mag * headsize, angle - arrow_angle, point));
shape.vertex(point);
shape.vertex(BC.Polar(mag * headsize, angle + arrow_angle, point));
};
export const vector = (point, origin = BC.Point(0, 0), headsize = 1 / 5) => shape => {
shape.hollow = true;
line(origin, point)(shape);
const arrow_angle = 2.4;
const length = point.length(origin);
const angle = point.angle(origin);
shape.vertex(point);
shape.vertex(BC.Polar(length * headsize, angle - arrow_angle, point));
shape.vertex(point);
shape.vertex(BC.Polar(length * headsize, angle + arrow_angle, point));
};
export const grid = (opaque = 40, night = false) => shape => { // Maybe allow arguments to modify how the grid works.
const {canvas} = shape;
const {stretch} = canvas;
canvas.temp(() => {
canvas.stroke_weight = 2;
const base = night ? 255 : 0;
const [light, dark] = [BC.RGBA(base, opaque), BC.RGBA(base, opaque + 40)];
const x_range = [canvas.corner.x, canvas.corner.x + canvas.width / stretch[0]];
for (let x = Math.floor(Math.min(...x_range));
x <= Math.max(...x_range);
x++) {
canvas.stroke = light;
canvas.render(`x${x}_gridline`, shape => {
shape.vertex(x, canvas.corner.y);
shape.vertex(x, canvas.corner.y + canvas.height / stretch[1]);
});
canvas.stroke = dark;
canvas.render(`x${x}_tick`, shape => {
shape.vertex(x, -3 / stretch[1]);
shape.vertex(x, 3 / stretch[1]);
});
canvas.temp(() => {
canvas.unscale();
canvas.stroke = BC.Color('transparent');
canvas.fill = dark;
canvas.text_align = 'right';
if (x !== 0) {
canvas.text(x, BC.Point(x * stretch[0] + 4, 14));
}
});
}
const y_range = [canvas.corner.y, canvas.corner.y + canvas.height / stretch[1]];
for (let y = Math.floor(Math.min(...y_range));
y <= Math.max(...y_range);
y++) {
canvas.stroke = light;
canvas.render(`y${y}_gridline`, shape => {
shape.vertex(canvas.corner.x, y);
shape.vertex(canvas.corner.x + canvas.width / stretch[0], y);
});
canvas.stroke = dark;
canvas.render(`y${y}_tickline`, shape => {
shape.vertex(-3 / stretch[0], y);
shape.vertex(3 / stretch[0], y);
});
canvas.temp(() => {
canvas.unscale();
canvas.stroke = BC.Color('transparent');
canvas.fill = dark;
canvas.text_align = 'right';
if (y !== 0) {
canvas.text(y, BC.Point(-4, y * stretch[1] + 4));
}
});
}
// Origin
canvas.temp(() => {
canvas.unscale();
canvas.stroke = BC.Color('transparent');
canvas.fill = dark;
canvas.text_align = 'right';
canvas.text('0', BC.Point(-4, 4));
});
canvas.stroke = dark;
canvas.render('x_axis', shape => {
shape.vertex(canvas.corner.x, 0);
shape.vertex(canvas.corner.x + canvas.width / stretch[0], 0);
});
canvas.render('y_axis', shape => {
shape.vertex(0, canvas.corner.y);
shape.vertex(0, canvas.corner.y + canvas.height / stretch[1]);
});
});
};