Juggling and JavaScript
by Mihail Mikov
About me
Senior Full-Stack Engineer at Skyscanner
About me
Hobby Juggler
Why Juggling?!
- It's a lot of fun
- It's relaxing and refreshing
- It's full of algorithms
Why JavaScript?!
- It's on almost every device
- There's a huge community of devs
- I actually like it (。・_・。)
Juggling
- any sort of coordinated object manipulation
- throwing 3 balls
JavaScript: the juggling function
const juggle = function* (hands, props, pattern) { }
Juggling pattern
- a unique series of manipulations
- the shower, the box, mills mess
Siteswap notation
- a numerical notation for recording patterns
- 3, 4, 5, 441, 423, 531, 51
Siteswap rules
- each number represents the "distance" the object moves
- each number tells you how high and in what direction to throw
Siteswap Rules
- 🤹 alternate hands
- 🤹 a - number denotes in which hand the ball will fall
- 🤹 [ab] - numbers in brackets are thrown togather from the same hand
- 🤹 (a,b) - numbers in braces are thrown togather from both hands
- 🤹 ([ab], [cd]) - throwing similatiously from both hands
Cascade - 3
More basic examples
▼
Two in one hand - 40
423
Async fountain - 4
More advanced examples
▼
Shower - 51
Rubenstein's revenge
Juggling with a friend
Juggling with friends
JavaScript: the juggling function
const juggle = function* (hands, props, pattern) { }
JavaScript: alternating hands
const alternate = function* (hands = ['left', 'right']) {
while (true) {
for (let hand of hands) {
yield hand;
}
}
}
JavaScript: shuffling props
const shuffle = function* (props = ['ball', 'club', 'ring']) {
while (true) {
let prop = props.splice(0, 1)[0];
if (!prop) throw new Error('no prop to throw');
let distance = yield prop;
if (props[distance]) throw new Error('multi-catch');
props[distance] = prop;
}
}
Shuffle props state
// stepping through the generator modifies the state
// a sparse array of the props with timing as index
const props = shuffle(['ball', 'club', 'ring']);
// to execute the '531' pattern
// we pass each throw's site-swap to the next function
props.next(5); // yields 'ball';
/* state: */ ['club', 'ring', null, null, 'ball']
props.next(3); // yields 'club';
/* state: */ ['ring', null, 'club', 'ball']
props.next(1); // yields 'ring';
/* state: */ ['ring', 'club', 'ball']
JavaScript: the juggling loop
const juggle = function* (hands, props, pattern) {
ticks = timer();
props = shuffle(props);
hands = alternate(hands);
while (true) {
for (let jthrow of pattern) {
let tick = ticks.next().value;
let hand = hands.next().value;
let prop = props.next(jthrow).value;
yield { tick, hand, prop, jthrow };
}
}
}
JavaScript: the juggling AST
juggle(twoHands, threeBalls, '531');
// results in the following AST
[{
tick: 0,
hand: 'right',
prop: 'Ball 1',
jthrow: 5
}, {
tick: 1,
hand: 'left',
prop: 'Ball 2',
jthrow: 3
}, {
tick: 2,
hand: 'right',
prop: 'Ball 3',
jthrow: 1
}]
There is a lot more to do
- Decorate the AST with more juggling properties
- e.g. throwing & catching styles
- Decorate the AST with physical properties
- e.g. prop's weight & throwing force
- Produce animation based on the AST
- using MatterJS (2d) or WebGL (3d)
Thank you!
Questions, Comments, Tricks?