Created
September 3, 2013 01:26
-
-
Save krukid/2b79dd1fb6005d3a683c to your computer and use it in GitHub Desktop.
js fiddling - canvas, trigonometry, chaining
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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