110 lines
No EOL
2.9 KiB
JavaScript
110 lines
No EOL
2.9 KiB
JavaScript
|
|
var Shape = function() {
|
|
|
|
var create = function(center, ps, theta, s) {
|
|
return { center: center, points: ps, theta: theta, scale: s };
|
|
};
|
|
|
|
//// Construction ////
|
|
|
|
var polygon = function(ps) { return function(center) {
|
|
var parr = [];
|
|
while (ps[0] === "Cons") {
|
|
parr.push([ps[1][1], ps[1][2]]);
|
|
ps = ps[2];
|
|
}
|
|
center = [center[1], center[2]];
|
|
return create(center, parr, 0, 1);
|
|
};
|
|
};
|
|
var ngon = function(n) { return function(r) { return function(center) {
|
|
var ps = [];
|
|
for (var i = n; i--;) {
|
|
ps.push([r * Math.cos(Math.PI * 2 * i/n),
|
|
r * Math.sin(Math.PI * 2 * i/n)]);
|
|
}
|
|
center = [center[1], center[2]];
|
|
return create(center, ps, 0, 1);
|
|
};
|
|
};
|
|
};
|
|
var rect = function(w) { return function(h) { return function(center) {
|
|
var ps = [[- w/2, - h/2],
|
|
[ w/2, - h/2],
|
|
[ w/2, h/2],
|
|
[- w/2, h/2]];
|
|
center = [center[1], center[2]];
|
|
return create(center, ps, 0, 1);
|
|
};
|
|
};
|
|
};
|
|
var oval = function(w) { return function(h) { return function(center) {
|
|
var ps = [];
|
|
for (var theta = 2 * Math.PI; theta > 0; theta -= Math.PI /50) {
|
|
ps.push([w/2 * Math.cos(theta), h/2 * Math.sin(theta)]);
|
|
}
|
|
center = [center[1], center[2]];
|
|
return create(center, ps, 0, 1);
|
|
};
|
|
};
|
|
};
|
|
|
|
//// Transforms ////
|
|
|
|
var move = function(x) { return function(y) { return function(shape) {
|
|
var newCenter = [x + shape.center[0],y + shape.center[1]];
|
|
return create(newCenter, shape.points, shape.theta, shape.scale);
|
|
};
|
|
};
|
|
};
|
|
var rotate = function(theta) { return function(shape) {
|
|
var newTheta = shape.theta + 2 * Math.PI * theta;
|
|
return create(shape.center, shape.points, newTheta, shape.scale);
|
|
};
|
|
};
|
|
var scale = function(s) { return function(shape) {
|
|
return create(shape.center, shape.points, shape.theta, shape.scale * s);
|
|
};
|
|
};
|
|
|
|
|
|
//// Atomize ////
|
|
|
|
var draw = function(fill) {
|
|
return function(color) { return function(shape) { return function(ctx) {
|
|
ctx.save();
|
|
ctx.translate(shape.center[0], shape.center[1]);
|
|
ctx.rotate(shape.theta);
|
|
ctx.scale(shape.scale, shape.scale);
|
|
ctx.beginPath();
|
|
var points = shape.points;
|
|
ctx.moveTo(points[0][0], points[0][1]);
|
|
for (var i = points.length; i--; ) {
|
|
ctx.lineTo(points[i][0], points[i][1]);
|
|
}
|
|
ctx.closePath();
|
|
if (fill) {
|
|
ctx.fillStyle = Color.Internal.extract(color);
|
|
ctx.fill();
|
|
} else {
|
|
ctx.strokeStyle = Color.Internal.extract(color);
|
|
ctx.stroke();
|
|
}
|
|
ctx.restore();
|
|
return ctx;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
var customOutline = function(p) {
|
|
return function(c) { return function(shape) {
|
|
shape.points.push(shape.points[0]);
|
|
return Line.customLine(p)(c)(shape);
|
|
};
|
|
};
|
|
};
|
|
return {polygon:polygon, ngon:ngon, rect:rect, oval:oval,
|
|
move:move, rotate:rotate, scale:scale,
|
|
filled:draw(true), outlined:draw(false), customOutline:customOutline };
|
|
}(); |