<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap-css@*" data-semver="3.0.0-rc2" rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc2/css/bootstrap.min.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.1.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js" data-semver="1.1.5"></script>
<script src="http://pc035860.github.io/ngQueue/ngQueue.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl" ng-init="asyncDelay = 300">
<a href="https://github.com/pc035860/ngQueue">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub" />
</a>
<div class="container">
<h3>ngQueue demo</h3>
<br />
<div class="row">
<div class="col-xs-4 text-center">
<button type="button" class="btn btn-primary" ng-click="queueSync()">queue sync</button>
</div>
<div class="col-xs-4 text-center">
<button type="button" class="btn btn-success" ng-click="queueAsync()">queue async</button>
</div>
<div class="col-xs-4 text-center">
<button type="button" class="btn btn-danger" ng-click="queueRandom(10)">random x 10</button>
</div>
</div>
<hr />
<div class="view-queue">
<div class="row" ng-repeat="item in vq" ng-animate="{enter: 'ng-enter', leave: 'ng-leave'}">
<div class="col-xs-2 text-right">{{ item[0] }}</div>
<div class="col-xs-10 text-left">
<span class="label" ng-class="{'sync': 'label-primary', 'async': 'label-success'}[item[1]]">{{ item[1] }}</span>
<span ng-if="item[2]">
<small class="countdown-text">
<span ng-hide="item[3]">{{ item[2] }}</span>
<span class="active" ng-if="item[3]" ui-countdown="{{ item[2] }}"></span>
ms
</small>
</span>
</div>
</div>
</div>
</div>
</body>
</html>
var app = angular.module('myApp', ['ngQueue']);
app.directive('uiCountdown', function($window, $timeout) {
return {
restrict: 'EA',
scope: {
startFrom: "@uiCountdown"
},
link: function postLink(scope, iElm, iAttrs) {
var _requestAnimFrame = (function(){
return $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame ||
$window.mozRequestAnimationFrame ||
function( callback ){
$window.setTimeout(callback, 1000 / 60);
};
})(),
_start,
_counter;
scope.$watch('startFrom', function (val) {
if (angular.isDefined(val)) {
_start = _now();
_tick();
}
});
function _now () {
return (new Date()).getTime();
}
function _tick () {
var diff = _now() - _start,
result = Math.max(0, scope.startFrom - diff);
iElm.text(result >>> 0);
if (result > 0) {
_requestAnimFrame(_tick);
}
}
}
};
});
app.controller('MainCtrl', function($scope, $queueFactory, $q, $timeout) {
var _taskId = 1,
// two concurrent tasks available
_queue = $queueFactory(2);
// view queue for demostration
$scope.vq = [];
$scope.queueSync = function () {
var taskId = _taskId++,
obj = [taskId, 'sync'];
$scope.vq.push(obj);
_queue.enqueue(function (vqObj) {
_removeFromVQ(vqObj);
}, null, [obj]);
};
$scope.queueAsync = function () {
var taskId = _taskId++,
duration = (Math.random() * 500 + 600) >>> 0,
obj = [taskId, 'async', duration];
$scope.vq.push(obj);
_queue.enqueue(function (vqObj) {
var dfd = $q.defer();
$timeout(function () {
_removeFromVQ(vqObj);
dfd.resolve();
}, duration);
// start countdown
vqObj.push(true);
return dfd.promise;
}, null, [obj]);
};
$scope.queueRandom = function (itrCount) {
for (var i = 0; i < itrCount; i++) {
if (Math.random() >= 0.5) {
$scope.queueAsync();
}
else {
$scope.queueSync();
}
}
};
// start with 30 random tasks
$scope.queueRandom(30);
function _removeFromVQ(obj) {
$scope.vq.splice($scope.vq.indexOf(obj), 1);
}
});
/* Put your css in here */
.container {
overflow: hidden;
}
.view-queue {
font-size: 22px;
}
.view-queue ul {
list-style-type: none;
margin-left: 0;
padding-left: 0;
}
.view-queue > .row {
overflow: hidden;
height: 41px;
-webkit-animation-duration: 600ms;
-moz-animation-duration: 600ms;
-ms-animation-duration: 600ms;
-o-animation-duration: 600ms;
animation-duration: 600ms;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-transition-timing-function: cubic-bezier(0.390, 0.575, 0.565, 1.000);
-moz-transition-timing-function: cubic-bezier(0.390, 0.575, 0.565, 1.000);
-ms-transition-timing-function: cubic-bezier(0.390, 0.575, 0.565, 1.000);
-o-transition-timing-function: cubic-bezier(0.390, 0.575, 0.565, 1.000);
transition-timing-function: cubic-bezier(0.390, 0.575, 0.565, 1.000); /* easeOutSine */
}
.view-queue .row.ng-enter {
-webkit-animation-name: "grow";
-moz-animation-name: "grow";
-ms-animation-name: "grow";
-o-animation-name: "grow";
animation-name: "grow";
}
.view-queue .row.ng-leave {
-webkit-animation-name: "ungrow";
-moz-animation-name: "ungrow";
-ms-animation-name: "ungrow";
-o-animation-name: "ungrow";
animation-name: "ungrow";
}
.view-queue .countdown-text {
font-size: 12px;
color: #aaa;
}
.view-queue .countdown-text .active {
color: #333;
font-weight: bold;
}
/* miss from the cdn ? */
.label-primary {
background-color: #428bca;
}
.label-primary[href]:hover,
.label-primary[href]:focus {
background-color: #3071a9;
}
@-webkit-keyframes "ungrow" {
from {
height: 41px;
opacity: 1;
}
to {
height: 0px;
opacity: 0;
}
}
@-moz-keyframes "ungrow" {
from {
height: 41px;
opacity: 1;
}
to {
height: 0px;
opacity: 0;
}
}
@-o-keyframes "ungrow" {
from {
height: 41px;
opacity: 1;
}
to {
height: 0px;
opacity: 0;
}
}
@keyframes "ungrow" {
from {
height: 41px;
opacity: 1;
}
to {
height: 0px;
opacity: 0;
}
}
@keyframes "grow" {
from {
height: 0px;
opacity: 0;
}
to {
height: 41px;
opacity: 1;
}
}
@-moz-keyframes grow {
from {
height: 0px;
filter: alpha(opacity=0);
opacity: 0;
}
to {
height: 41px;
filter: alpha(opacity=100);
opacity: 1;
}
}
@-webkit-keyframes "grow" {
from {
height: 0px;
opacity: 0;
}
to {
height: 41px;
opacity: 1;
}
}
@-o-keyframes "grow" {
from {
height: 0px;
filter: alpha(opacity=0);
opacity: 0;
}
to {
height: 41px;
filter: alpha(opacity=100);
opacity: 1;
}
}