Animation for score

This commit is contained in:
2016-02-27 19:43:08 +08:00
parent c59c5eef0d
commit e1306cf35a
5 changed files with 325 additions and 69 deletions
+228 -14
View File
@@ -97,24 +97,24 @@ h1 br {
/* Floating updates */
.update-value {
position: absolute;
right: 1em;
top: 1.42857em;
position: relative;
right: -2em;
top: -1.42857em;
height: 1.42857em;
}
.update-plus {
color: green;
float: left;
right: 5px;
position: absolute;
/*right: -1em;*/
/*top: -1em;*/
position: relative;
}
.update-minus {
color: red;
float: left;
right: 5px;
position: absolute;
/*right: -1em;*/
/*top: -1em;*/
position: relative;
}
#labname {
@@ -135,8 +135,8 @@ h1 br {
}
.col-no-padding {
padding-right: 0;
padding-left: 0;
padding-right: 0px;
padding-left: 0px;
}
.tab-content {
@@ -310,16 +310,21 @@ h1 br {
}
.element {
font-size: 3em;
font-weight: bold;
border: 0px;
padding: 1px;
z-index: 50;
min-width: 50px;
min-height: 50px;
}
.element.empty {
opacity: 0.2;
}
.white-badge.empty {
opacity: 0.2;
opacity: 0;
}
.col-little-padding{
padding-right: 1px;
padding-left: 1px;
}
#observationsContent {
font-size: 24px;
@@ -444,5 +449,214 @@ h1 br {
}
.guess-wrong{
}
/** ng animate **/
.hand.ng-enter,
.hand.ng-leave
{
-webkit-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
position: relative;
display: block;
overflow: hidden;
text-overflow: clip;
white-space:nowrap;
}
.hand.ng-leave.hand.ng-leave-active,
.hand.ng-enter {
opacity: 0;
width: 0px;
height: 0px;
}
.hand.ng-enter.hand.ng-enter-active,
.hand.ng-leave {
opacity: 1;
width: 150px;
height: 30px;
}
.mainline.ng-enter {
-webkit-animation: enter 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
animation: enter 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
display: block;
position: relative;
}
@-webkit-keyframes enter {
from {
opacity: 0;
height: 0px;
top: -70px;
}
75% {
top: 15px;
}
to {
opacity: 1;
height: 30px;
top: 0px;
}
}
@keyframes enter {
from {
opacity: 0;
height: 0px;
top: -70px;
}
75% {
top: 15px;
}
to {
opacity: 1;
height: 30px;
top: 0px;
}
}
/* you can also define the transition style
on the base class as well (.repeat-item) */
.repeat-item.ng-enter,
.repeat-item.ng-leave {
-webkit-transition:0.25s linear all;
transition:0.25s linear all;
}
.repeat-item.ng-enter,
.repeat-item.ng-leave.ng-leave-active {
opacity:0;
}
.repeat-item.ng-leave,
.repeat-item.ng-enter.ng-enter-active {
opacity:1;
}
.add-item.ng-enter {
-webkit-transition:0.25s linear all;
transition:0.25s linear all;
}
.add-item.ng-enter {
opacity:0;
}
.fadein,
.fadeout {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
}
.fadein.ng-hide-remove,
.fadeout.ng-hide-add.ng-hide-add-active {
opacity: 0;
display: block !important;
}
.fadeout.ng-hide-add,
.fadein.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
display: block !important;
}
.mainline.ng-leave {
-webkit-animation: leave 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
animation: leave 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
display: block;
position: relative;
}
@-webkit-keyframes leave {
to {
opacity: 0;
height: 0px;
top: -70px;
}
25% {
top: 15px;
}
from {
opacity: 1;
height: 30px;
top: 0px;
}
}
@keyframes leave {
to {
opacity: 0;
height: 0px;
top: -70px;
}
25% {
top: 15px;
}
from {
opacity: 1;
height: 30px;
top: 0px;
}
}
.add-from-top.ng-enter
{
-webkit-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
position: relative;
display: block;
}
.add-from-top.ng-enter.add-from-top.ng-enter-active {
opacity: 1;
top: 0;
height: 30px;
}
.add-from-top.ng-enter {
opacity: 0;
top: -50px;
height: 0px;
}
.add-from-right.ng-enter
{
-webkit-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
position: relative;
display: block;
}
.add-from-right.ng-enter.add-from-right.ng-enter-active {
opacity: 1;
right: 0;
height: 30px;
}
.add-from-right.ng-enter {
opacity: 0;
right: -50px;
height: 0px;
}
/** It's hard to get rid of the padding on rows because it's meant to compensate for
margin left -15px on rows. So we fix it this way **/
.col-no-padding-xs .row {
margin-left: 0;
margin-right: 0;
}
.col-no-padding .row {
margin-left: 0;
margin-right: 0;
}
+27 -24
View File
@@ -65,7 +65,7 @@
</div>
</nav>
<div id="main-content" class="container-fluid col-no-padding Paired">
<div id="main-content" class="container-fluid Paired">
<div class="row">
<div class="col-md-3 col-md-3s col-lg-2 col-no-padding visible-md-block visible-lg-block">
<div class="panel panel-default">
@@ -81,20 +81,20 @@
<div id="elementContent">
<div class="row" ng-cloak>
<div class="col-md-4" ng-repeat="r in rc.elements" ng-show="rc.isAvailable(r)">
<div class="col-xs-2 col-no-padding " ng-repeat="r in rc.elements|orderBy:'key'" ng-show="rc.isAvailable(r)">
<span ng-show="rc.isAvailable(r)"
id="{{r.key}}"
class="{{r.key}} element element-store {{ r.state.interesting ? 'blink' : '' }} {{r.color}} {{rc.isAvailable(r) ? ' ui-draggable': 'empty'}}"
ng-click="rc.onClick(r,$event)"
data-element="{{r.key}}"
data-drag="rc.isAvailable(r)"
jqyoui-draggable="rc.dragOptions"
data-jqyoui-options="rc.jqyouiDragOptions"
jqyoui-draggable="rc.jqyouiDraggable"
data-jqyoui-options="rc.dataJqyouiOptions"
data-hashkey={{r.$$hashKey}}
>
{{r.key}}
</span>
<span ng-show="r.state.amount > 1" class="{{rc.isAvailable(r) ? '': 'empty'}} white-badge ng-binding">{{r.state.amount}}</span>
<span class="{{rc.isAvailable(r) ? '': 'empty'}} {{r.state.amount > 1? 'white-badge': 'white-badge empty'}} ng-binding">{{r.state.amount}}</span>
</div>
</div>
</div>
@@ -108,14 +108,17 @@
<!-- <input class="hidden-xs" id="labname" value="{{ lc.lab.state.name }}" ng-model="lc.lab.state.name" ng-cloak> -->
<div class="row status" ng-cloak>
<div class="col-xs-12 text-center col-no-padding-xs">
<strong>Score</strong><br>
{{ lc.lab.state.score | niceNumber }}
<div class="update-value" id="update-data"></div>
<div class="{{lc.lab.state.score<0?'bg-danger':''}} animate-increase animate-decrease" ><strong>Score</strong><br>{{ lc.lab.state.score | niceNumber }}</div>
<div class="update-value " ng-model="lc.lab.state.score" cfs-score-change id="update-data"></div>
</div>
</div>
<hr class="hidden-xs">
<hr class="hidden-xs row"></hr>
<div class=""><strong> Which card is next?</strong><br></div>
<div id="detector-holder">
<div id="detector" ng-controller="DetectorController as dc">
@@ -123,13 +126,13 @@
<div id="detector-element-container"
ng-cloak
jqyoui-droppable="dc.dropOptions"
data-jqyoui-options="dc.jqyouiDropOptions"
jqyoui-droppable="dc.jqyouiDroppable"
data-jqyoui-options="dc.dataJqyouiOptions"
data-drop="true"
>
<div class="main-line card-line" id="lastCards">
<div class="row" >
<div class="col-md-1" ng-repeat="r in dc.lastCards | limitTo: -10" ng-cloak>
<div class="col-xs-1 col-no-padding add-from-top" ng-repeat="r in dc.lastCards | limitTo: -10" ng-cloak>
<span
class="{{r.key}} element {{r.color}}"
data-element="{{r.key}}"
@@ -140,18 +143,18 @@
</div>
</div>
</div>
<div class="side-line card-line short-lines" id="incorrectCards">
<div class="side-line card-line short-lines-nup" id="incorrectCards">
<div class="row">
<div ng-repeat="rr in dc.incorrectCards | limitTo: -10" class="col-md-1" ng-cloak>
<div ng-repeat="r in rr| limitTo: -10" class="row">
<div class="col-md-12">
<span
class="{{r.key}} element {{r.color}}"
data-element="{{r.key}}"
data-hashkey={{r.$$hashKey}}
>
{{r.key}}
</span>
<div class="col-md-1 col-no-padding" ng-repeat="rr in dc.incorrectCards | limitTo: -10" ng-cloak>
<div class="row">
<div ng-repeat="r in rr| limitTo: -10" class="col-md-12 col-no-padding add-from-right ">
<span
class="{{r.key}} element {{r.color}}"
data-element="{{r.key}}"
data-hashkey={{r.$$hashKey}}
>
{{r.key}}
</span>
</div>
</div>
</div>
@@ -229,7 +232,7 @@
</li>
</ul> -->
<form class="form-inline hypotheses" ng-submit="uc.guess($event,uc.rules2[uc.guessedIndex])">
<form class="hypotheses" ng-submit="uc.guess($event,uc.rules2[uc.guessedIndex])">
<div class="radio" ng-repeat="rule in uc.rules2">
<label class="{{uc.isGuessed(rule)}}" ng-cloak>
<input type="radio" ng-model="uc.guessedIndex" name="ruleRadios" id="ruleRadios-{{$index}}" value="{{$index}}" class="btn btn-sm btn-default">
+55 -10
View File
@@ -33,6 +33,46 @@ var app = (function () {
// ]);
/**
* Make little score animations when score changes require ng-model="score"
*/
function cfsScoreChange($compile) {
return {
link: function (scope, element, attrs) {
scope.$watch(attrs.ngModel, function (newValue, oldValue) {
console.log('value changed, new value is: ' + newValue, oldValue);
// showUpdateValue
var num = newValue-oldValue;
var formatted = Helpers.formatNumberPostfix(num);
var insert;
if (num > 0) {
insert = angular.element("<div class=''></div>")
.attr("class", "update-plus")
.html("+" + formatted);
} else {
insert = angular.element("<div></div>")
.attr("class", "update-minus")
.html(formatted);
}
// showUpdate
element.append(insert);
insert.animate({
"bottom":"+=30px",
"opacity": 0
}, { duration: 500, complete: function() {
angular.element(this).remove();
}});
});
}
};
};
cfsScoreChange.$inject = ['$compile'];
app.directive('cfsScoreChange', cfsScoreChange);
/**
* Directive to render a rule and bind it's option with select boxes
* This expects ng-model="rule" as an attribute
@@ -40,7 +80,6 @@ var app = (function () {
function cfsRule($compile) {
return {
link: function (scope, element, attrs) {
scope.$eval("$index");
var rule = scope.$eval(attrs.ngModel);
// first generate a select box for each option (using lodash templating)
@@ -161,26 +200,32 @@ var app = (function () {
function ElementController($scope, $compile, game, lab) {
var vm = this;
vm.jqyouiDragOptions = {
revert: true, //"invalid",
vm.dataJqyouiOptions = {
revert: "invalid",
zIndex: 100,
cancel: false,
};
vm.dragOptions = {
vm.jqyouiDraggable = {
containment:'offset',
onStart:'rc.dragStart(r)',
onStop:'rc.dragStop(r)',
animate:true,
};
vm.onClick = function (card) {
// a flag to preven ng-click being fired on drag
if (!card.state.dragged)
// don't click if it was dragged within .222 seconds
// (to prevent double firing)
if (!card.state.lastDragged || new Date()-new Date(card.state.lastDragged)>300)
game.play(card);
else
console.log('clickprevent',card.state.lastDragged);
};
vm.dragStart = function(event, ui,card){
card.state.dragged=true;
card.state.lastDragged=new Date();
console.log('startDrag');
};
vm.dragStop = function(event, ui,card){
card.state.dragged=false;
card.state.lastDragged=new Date();
console.log('endDrag');
};
vm.elements = game.elements;
vm.isVisible = function (item) {
@@ -202,7 +247,7 @@ var app = (function () {
vm.ruleCost = 300;
vm.lastCards = game.lastCards;
vm.incorrectCards = game.incorrectCards;
vm.jqyouiDropOptions = {
vm.dataJqyouiOptions = {
// accept: ".rune",
addClasses: true,
// greedy: true,
@@ -210,7 +255,7 @@ var app = (function () {
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
};
vm.dropOptions={onDrop: 'dc.onDrop'};
vm.jqyouiDroppable={onDrop: 'dc.onDrop',multiple:true};
vm.onDrop = function (event, ui) {
var result = game.onDrop(event, ui, game);
};
+1 -1
View File
@@ -177,7 +177,7 @@ var Game = (function (Helpers, GameObjects, ObjectStorage) {
// deal 2 random cards
_.sample(this.elements).state.amount+=1;
_.sample(this.elements).state.amount+=1;
this.lab.state.score-=1;
this.lab.state.score-=2;
}
return correct;
};
+14 -20
View File
@@ -279,13 +279,13 @@ var Rules = (function functionName(_) {
if (d > 3 && d < 21) return d+'th to last'; // thanks kennebec
switch (d % 10) {
case 1:
return d+" st to last";
return "last";
case 2:
return d+" nd to last";
return d+"nd to last";
case 3:
return d+" rd to last";
return d+"rd to last";
default:
return d+" th to last";
return d+"th to last";
}
};
@@ -326,7 +326,7 @@ var Rules = (function functionName(_) {
]
),
new Rule(
"If last <%= n %><%=nth(n)%> cards value was between <%= min %> and <%= max %> play a card that isn't and vice versa.",
"If <%= lastn(n) %> cards value was between <%= min %> and <%= max %> play a card that isn't and vice versa.",
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - this.options.n];
var property = this.options.property;
@@ -372,19 +372,12 @@ var Rules = (function functionName(_) {
]
),
new Rule(
"Play a card with a value <%= min %> to <%= max %> higher than the value of the last <%=n%><%=nth(n)%> card. The numbers wrap around once they reach the max",
"Play a card with a value <%= min %> to <%= max %> higher than the value of the <%= lastn(n) %> card. The numbers wrap around once they reach the max",
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - this.options.n];
var property = this.options.property;
var lastWasbetween = options.min < lastNCard.value && lastNCard.value < options.max;
if (lastWasbetween)
return chai.expect(card)
.to.have.property('value')
.not.within(options.min, options.max);
else
return chai.expect(card)
.to.have.property('value')
.within(options.min, options.max);
var val = card.value%16;
return chai.expect(val).to.be
.within(lastNCard.value+options.min, lastNCard.value+options.max);
}, {
n: 1,
min: 1,
@@ -423,7 +416,7 @@ var Rules = (function functionName(_) {
new Rule(
"If the last <%= n %><%=nth(n)%> card is an even-valued card, play a <%= evenColor %> card. Otherwise play the other color",
"If the <%= lastn(n) %> card is an even-valued card, play a <%= evenColor %> card. Otherwise play the other color",
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - this.options.n];
var lastWasEven = lastNCard % 2 == 0;
@@ -462,7 +455,7 @@ var Rules = (function functionName(_) {
),
new Rule(
"Play a card that has the same <%= property %> or color as the last <%= n %><%=nth(n)%> card but not both.",
"Play a card that has the same <%= property %> or color as the <%= lastn(n) %> card but not both.",
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - options.n];
var matchesColor = lastNCard.color === card.color;
@@ -492,7 +485,7 @@ var Rules = (function functionName(_) {
),
new Rule(
"If the last <%= n %><%=nth(n)%> card's number is higher than <%= min %>, change <%= property %>, and if lower, keep it the same.",
"If the <%= lastn(n) %> card's number is higher than <%= min %>, change <%= property %>, and if lower, keep it the same.",
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - options.n];
var lastWasHigher = lastNCard.value > options.min;
@@ -537,7 +530,8 @@ var Rules = (function functionName(_) {
]
),
new Rule(
"If the last <%= n %><%=nth(n)%> card was a <%= property %> card, play a higher value card otherwise lower.",
"If the <%= lastn(n) %> card was a <%= property %> card, play a higher value card otherwise lower.",
//TODO what if we have a high card? we can only go higher
function (card, lastCards, allCards, options) {
var lastNCard = lastCards[lastCards.length - options.n];
var lastHadProperty = lastNCard[options.property];