Skip to content

Instantly share code, notes, and snippets.

@krukid
Created September 3, 2013 01:26
Show Gist options
  • Save krukid/2b79dd1fb6005d3a683c to your computer and use it in GitHub Desktop.
Save krukid/2b79dd1fb6005d3a683c to your computer and use it in GitHub Desktop.
js fiddling - canvas, trigonometry, chaining
Gfx = (function(window) {
var document = window.document;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var helpers = {
hyp: function(x0, y0, x1, y1) {
return Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
},
sign: function(value) {
if (typeof value == "boolean")
return value ? -1 : 1;
else if (typeof value === "number")
return value < 0 ? -1 : 1;
else
throw "argument error";
},
roundAbout: function(x0, y0, r, n, fn) {
var dA = 2*Math.PI/n;
for (var i = 0; i < n; ++i) {
var a = i * dA;
var x = x0 + r * Math.cos(a);
var y = y0 + r * Math.sin(a);
fn(x, y);
}
},
rotatePoint: function(x0, y0, x, y, a, clockwise) {
var hyp = helpers.hyp(x0, y0, x, y);
var sin = (y - y0) / hyp;
var cos = (x - x0) / hyp;
var a = helpers.sign(sin) * Math.acos(cos) - helpers.sign(clockwise) * a;
return {x: x0 + hyp * Math.cos(a), y: y0 + hyp * Math.sin(a)};
},
countByGap: function(gap, R, r) {
gap += ctx.lineWidth;
var len = 2 * Math.PI * R;
return parseInt((len + gap) / (2*r + gap));
}
};
var _cx0 = 250, _cy0 = 200,
_cx1 = 300, _cy1 = 320,
_g0 = 1, _r0 = 1, _R0 = 100,
_g1 = 1, _r1 = 11;
var methods = {
cross: function(x, y, h) {
ctx.beginPath();
ctx.moveTo(x - h, y - h);
ctx.lineTo(x + h, y + h);
ctx.moveTo(x - h, y + h);
ctx.lineTo(x + h, y - h);
ctx.stroke();
},
create: function() {
container = document.body;
canvas.id = 'the_canvas';
canvas.style.display = 'block';
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
container.appendChild(canvas);
},
setupShadow: function(ox, oy, color, blur) {
ctx.shadowOffsetX = ox;
ctx.shadowOffsetY = oy;
ctx.shadowColor = color;
ctx.shadowBlur = blur;
},
startLine: function() {
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(_cx0, _cy0);
ctx.stroke();
},
startCircle: function() {
ctx.beginPath();
ctx.arc(_cx0, _cy0, 10, 0, 2*Math.PI);
ctx.stroke();
},
joinCurve: function() {
var R = helpers.hyp(_cx0, _cy0, _cx1, _cy1);
var n = helpers.countByGap(_g1, R, _r1);
helpers.roundAbout(_cx0, _cy0, R, n, function(x, y) {
var curvePointX0 = (x - _cx0) * 2 / 3 + _cx0;
var curvePointY0 = (y - _cy0) * 2 / 3 + _cy0;
var curvePoint = helpers.rotatePoint(
_cx0, _cy0, curvePointX0, curvePointY0, Math.PI/6, x < _cx0);
methods.cross(curvePointX0, curvePointY0, 5);
methods.cross(curvePoint.x, curvePoint.y, 5);
ctx.beginPath();
ctx.moveTo(_cx0, _cy0);
ctx.quadraticCurveTo(curvePoint.x, curvePoint.y, x, y);
ctx.stroke();
methods.style({strokeStyle: 'lime'}).cross(x, y, 5);
methods.style({strokeStyle: 'blue'});
});
},
testRoundAbout: function() {
var n = helpers.countByGap(_g0, _R0, _r0);
helpers.roundAbout(_cx1, _cy1, _R0, n, function(x, y) {
ctx.beginPath();
ctx.arc(x, y, _r0, 0, 2*Math.PI);
ctx.stroke();
});
},
previewBreakingPoint: function() {
/*
var R = helpers.hyp(_cx0, _cy0, _cx1, _cy1),
n = helpers.countByGap(_g1, R, _r1);
var dA = 2*Math.PI/n;
for (var i = 0; i < n; ++i) {
var pos = helpers.rotatePoint(_cx0, _cy0, _cx1, _cy1, dA*i, true);
ctx.beginPath();
ctx.arc(pos.x, pos.y, _r1, 0, 2*Math.PI);
ctx.stroke();
}
*/
var R = helpers.hyp(_cx0, _cy0, _cx1, _cy1),
n = helpers.countByGap(_g1, R, _r1);
helpers.roundAbout(_cx0, _cy0, R, n, function(x,y) {
ctx.beginPath();
ctx.arc(x, y, _r1, 0, 2*Math.PI);
ctx.stroke();
});
},
style: function(opt) {
for (var k in opt) {
ctx[k] = opt[k];
}
return methods;
}
};
return methods;
})(window);
Gfx.create();
//Gfx.setupShadow(1, 1, 'green', 5);
//Gfx.startLine();
Gfx.startCircle();
Gfx.testRoundAbout();
Gfx.style({strokeStyle: 'red', lineWidth: 3}).previewBreakingPoint();
Gfx.style({strokeStyle: 'blue'}).joinCurve();
/*
Chaining:
============================
Gfx = (function() {
var f = function(opt) {
f.ctx = ...; // per-chain setup, synchronous
return f.fn;
};
f.fn = {}; // static method storage
return f;
})();
Gfx.fn.doStuff = function() { console.log(arguments); return this };
Gfx().doStuff(1).doStuff(2,3,4)...
~~~~~~~~~~~~~~~~
Gfx().setStyle({strokeStyle: 'red', lineWidth: 5}).joinCurve().resetStyle()
Gfx().setStyle({...}).startLine(1, 1, 5, 5).withStyle({strokeStyle: 'blue'}, function() { this.printText('qwd'); }).moveTo(1,1).lineTo(5,5).bubbleArcByGap(5, 100, function(points) { this.joinCurve(points, x0 < x1, function(points) { this.cross(points).moveTo(points.random()); }) }).etc().etc();
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment