elm/core-js/collage/Line.js

104 lines
2.7 KiB
JavaScript
Raw Normal View History

2012-04-20 03:10:25 +00:00
var Line = function() {
var pair = function(a,b) { return [a,b]; };
var create = function(center, ps, theta, s) {
return { center: center, points: ps, theta: theta, scale: s };
};
//// Construction ////
var line = function(ps) {
var parr = [];
while (ps[0] === "Cons") {
parr.push(pair(ps[1][1], ps[1][2]));
ps = ps[2];
}
return create(pair(0,0), parr, 0, 1);
};
//// Atomize ////
var solid = function(color) { return function(line) { return function(ctx) {
ctx.save();
ctx.beginPath();
ctx.translate(line.center[0], line.center[1]);
ctx.rotate(line.theta);
ctx.scale(line.scale, line.scale);
var points = line.points;
var i = points.length;
ctx.moveTo(points[i-1][0], points[i-1][1]);
while (i--) {
ctx.lineTo(points[i][0], points[i][1]);
}
ctx.strokeStyle = Color.Internal.extract(color);
ctx.stroke();
ctx.restore();
return ctx;
};
};
};
var customLine = function(pattern) {
return function(color) { return function(line) {
if (typeof pattern[0] === "string") {
var temp = [];
while (pattern[0] === "Cons") {
temp.push(pattern[1]);
pattern = pattern[2];
}
pattern = temp;
}
if (pattern.length === 0) { pattern = [8,4]; }
return function(ctx) {
ctx.save();
ctx.beginPath();
ctx.translate(line.center[0], line.center[1]);
ctx.rotate(line.theta);
ctx.scale(line.scale, line.scale);
customLineHelp(ctx, pattern, line.points);
ctx.strokeStyle = Color.Internal.extract(color);
ctx.stroke();
ctx.restore();
return ctx;
};
};
};
};
var customLineHelp = function(ctx, pattern, points) {
var i = points.length - 1;
var x0 = points[i][0], y0 = points[i][1];
var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
var pindex = 0, plen = pattern.length;
var draw = true, segmentLength = pattern[0];
ctx.moveTo(x0,y0);
while (i--) {
x1 = points[i][0]; y1 = points[i][1];
dx = x1 - x0; dy = y1 - y0;
remaining = Math.sqrt(dx * dx + dy * dy);
while (segmentLength <= remaining) {
x0 += dx * segmentLength / remaining;
y0 += dy * segmentLength / remaining;
ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
// update starting position
dx = x1 - x0; dy = y1 - y0;
remaining = Math.sqrt(dx * dx + dy * dy);
// update pattern
draw = !draw;
pindex = (pindex + 1) % plen;
segmentLength = pattern[pindex];
}
if (remaining > 0) {
ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
segmentLength -= remaining;
}
x0 = x1; y0 = y1;
}
};
return {line:line, customLine:customLine, solid:solid,
dashed: customLine([8,4]), dotted: customLine([3,3]) };
}();