[7] Play Simon! (Final)
New layout and styles, based on http://codepen.io/elrolfe/full/qNbLYO/ Observable sequences adjusted. Next step: do it with CycleJs
by Jaume Vinyes
HTML
<script src="https://cdn.jsdelivr.net/rxjs/4.1.0/rx.all.min.js"></script>
<div class="simon-base">
<div class="button" id="red"></div>
<div class="button" id="blue"></div>
<div class="button" id="yellow"></div>
<div class="button" id="green"></div>
<div id="controls">
<p id="logo">Simon<span id="reg-mark">®</span></p>
<p id="counter"></p>
<button id="start"></button>
</div>
</div>
SCSS
$radius: 500px;
$spacing: 20px;
$button-radius: ($radius / 2) - ($spacing * 1.5);
$control-radius: $radius / 4;
$base-color: #333;
.simon-base {
width: $radius;
height: $radius;
position: relative;
margin: 50px auto;
background-color: $base-color;
border-radius: 50%;
.button {
width: 0;
height: 0;
cursor: pointer;
position: absolute;
border-top: $button-radius solid #fff;
border-left: $button-radius solid transparent;
border-bottom: $button-radius solid transparent;
border-right: $button-radius solid transparent;
border-radius: $button-radius;
-webkit-clip-path: polygon(50% 50%, 100% 0%, 0% 0%);
clip-path: polygon(50% 50%, 100% 0%, 0% 0%);
&#green {
top: $spacing;
left: $spacing;
border-top-color: #2a2;
transform: rotate(-45deg);
&.lit {
border-top-color: #4e4;
}
}
&#yellow {
bottom: $spacing;
left: $spacing;
border-top-color: #aa2;
transform: rotate(-135deg);
&.lit {
border-top-color: #ee4;
}
}
&#red {
top: $spacing;
right: $spacing;
border-top-color: #a33;
transform: rotate(45deg);
&.lit {
border-top-color: #f55;
}
}
&#blue {
bottom: $spacing;
right: $spacing;
border-top-color: #33a;
transform: rotate(135deg);
&.lit {
border-top-color: #55f;
}
}
}
#controls {
width: $control-radius * 2;
height: $control-radius * 2;
box-sizing: border-box;
position: absolute;
top: $control-radius;
left: $control-radius;
background-color: #eee;
border-radius: 50%;
border: $spacing solid $base-color;
font-family: "Droid Sans Mono";
font-size: 12px;
color: #111;
button:focus {
outline: none;
}
#logo {
text-align: center;
font-family: "Sarpanch";
font-size: 45px;
...
JavaScript
// Observables
var restart$= Rx.Observable.fromEvent($("#start"), "click");
var red$ = Rx.Observable.fromEvent($('#red'), 'click').map(1);
var blue$ = Rx.Observable.fromEvent($('#blue'), 'click').map(2);
var green$ = Rx.Observable.fromEvent($('#green'), 'click').map(3);
var yellow$ = Rx.Observable.fromEvent($('#yellow'), 'click').map(4);
var simon = new Rx.ReplaySubject();
// Subscriptions
var simonSubscription;
var userSubscription;
var restartSubscription = restart$.subscribe(o => {
restartSequence();
setCounterText("1");
subscribeToSimon();
launchNewValue();
});
function restartSequence() {
if(simonSubscription != null) simonSubscription.dispose();
if(userSubscription != null) userSubscription.dispose();
simon.onCompleted();
simon = new Rx.ReplaySubject();
}
function subscribeToSimon() {
currentSequence = [];
simonSubscription = getSimonStream().subscribe(
o =>
{
currentSequence.push(o);
switchLight(o);
},
err =>
{
console.log(err);
},
() =>
{
setCounterText("GO")
subscribeToUser();
});
}
function subscribeToUser() {
var userIndex = 0;
var validEntry = false;
userSubscription = getUserStream().subscribe(
o =>
{
var expectedValue = currentSequence[userIndex];
var currentColor = numberToColor(o);
if (currentColor == expectedValue) {
switchLight(currentColor);
validEntry = true;
userIndex++;
}
else {
validEntry = false;
launchError();
userSubscription.dispose();
}
},
err =>
{
console.log(err);
launchError();
},
() =>
{
if (validEntry) {
setCounterText(userIndex + 1);
subscribeToSimon();
launchNewValue();
}
else {
launchError();
}
});
}
function getSimonStream() {
var colorDelay = Rx.Observable.empty().delay(700);
var separator = Rx.Observable.return(0);
var separatorDelay =...