Created
September 22, 2016 14:40
-
-
Save wyudong/335ed05e00a6f6a91427e36031a846dc to your computer and use it in GitHub Desktop.
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 values = { | |
friction: 0.8, | |
timeStep: 0.01, | |
amount: 15, | |
mass: 2, | |
count: 0 | |
}; | |
values.invMass = 1 / values.mass; | |
var path, springs; | |
var size = view.size * [1.2, 1]; | |
var Spring = function(a, b, strength, restLength) { | |
this.a = a; | |
this.b = b; | |
this.restLength = restLength || 80; | |
this.strength = strength ? strength : 0.55; | |
this.mamb = values.invMass * values.invMass; | |
}; | |
Spring.prototype.update = function() { | |
var delta = this.b - this.a; | |
var dist = delta.length; | |
var normDistStrength = (dist - this.restLength) / (dist * this.mamb) * this.strength; | |
delta.y *= normDistStrength * values.invMass * 0.2; | |
if (!this.a.fixed) this.a.y += delta.y; | |
if (!this.b.fixed) this.b.y -= delta.y; | |
}; | |
function createPath(strength) { | |
var path = new Path({ | |
fillColor: 'black' | |
}); | |
springs = []; | |
for (var i = 0; i <= v alues.amount; i++) { | |
var segment = p ath.add(new Point(i / values.amount, 0.5) * size); | |
var point = s egment.point; | |
if (i == 0 || i == v alues.amount) point.y += s ize.height; | |
point.px = p oint.x; | |
point.py = p oint.y; // The first two and last two points are fixed: | |
point.fixed = i < 2 || i > values.amount - 2; | |
if (i > 0) { | |
var spring = new Spring(segment.previous.point, point, strength); | |
springs.push(spring); | |
} | |
} | |
path.position.x -= size.width / 4; | |
return path; | |
} | |
function onResize() { | |
if (path) path.remove(); | |
size = view.bounds.size * [2, 1]; | |
path = createPath(0.1); | |
} | |
function onMouseMove(event) { | |
var location = path.getNearestLocation(event.point); | |
var segment = location.segment; | |
var point = segment.point; | |
if (!point.fixed && location.distance < size.height / 4) { | |
var y = e vent.point.y; | |
point.y += (y - point.y) / 6; | |
if (segment.previous && !segment.previous.fixed) { | |
var previous = s egment.previous.point; | |
previous.y += (y - previous.y) / 24; | |
} | |
if (segment.next && !segment.next.fixed) { | |
var next = s | |
egment.next.point; | |
next.y += (y - next.y) / 24; | |
} | |
} | |
} | |
function onFrame(event) { | |
updateWave(path); | |
} | |
function updateWave(path) { | |
var force = 1 - values.friction * values.timeStep * values.timeStep; | |
for (var i = 0, l = p ath.segments.length; i < l; i++) { | |
var point = p ath.segments[i].point; | |
var dy = (point.y - point.py) * force; | |
point.py = p oint.y; | |
point.y = M ath.max(point.y + dy, 0); | |
} | |
for (var j = 0, l = s prings.length; j < l; j++) { | |
springs[j].update(); | |
} | |
path.smooth({ | |
type: 'continuous' | |
}); | |
} | |
function | |
onKeyDown(event) { | |
if (event.key == 'space') { | |
path.fullySelected = !path.fullySelected; | |
path.fillColor = p ath.fullySelected ? null : 'black'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment