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

  1. Decorate the AST with more juggling properties
    • e.g. throwing & catching styles

  2. Decorate the AST with physical properties
    • e.g. prop's weight & throwing force

  3. Produce animation based on the AST
    • using MatterJS (2d) or WebGL (3d)

Thank you!

Questions, Comments, Tricks?