Just toying around with RxJS stuff.
A Pen by Michael Russell on CodePen.
<div class="wrapper"> | |
<!-- buttons generated by js --> | |
</div> | |
<script> | |
console.log('from html') | |
</script> |
Just toying around with RxJS stuff.
A Pen by Michael Russell on CodePen.
console.clear() // clear out the console on each save/update in codepen | |
var percussion = new Percussion(); | |
percussion.setAutoScroll(false); | |
percussion.stop(); | |
// ------------ | |
// DOM Helpers | |
// ------------ | |
function childIndexOf(element){ | |
return [].indexOf.call(element.parentNode.children, element); | |
} | |
const createAndAddButton = (function(){ | |
let wrapper = $('.wrapper'); | |
return () => { | |
let btn = $('<button/>'); | |
let indx = wrapper.children().length; | |
btn.attr('data-indx', indx); | |
btn.css({opacity: 0}); | |
btn.html(indx); | |
wrapper.append(btn); | |
return btn; | |
}; | |
}()); | |
// ------------ | |
// RxJS Helpers | |
// ------------ | |
function delegate(wrapper, selector, eventName){ | |
return Rx.Observable.fromEvent( | |
$(wrapper), | |
eventName, | |
e => ({ event:e, delegate:e.target.closest(selector) }) | |
).filter(x => x.delegate !== null); | |
} | |
// Generate a stream of numbers from an array and then randomize them. | |
const correctSequence$ = Rx.Observable | |
.fromArray(_.shuffle(_.range(0, 6))); | |
percussion.addStream(correctSequence$); | |
// Hold streams within array to retrieve length later on | |
const correctSequenceArray$ = correctSequence$.toArray(); | |
// log sequence as array to console (to get answer...) | |
correctSequenceArray$ | |
.subscribe(n => console.log(n)); | |
// build out button UI | |
correctSequence$.forEach(createAndAddButton); | |
const animation$ = correctSequence$ | |
.flatMap( (itemIndx, indx) => { | |
let elm = $('.wrapper').children().eq(itemIndx); | |
return Rx.Observable.fromPromise( | |
$.when(elm.delay(indx * 750).fadeTo(500, 1)) | |
); | |
}).share(); | |
percussion.addStream(animation$); | |
// On the last animation trigger the done. | |
animation$.last() | |
.subscribe(()=>console.log('Animation Stream Completed')); | |
// create a stream of button clicks | |
const buttonClicks$ = delegate('.wrapper', 'button', 'click'); | |
buttonClicks$.subscribe(e => e.delegate.disabled = true); | |
percussion.addStream(buttonClicks$); | |
// map the stream of button clicks to their child index | |
const buttonClicksIndex$ = buttonClicks$ | |
.map(e => childIndexOf(e.delegate)); | |
// buffer the clicks into sets of the array length | |
// then check if the sequence of clicks match the | |
// sequence from array (mapping to a list of true/false values) | |
const buttonSequence$ = correctSequenceArray$.flatMap(arr => { | |
return buttonClicksIndex$ | |
.windowWithCount(arr.length) | |
.flatMap(btnClick => btnClick.sequenceEqual(correctSequence$)) | |
}); | |
percussion.addStream(buttonSequence$); | |
// Track the number of clicks the user has made and group | |
// them into a set based on length of sequence | |
const buttonsClickCount$ = correctSequenceArray$ | |
.flatMap(arr => buttonClicks$.bufferWithCount(arr.length)); | |
percussion.addStream(buttonsClickCount$); | |
// filter the buffered squence of clicks based on | |
// whether the sequece was successfully entered (filter for 'true') | |
const buttonSequenceCorrect$ = buttonSequence$ | |
.takeUntil(buttonsClickCount$) | |
.filter(equal => equal); | |
percussion.addStream(buttonSequenceCorrect$); | |
// Naming is hard... | |
const sequenceCorrectAndClicks$ = | |
// ZIP!!!! | |
Rx.Observable.zip(buttonSequence$, buttonsClickCount$); | |
percussion.addStream(sequenceCorrectAndClicks$); | |
// array of results | |
// 0: is boolean if squence was correct | |
// 1: is list of the clicks made | |
sequenceCorrectAndClicks$ | |
.subscribe( (results) => { | |
alert(`Sequence correct: ${results[0]}`); | |
results[1].forEach(e => e.delegate.disabled = false); | |
}); |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script> | |
<script src="https://rawgit.com/grisendo/Percussion/master/dist/Percussion.min.js"></script> |
*{ | |
box-sizing: border-box; | |
} | |
html,body{ | |
width: 100%; | |
height: 100%; | |
} | |
body{ | |
padding: 20px; | |
} | |
.wrapper{ | |
height: 100%; | |
display: flex; | |
align-items: center; | |
flex-wrap: wrap; | |
justify-content: center; | |
flex-flow: row wrap; | |
align-content: center; | |
button{ | |
width: 33.333333333%; | |
box-sizing: border-box; | |
padding: 20px 0; | |
display: inline-block; | |
} | |
} |