Last active
August 29, 2015 14:13
-
-
Save Strikeskids/9f640af465ebd49b0b61 to your computer and use it in GitHub Desktop.
// source http://jsbin.com/finosu
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/1.2.0/math.js"></script> | |
<style id="jsbin-css"> | |
#source { | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas id="main" width="1000" height="500"></canvas> | |
<svg id="source"> | |
<path id="sourcePath" d="m91.5,72c89,-22 219,-82 295,-22c76,60 154,122 77,120c-77,-2 -63,-96 -116,-67c-53,29 -31,85 -23,100c8,15 98,2 122,2c24,0 119,9 119,21c0,12 -60,24 -108,30c-48,6 -143,5 -143.5,5c0.5,0 90.5,8 119.5,19c29,11 124,18 117,46c-7,28 -108,11 -133,9c-25,-2 -109,-7 -109.5,-7c0.5,0 68.5,27 68,27c0.5,0 -188.5,6 -189,6c0.5,0 -19.5,-198 -20,-198c0.5,0 -164.5,-69 -75.5,-91z"/> | |
</svg> | |
<script id="jsbin-javascript"> | |
var ctx, source; | |
var pi2 = 2 * Math.PI | |
var currentFrame; | |
var Circle = function me_Circle(radius, angle, rate) { | |
this.radius = radius | |
this.angle = angle | |
this.rate = rate | |
} | |
Circle.prototype.update = function(delta) { | |
this.angle += delta * pi2 * this.rate / 1000 | |
this.angle %= pi2 | |
} | |
Circle.prototype.main = function(x, y) { | |
return { | |
x: x + Math.cos(this.angle) * this.radius, | |
y: y + Math.sin(this.angle) * this.radius | |
} | |
} | |
var circles = [ | |
] | |
var points = [] | |
var sourcePoints = [] | |
function rev(n, bits) { | |
var reved=0,i=0; | |
for(;i<bits;++i) { | |
reved=(reved<<1)|(n>>i)&1; | |
} | |
return reved; | |
} | |
function bitCount(points) { | |
var bits; | |
for(bits=0,i=1;i<=points;i<<=1,++bits) {} | |
return bits | |
} | |
var center; | |
window.addEventListener('load', function() { | |
ctx = document.getElementById('main').getContext('2d') | |
source = document.getElementById('sourcePath') | |
var points = 256, i, bits = bitCount(points)-1, inc = source.getTotalLength()/(points-1) | |
for (i=0;i<points;++i) { | |
sourcePoints.push(source.getPointAtLength(i*inc)) | |
} | |
var sourceData, trig, lower, upper, lowerIndex, upperIndex, bit, level | |
sourceData = sourcePoints.map(function(point) { | |
return math.complex({re: point.x, im: point.y}) | |
}) | |
sourceData = sourceData.map(function(point, i) { | |
return sourceData[rev(i, bits)] | |
}) | |
for (bit=0;bit<bits;++bit) { | |
var outerSize = (1<<bit), innerSize = (1<<(bits-bit-1)) | |
for (level=0;level<outerSize;++level) { | |
trig = math.complex({r: 1, phi: Math.PI * level / outerSize}) | |
for (i=0;i<innerSize;++i) { | |
lowerIndex = i*2*outerSize + level | |
upperIndex = lowerIndex + outerSize | |
lower = sourceData[lowerIndex] | |
upper = math.multiply(sourceData[upperIndex], trig) | |
sourceData[lowerIndex] = math.add(lower, upper) | |
sourceData[upperIndex] = math.subtract(lower, upper) | |
} | |
} | |
} | |
center = { | |
x: sourceData[0].re/points, | |
y: sourceData[0].im/points | |
} | |
for (i=1;i<points;++i) { | |
var num = sourceData[i].toPolar() | |
circles.push(new Circle(num.r/points, num.phi, (((i+points/2)%points)-points/2)/20)) | |
} | |
circles.sort(function (a, b) { | |
if (a.radius > b.radius) { | |
return -1 | |
} else if (b.radius > a.radius){ | |
return 1 | |
} else { | |
return 0 | |
} | |
}) | |
circles.splice(80) | |
// circles.reverse() | |
window.requestAnimationFrame(frame) | |
}) | |
var frame = function me_frame(timestamp) { | |
var start, prev, progress, change, calls; | |
start = me_frame.start || timestamp | |
prev = me_frame.prev || timestamp | |
progress = timestamp - start | |
change = timestamp - prev | |
me_frame.prev = timestamp | |
var x, y | |
x = center.x | |
y = center.y | |
ctx.clearRect(0, 0, 1000, 500) | |
ctx.fillStyle = '#888' | |
ctx.strokeStyle = '#000' | |
circles.forEach(function(circle) { | |
circle.update(change) | |
ctx.beginPath() | |
ctx.arc(x, y, circle.radius, 0, pi2) | |
var newp = circle.main(x, y) | |
ctx.moveTo(x, y) | |
x = newp.x | |
y = newp.y | |
ctx.lineTo(x, y) | |
ctx.stroke() | |
}) | |
// points.push({x: x, y: y}) | |
ctx.strokeStyle = '#0f0' | |
ctx.beginPath() | |
ctx.moveTo(sourcePoints[0].x, sourcePoints[0].y) | |
sourcePoints.forEach(function(point) { | |
ctx.lineTo(point.x, point.y) | |
}) | |
ctx.stroke() | |
ctx.strokeStyle = 'f00' | |
ctx.fillStyle = '#f00' | |
ctx.beginPath() | |
ctx.arc(x, y, 3, 0, pi2) | |
ctx.fill() | |
// ctx.moveTo(points[0].x, points[0].y) | |
// points.forEach(function(point) { | |
// ctx.lineTo(point.x, point.y) | |
// }) | |
// ctx.stroke() | |
currentFrame = window.requestAnimationFrame(frame) | |
} | |
var stop = function() { | |
window.cancelAnimationFrame(currentFrame) | |
} | |
</script> | |
<script id="jsbin-source-css" type="text/css">#source { | |
display: none; | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">var ctx, source; | |
var pi2 = 2 * Math.PI | |
var currentFrame; | |
var Circle = function me_Circle(radius, angle, rate) { | |
this.radius = radius | |
this.angle = angle | |
this.rate = rate | |
} | |
Circle.prototype.update = function(delta) { | |
this.angle += delta * pi2 * this.rate / 1000 | |
this.angle %= pi2 | |
} | |
Circle.prototype.main = function(x, y) { | |
return { | |
x: x + Math.cos(this.angle) * this.radius, | |
y: y + Math.sin(this.angle) * this.radius | |
} | |
} | |
var circles = [ | |
] | |
var points = [] | |
var sourcePoints = [] | |
function rev(n, bits) { | |
var reved=0,i=0; | |
for(;i<bits;++i) { | |
reved=(reved<<1)|(n>>i)&1; | |
} | |
return reved; | |
} | |
function bitCount(points) { | |
var bits; | |
for(bits=0,i=1;i<=points;i<<=1,++bits) {} | |
return bits | |
} | |
var center; | |
window.addEventListener('load', function() { | |
ctx = document.getElementById('main').getContext('2d') | |
source = document.getElementById('sourcePath') | |
var points = 256, i, bits = bitCount(points)-1, inc = source.getTotalLength()/(points-1) | |
for (i=0;i<points;++i) { | |
sourcePoints.push(source.getPointAtLength(i*inc)) | |
} | |
var sourceData, trig, lower, upper, lowerIndex, upperIndex, bit, level | |
sourceData = sourcePoints.map(function(point) { | |
return math.complex({re: point.x, im: point.y}) | |
}) | |
sourceData = sourceData.map(function(point, i) { | |
return sourceData[rev(i, bits)] | |
}) | |
for (bit=0;bit<bits;++bit) { | |
var outerSize = (1<<bit), innerSize = (1<<(bits-bit-1)) | |
for (level=0;level<outerSize;++level) { | |
trig = math.complex({r: 1, phi: Math.PI * level / outerSize}) | |
for (i=0;i<innerSize;++i) { | |
lowerIndex = i*2*outerSize + level | |
upperIndex = lowerIndex + outerSize | |
lower = sourceData[lowerIndex] | |
upper = math.multiply(sourceData[upperIndex], trig) | |
sourceData[lowerIndex] = math.add(lower, upper) | |
sourceData[upperIndex] = math.subtract(lower, upper) | |
} | |
} | |
} | |
center = { | |
x: sourceData[0].re/points, | |
y: sourceData[0].im/points | |
} | |
for (i=1;i<points;++i) { | |
var num = sourceData[i].toPolar() | |
circles.push(new Circle(num.r/points, num.phi, (((i+points/2)%points)-points/2)/20)) | |
} | |
circles.sort(function (a, b) { | |
if (a.radius > b.radius) { | |
return -1 | |
} else if (b.radius > a.radius){ | |
return 1 | |
} else { | |
return 0 | |
} | |
}) | |
circles.splice(80) | |
// circles.reverse() | |
window.requestAnimationFrame(frame) | |
}) | |
var frame = function me_frame(timestamp) { | |
var start, prev, progress, change, calls; | |
start = me_frame.start || timestamp | |
prev = me_frame.prev || timestamp | |
progress = timestamp - start | |
change = timestamp - prev | |
me_frame.prev = timestamp | |
var x, y | |
x = center.x | |
y = center.y | |
ctx.clearRect(0, 0, 1000, 500) | |
ctx.fillStyle = '#888' | |
ctx.strokeStyle = '#000' | |
circles.forEach(function(circle) { | |
circle.update(change) | |
ctx.beginPath() | |
ctx.arc(x, y, circle.radius, 0, pi2) | |
var newp = circle.main(x, y) | |
ctx.moveTo(x, y) | |
x = newp.x | |
y = newp.y | |
ctx.lineTo(x, y) | |
ctx.stroke() | |
}) | |
// points.push({x: x, y: y}) | |
ctx.strokeStyle = '#0f0' | |
ctx.beginPath() | |
ctx.moveTo(sourcePoints[0].x, sourcePoints[0].y) | |
sourcePoints.forEach(function(point) { | |
ctx.lineTo(point.x, point.y) | |
}) | |
ctx.stroke() | |
ctx.strokeStyle = 'f00' | |
ctx.fillStyle = '#f00' | |
ctx.beginPath() | |
ctx.arc(x, y, 3, 0, pi2) | |
ctx.fill() | |
// ctx.moveTo(points[0].x, points[0].y) | |
// points.forEach(function(point) { | |
// ctx.lineTo(point.x, point.y) | |
// }) | |
// ctx.stroke() | |
currentFrame = window.requestAnimationFrame(frame) | |
} | |
var stop = function() { | |
window.cancelAnimationFrame(currentFrame) | |
}</script></body> | |
</html> |
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
#source { | |
display: none; | |
} |
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
var ctx, source; | |
var pi2 = 2 * Math.PI | |
var currentFrame; | |
var Circle = function me_Circle(radius, angle, rate) { | |
this.radius = radius | |
this.angle = angle | |
this.rate = rate | |
} | |
Circle.prototype.update = function(delta) { | |
this.angle += delta * pi2 * this.rate / 1000 | |
this.angle %= pi2 | |
} | |
Circle.prototype.main = function(x, y) { | |
return { | |
x: x + Math.cos(this.angle) * this.radius, | |
y: y + Math.sin(this.angle) * this.radius | |
} | |
} | |
var circles = [ | |
] | |
var points = [] | |
var sourcePoints = [] | |
function rev(n, bits) { | |
var reved=0,i=0; | |
for(;i<bits;++i) { | |
reved=(reved<<1)|(n>>i)&1; | |
} | |
return reved; | |
} | |
function bitCount(points) { | |
var bits; | |
for(bits=0,i=1;i<=points;i<<=1,++bits) {} | |
return bits | |
} | |
var center; | |
window.addEventListener('load', function() { | |
ctx = document.getElementById('main').getContext('2d') | |
source = document.getElementById('sourcePath') | |
var points = 256, i, bits = bitCount(points)-1, inc = source.getTotalLength()/(points-1) | |
for (i=0;i<points;++i) { | |
sourcePoints.push(source.getPointAtLength(i*inc)) | |
} | |
var sourceData, trig, lower, upper, lowerIndex, upperIndex, bit, level | |
sourceData = sourcePoints.map(function(point) { | |
return math.complex({re: point.x, im: point.y}) | |
}) | |
sourceData = sourceData.map(function(point, i) { | |
return sourceData[rev(i, bits)] | |
}) | |
for (bit=0;bit<bits;++bit) { | |
var outerSize = (1<<bit), innerSize = (1<<(bits-bit-1)) | |
for (level=0;level<outerSize;++level) { | |
trig = math.complex({r: 1, phi: Math.PI * level / outerSize}) | |
for (i=0;i<innerSize;++i) { | |
lowerIndex = i*2*outerSize + level | |
upperIndex = lowerIndex + outerSize | |
lower = sourceData[lowerIndex] | |
upper = math.multiply(sourceData[upperIndex], trig) | |
sourceData[lowerIndex] = math.add(lower, upper) | |
sourceData[upperIndex] = math.subtract(lower, upper) | |
} | |
} | |
} | |
center = { | |
x: sourceData[0].re/points, | |
y: sourceData[0].im/points | |
} | |
for (i=1;i<points;++i) { | |
var num = sourceData[i].toPolar() | |
circles.push(new Circle(num.r/points, num.phi, (((i+points/2)%points)-points/2)/20)) | |
} | |
circles.sort(function (a, b) { | |
if (a.radius > b.radius) { | |
return -1 | |
} else if (b.radius > a.radius){ | |
return 1 | |
} else { | |
return 0 | |
} | |
}) | |
circles.splice(80) | |
// circles.reverse() | |
window.requestAnimationFrame(frame) | |
}) | |
var frame = function me_frame(timestamp) { | |
var start, prev, progress, change, calls; | |
start = me_frame.start || timestamp | |
prev = me_frame.prev || timestamp | |
progress = timestamp - start | |
change = timestamp - prev | |
me_frame.prev = timestamp | |
var x, y | |
x = center.x | |
y = center.y | |
ctx.clearRect(0, 0, 1000, 500) | |
ctx.fillStyle = '#888' | |
ctx.strokeStyle = '#000' | |
circles.forEach(function(circle) { | |
circle.update(change) | |
ctx.beginPath() | |
ctx.arc(x, y, circle.radius, 0, pi2) | |
var newp = circle.main(x, y) | |
ctx.moveTo(x, y) | |
x = newp.x | |
y = newp.y | |
ctx.lineTo(x, y) | |
ctx.stroke() | |
}) | |
// points.push({x: x, y: y}) | |
ctx.strokeStyle = '#0f0' | |
ctx.beginPath() | |
ctx.moveTo(sourcePoints[0].x, sourcePoints[0].y) | |
sourcePoints.forEach(function(point) { | |
ctx.lineTo(point.x, point.y) | |
}) | |
ctx.stroke() | |
ctx.strokeStyle = 'f00' | |
ctx.fillStyle = '#f00' | |
ctx.beginPath() | |
ctx.arc(x, y, 3, 0, pi2) | |
ctx.fill() | |
// ctx.moveTo(points[0].x, points[0].y) | |
// points.forEach(function(point) { | |
// ctx.lineTo(point.x, point.y) | |
// }) | |
// ctx.stroke() | |
currentFrame = window.requestAnimationFrame(frame) | |
} | |
var stop = function() { | |
window.cancelAnimationFrame(currentFrame) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment