Skip to content

Instantly share code, notes, and snippets.

@subtleGradient
Created March 23, 2018 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subtleGradient/b2c653918064950d581b3ed3940b934a to your computer and use it in GitHub Desktop.
Save subtleGradient/b2c653918064950d581b3ed3940b934a to your computer and use it in GitHub Desktop.
//https://www.khanacademy.org/computer-programming/bouncy-hat/5273009214128128
var hatY = 0;
var HATY_MAX = 106;
var defaultSpringState = {
enabled: true,
mass: 10,
friction: 3,
stiffness: 120 / 100,
precision: 100,
min: 0.01,
ts: null,
scale: 0, // dynamically figure out scale
speed: 0,
value: 0,
endValue: 0,
};
var calculateSpring = function(state){
var mass = state.mass || defaultSpringState.mass;
var friction = state.friction || defaultSpringState.friction;
var stiffness = state.stiffness || defaultSpringState.stiffness;
var precision = state.precision || defaultSpringState.precision;
var distanceMinimum = state.min || defaultSpringState.min;
var speedMinimum = state.min || defaultSpringState.min;
// var valueTarget = Math.round((state.endValue || defaultSpringState.endValue) * precision) / precision;
var valueTarget = state.endValue || defaultSpringState.endValue;
var value = state.value || defaultSpringState.value;
var speed = state.speed || defaultSpringState.speed;
var scale = state.scale || defaultSpringState.scale;
if (!scale){
var ts = state.ts || Date.now();
state.ts = Date.now();
scale = (state.ts - ts) / 30 || 1;
}
// calculate
var totalDistanceToGo = value - valueTarget;
// stop?
var totalDistanceToGoIsBigEnough = totalDistanceToGo > distanceMinimum && totalDistanceToGo > -distanceMinimum || totalDistanceToGo < distanceMinimum && totalDistanceToGo < -distanceMinimum;
var speedIsBigEnough = speed > speedMinimum && speed > -speedMinimum || speed < speedMinimum && speed < -speedMinimum;
if (!totalDistanceToGoIsBigEnough && !speedIsBigEnough) {
// stop
totalDistanceToGo = 0;
value = valueTarget;
speed = 0;
}
var forceFromDamping = -friction * speed;
var forceFromSpring = -stiffness * totalDistanceToGo;
var forceTotal = forceFromSpring + forceFromDamping;
var acceleration = forceTotal / mass;
// output
state.speed = speed + acceleration * scale;
state.value = value + state.speed;
};
var drawHat = function(){
fill(89, 69, 36);
noStroke();
rect(216, 40, 69, 6);//hat rim
rect(229, 17, 45, 25, 7);//hat
fill(3, 3, 3);
rect(228, 35, 48, 5);
};
var hatSpringState = {
value: 0,
endValue: HATY_MAX,
};
var drawHatAnimated = function(){
pushMatrix();
translate(0, hatY);
calculateSpring(hatSpringState);
hatY = hatSpringState.value;
var hatSquish = 0;
if (hatY > HATY_MAX) {
hatSquish = hatY - HATY_MAX;
//hatY = HATY_MAX;
}
scale(1, 1 + hatSquish / -100);
translate(0, -hatSquish);
drawHat();
popMatrix();
};
var draw = function () {
background(250, 250, 250);
stroke(0, 0, 0);
fill(250, 250, 250);
ellipse(279, 178, 20, 20);//right eye
fill(0, 0, 0);
ellipse(284, 178, 10, 10);//right pupil
noStroke();
fill(0, 250, 229);
rect(150, 149, 130, 75);//body
rect(150, 222, 10, 25, 8);
rect(168, 213, 10, 25, 8);
rect(227, 222, 10, 25, 8);
rect(244, 213, 10, 25, 8);//legs
fill(255, 145, 0);
rect(90, 200, 60, 9);//tail
rect(271, 180, 11, 19, 9);
rect(265, 192, 48, 14, 7);//bill
fill(250, 245, 245);
stroke(0, 0, 0);
ellipse(251, 182, 20, 20);//left eye
fill(0, 0, 0);
ellipse(249, 181, 10, 10);//left pupil
drawHatAnimated();
text("Click the hat to make it bounce.", 13, 24);
};
var mousePressed = function () {
hatSpringState.endValue = 0;
};
var mouseReleased = function () {
hatSpringState.endValue = HATY_MAX;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment