unable to show AJAX loader while image is being loaded completely - javascript

I am working on a image slider and here is my code so far:
angular
.module('myApp', [])
.controller("imageController", ['$scope', function ($scope) {
var imageArray = [ // dynamic array
'http://s3.amazonaws.com/theoatmeal-img/thumbnails/random_comics.png',
'http://images5.fanpop.com/image/photos/30200000/-random-30240825-200-200.gif',
'https://cdn.tutsplus.com/active/uploads/legacy/tuts/059_QTRandom/Preview/Preview.png'
];
var index = 0; // so as to have the first image displayed when the page is loaded
$scope.showAjaxLoader = true; // show
$scope.url = imageArray[index];
$scope.showAjaxLoader = false; // hide
if(imageArray.length > 0){
$scope.showNext = true;
}
$scope.getPrev = function(){
$scope.showAjaxLoader = true; // show
index--;
$scope.url = imageArray[index];
if(index === 0){
$scope.showPrev = false;
}
$scope.showNext = true;
$scope.showAjaxLoader = false; // hide
};
$scope.getNext = function(){
$scope.showAjaxLoader = true; // show
index++;
$scope.url = imageArray[index];
if(index === imageArray.length-1){
$scope.showNext = false;
}
$scope.showPrev = true;
$scope.showAjaxLoader = false; // hide
};
}]);
img{
width: 100%;
}
button{
position: fixed;
top: calc(50% - 17px);
font-size: 25px;
}
#previous{
left: 0px;
}
#next{
right: 0px;
}
/* AJAX loader */
#circularG{
position:relative;
width:58px;
height:58px;
margin: auto;
}
.circularG{
position:absolute;
background-color:rgb(0,0,0);
width:14px;
height:14px;
border-radius:9px;
-o-border-radius:9px;
-ms-border-radius:9px;
-webkit-border-radius:9px;
-moz-border-radius:9px;
animation-name:bounce_circularG;
-o-animation-name:bounce_circularG;
-ms-animation-name:bounce_circularG;
-webkit-animation-name:bounce_circularG;
-moz-animation-name:bounce_circularG;
animation-duration:1.1s;
-o-animation-duration:1.1s;
-ms-animation-duration:1.1s;
-webkit-animation-duration:1.1s;
-moz-animation-duration:1.1s;
animation-iteration-count:infinite;
-o-animation-iteration-count:infinite;
-ms-animation-iteration-count:infinite;
-webkit-animation-iteration-count:infinite;
-moz-animation-iteration-count:infinite;
animation-direction:normal;
-o-animation-direction:normal;
-ms-animation-direction:normal;
-webkit-animation-direction:normal;
-moz-animation-direction:normal;
}
#circularG_1{
left:0;
top:23px;
animation-delay:0.41s;
-o-animation-delay:0.41s;
-ms-animation-delay:0.41s;
-webkit-animation-delay:0.41s;
-moz-animation-delay:0.41s;
}
#circularG_2{
left:6px;
top:6px;
animation-delay:0.55s;
-o-animation-delay:0.55s;
-ms-animation-delay:0.55s;
-webkit-animation-delay:0.55s;
-moz-animation-delay:0.55s;
}
#circularG_3{
top:0;
left:23px;
animation-delay:0.69s;
-o-animation-delay:0.69s;
-ms-animation-delay:0.69s;
-webkit-animation-delay:0.69s;
-moz-animation-delay:0.69s;
}
#circularG_4{
right:6px;
top:6px;
animation-delay:0.83s;
-o-animation-delay:0.83s;
-ms-animation-delay:0.83s;
-webkit-animation-delay:0.83s;
-moz-animation-delay:0.83s;
}
#circularG_5{
right:0;
top:23px;
animation-delay:0.97s;
-o-animation-delay:0.97s;
-ms-animation-delay:0.97s;
-webkit-animation-delay:0.97s;
-moz-animation-delay:0.97s;
}
#circularG_6{
right:6px;
bottom:6px;
animation-delay:1.1s;
-o-animation-delay:1.1s;
-ms-animation-delay:1.1s;
-webkit-animation-delay:1.1s;
-moz-animation-delay:1.1s;
}
#circularG_7{
left:23px;
bottom:0;
animation-delay:1.24s;
-o-animation-delay:1.24s;
-ms-animation-delay:1.24s;
-webkit-animation-delay:1.24s;
-moz-animation-delay:1.24s;
}
#circularG_8{
left:6px;
bottom:6px;
animation-delay:1.38s;
-o-animation-delay:1.38s;
-ms-animation-delay:1.38s;
-webkit-animation-delay:1.38s;
-moz-animation-delay:1.38s;
}
#keyframes bounce_circularG{
0%{
transform:scale(1);
}
100%{
transform:scale(.3);
}
}
#-o-keyframes bounce_circularG{
0%{
-o-transform:scale(1);
}
100%{
-o-transform:scale(.3);
}
}
#-ms-keyframes bounce_circularG{
0%{
-ms-transform:scale(1);
}
100%{
-ms-transform:scale(.3);
}
}
#-webkit-keyframes bounce_circularG{
0%{
-webkit-transform:scale(1);
}
100%{
-webkit-transform:scale(.3);
}
}
#-moz-keyframes bounce_circularG{
0%{
-moz-transform:scale(1);
}
100%{
-moz-transform:scale(.3);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="imageController">
<!-- AJAX loader -->
<div id="circularG" ng-show='showAjaxLoader'>
<div id="circularG_1" class="circularG"></div>
<div id="circularG_2" class="circularG"></div>
<div id="circularG_3" class="circularG"></div>
<div id="circularG_4" class="circularG"></div>
<div id="circularG_5" class="circularG"></div>
<div id="circularG_6" class="circularG"></div>
<div id="circularG_7" class="circularG"></div>
<div id="circularG_8" class="circularG"></div>
</div>
<!-- Next/Previous buttons -->
<button id='previous' ng-click='getPrev()' ng-init='showPrev=false' ng-show='showPrev'>Prev</button>
<button id='next' ng-click='getNext()' ng-show='showNext'>Next</button>
<!-- image -->
<img src={{url}} />
</div>
</body>
It works fine, except the fact that the AJAX loader is not displayed while the other image is being loaded completely. The problem is that it gets hidden immediately when I set the ng-show to false.
How do I make it to work so that it is shown while the image is being fetched or completely loaded on the webpage?

Whenever an image url changes, a new javascript image object is created, and the image onload event is used to cancel the ajax loader.
Note that after an image was loaded, it is cached by the browser, so the ajax loader will usually appear once for every image. To see the ajax loader again, you'll have to clean the cache.
angular
.module('myApp', [])
.controller("imageController", ['$scope', function ($scope) {
var imageArray = [ // dynamic array
'http://s3.amazonaws.com/theoatmeal-img/thumbnails/random_comics.png',
'http://images5.fanpop.com/image/photos/30200000/-random-30240825-200-200.gif',
'https://cdn.tutsplus.com/active/uploads/legacy/tuts/059_QTRandom/Preview/Preview.png'
];
var index = 0; // so as to have the first image displayed when the page is loaded
showImage(imageArray[index]);
function showImage(url) {
$scope.showAjaxLoader = true; // show
var img = new Image(); // create a new image
img.onload = function () { // create an image onload event handler
$scope.$apply(function () { // don't forget to apply as the event is out of angular digest cycle
$scope.showAjaxLoader = false; // hide when image is loaded
});
};
$scope.url = url;
img.src = url; // assign url to image
}
if (imageArray.length > 0) {
$scope.showNext = true;
}
$scope.getPrev = function () {
index--;
showImage(imageArray[index]);
if (index === 0) {
$scope.showPrev = false;
}
$scope.showNext = true;
};
$scope.getNext = function () {
index++;
showImage(imageArray[index]);
if (index === imageArray.length - 1) {
$scope.showNext = false;
}
$scope.showPrev = true;
};
}
]);
img{
width: 100%;
}
button{
position: fixed;
top: calc(50% - 17px);
font-size: 25px;
}
#previous{
left: 0px;
}
#next{
right: 0px;
}
/* AJAX loader */
#circularG{
position: fixed;
width:58px;
height:58px;
margin: auto;
top: 100px;
left: calc(50% - 29px);
}
.circularG{
position:absolute;
background-color:rgb(0,0,0);
width:14px;
height:14px;
border-radius:9px;
-o-border-radius:9px;
-ms-border-radius:9px;
-webkit-border-radius:9px;
-moz-border-radius:9px;
animation-name:bounce_circularG;
-o-animation-name:bounce_circularG;
-ms-animation-name:bounce_circularG;
-webkit-animation-name:bounce_circularG;
-moz-animation-name:bounce_circularG;
animation-duration:1.1s;
-o-animation-duration:1.1s;
-ms-animation-duration:1.1s;
-webkit-animation-duration:1.1s;
-moz-animation-duration:1.1s;
animation-iteration-count:infinite;
-o-animation-iteration-count:infinite;
-ms-animation-iteration-count:infinite;
-webkit-animation-iteration-count:infinite;
-moz-animation-iteration-count:infinite;
animation-direction:normal;
-o-animation-direction:normal;
-ms-animation-direction:normal;
-webkit-animation-direction:normal;
-moz-animation-direction:normal;
}
#circularG_1{
left:0;
top:23px;
animation-delay:0.41s;
-o-animation-delay:0.41s;
-ms-animation-delay:0.41s;
-webkit-animation-delay:0.41s;
-moz-animation-delay:0.41s;
}
#circularG_2{
left:6px;
top:6px;
animation-delay:0.55s;
-o-animation-delay:0.55s;
-ms-animation-delay:0.55s;
-webkit-animation-delay:0.55s;
-moz-animation-delay:0.55s;
}
#circularG_3{
top:0;
left:23px;
animation-delay:0.69s;
-o-animation-delay:0.69s;
-ms-animation-delay:0.69s;
-webkit-animation-delay:0.69s;
-moz-animation-delay:0.69s;
}
#circularG_4{
right:6px;
top:6px;
animation-delay:0.83s;
-o-animation-delay:0.83s;
-ms-animation-delay:0.83s;
-webkit-animation-delay:0.83s;
-moz-animation-delay:0.83s;
}
#circularG_5{
right:0;
top:23px;
animation-delay:0.97s;
-o-animation-delay:0.97s;
-ms-animation-delay:0.97s;
-webkit-animation-delay:0.97s;
-moz-animation-delay:0.97s;
}
#circularG_6{
right:6px;
bottom:6px;
animation-delay:1.1s;
-o-animation-delay:1.1s;
-ms-animation-delay:1.1s;
-webkit-animation-delay:1.1s;
-moz-animation-delay:1.1s;
}
#circularG_7{
left:23px;
bottom:0;
animation-delay:1.24s;
-o-animation-delay:1.24s;
-ms-animation-delay:1.24s;
-webkit-animation-delay:1.24s;
-moz-animation-delay:1.24s;
}
#circularG_8{
left:6px;
bottom:6px;
animation-delay:1.38s;
-o-animation-delay:1.38s;
-ms-animation-delay:1.38s;
-webkit-animation-delay:1.38s;
-moz-animation-delay:1.38s;
}
#keyframes bounce_circularG{
0%{
transform:scale(1);
}
100%{
transform:scale(.3);
}
}
#-o-keyframes bounce_circularG{
0%{
-o-transform:scale(1);
}
100%{
-o-transform:scale(.3);
}
}
#-ms-keyframes bounce_circularG{
0%{
-ms-transform:scale(1);
}
100%{
-ms-transform:scale(.3);
}
}
#-webkit-keyframes bounce_circularG{
0%{
-webkit-transform:scale(1);
}
100%{
-webkit-transform:scale(.3);
}
}
#-moz-keyframes bounce_circularG{
0%{
-moz-transform:scale(1);
}
100%{
-moz-transform:scale(.3);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="imageController">
<!-- AJAX loader -->
<div id="circularG" ng-show='showAjaxLoader'>
<div id="circularG_1" class="circularG"></div>
<div id="circularG_2" class="circularG"></div>
<div id="circularG_3" class="circularG"></div>
<div id="circularG_4" class="circularG"></div>
<div id="circularG_5" class="circularG"></div>
<div id="circularG_6" class="circularG"></div>
<div id="circularG_7" class="circularG"></div>
<div id="circularG_8" class="circularG"></div>
</div>
<!-- Next/Previous buttons -->
<button id='previous' ng-click='getPrev()' ng-init='showPrev=false' ng-show='showPrev'>Prev</button>
<button id='next' ng-click='getNext()' ng-show='showNext'>Next</button>
<!-- image -->
<img src={{url}} />
</div>
</body>

Here, is the alternate way using angular directive.
https://jsfiddle.net/8drLy2bp/1/
Directive:
angular
.module('myApp', [])
.directive('orientable', function () {
return {
scope: false,
link: function($scope, element, attrs) {
$scope.$watch("url", function(newValue){
element.bind("load" , function(e){
$scope.$apply(function(){
$scope.showAjaxLoader = false;
});
});
});
}
}
});

Related

How to add transition from one function to another in JavaScript?

I want to add some smooth transition or animation from the mouse enter event to the mouse leave.
JS :
/* mudar cor do logo maior */
var myImage = document.querySelector('img#logo-maior');
myImage.onmouseenter = function() {
var mySrc = myImage.getAttribute('src');
myImage.setAttribute ('src','images/type-logo-coral.png');
}
myImage.onmouseleave = function() {
var mySrc = myImage.getAttribute('src');
myImage.setAttribute ('src','images/type-logo.png');
}
HTML :
<div class="display">
<img id="modelos" src="images/modelos/1.png">
<img id="logo-maior" src="images/type-logo.png" alt="TYPE logo">
<!--
<button type="button" onclick="displayPreviousImage()">Previous</button>
<button type="button" onclick="displayNextImage()">Next</button>
-->
</div>
Use CSS Animation. Add class for each function that will trigger the animation
Try this code
css
.transition1{
animation: fadeIn1 1.5s;
-webkit-animation: fadeIn1 1.5s; ;
opacity: 1;
}
#keyframes fadeIn1{
from{
opacity: 0;
}
to{
opacity: 1;
}
}
#-webkit-keyframeskeyframes fadeIn1{
from{
opacity: 0;
}
to{
opacity: 1;
}
}
.transition2{
animation: fadeIn2 1.5s;
-webkit-animation: fadeIn2 1.5s; ;
opacity: 1;
}
#-webkit-keyframeskeyframes fadeIn2{
from{
opacity: 0;
}
to{
opacity: 1;
}
}
javascript
var myImage = document.querySelector("img#logo-maior");
myImage.onmouseenter = function() {
myImage.classList.remove("transition2");
myImage.setAttribute("class", "transition1");
myImage.setAttribute("src", "../image2.jpg");
};
myImage.onmouseleave = function() {
myImage.classList.remove("transition1");
myImage.setAttribute("class", "transition2");
myImage.setAttribute("src","../image1.jpg"
);
};
html
<div class="display">
<img
id="logo-maior"
src="../img1.jpg"
alt="TYPE logo"
/>
</div>
In your CSS code:
img:hover {
(whatever styles you want for the hovering effect)
transition: all 0.5s ease-out;
}
For more information on transitions visit: https://developer.mozilla.org/en-US/docs/Web/CSS/transition

Using Angular promises with ng-show

I have an Angular SPA, which loads a bunch of data from the backend and displays them in, let's say tables. In order to provide a better user experience, I'm hiding those tables while the data is loaded and display a spinner. So I end up writing code like this:
Template:
<div class="row">
<div class="col-md-12">
<spinner ng-show="ctrl.loading.unicorns"></spinner>
<ul ng-hide="ctrl.loading.unicorns">
<li ng-repeat="unicorn in ctrl.unicorns">{{ unicorn.name }}</li>
</ul>
</div>
</div>
Controller:
function unicornController() {
var ctrl = this;
ctrl.loading = {
unicorns: true
};
unicornService
.get()
.then(function(data) {
ctrl.unicorns = data;
})
.finally(function() {
ctrl.loading.unicorns = false;
});
return ctrl;
}
With one loader it's not a big deal, but when I have 3 of them in every view, it feels like the loading could be handled in a better way. I found out that promises have a $$state.status property which holds exactly this value, but afaik I should not use that as it's not part of the public API. Is there any other way to achieve this without messing around local flags?
You can either find a way to do it yourself or you can find an existing way to do it.
Here is a usefull projects that will automatically display the progress of your $http requests.
Angular loading bar
Install (npm or bower)
$ npm install angular-loading-bar
$ bower install angular-loading-bar
Include
angular.module('myApp', ['angular-loading-bar'])
If you are doing it a lot and you need to have independent loader maybe it is good idea to implement specific directive/component just for that?
Simple example with spinKit spinner.
angular.module('app', []);
angular.module('app').component('loading', {
transclude: true,
template: `
<div class="spinner" ng-show="$ctrl.loading"></div>
<ng-transclude ng-hide="$ctrl.loading"></ng-transclud>
`,
bindings: {
promise: '<'
},
controller: function() {
this.loading = false;
this.$onChanges = function() {
if (this.promise != null) {
this.loading = true;
this.promise
.then(function() {
this.loading = false;
}.bind(this));
}
}.bind(this);
}
});
angular.module('app').controller('Example', function($timeout) {
this.emitPromise = function(propName) {
this[propName] = createRandomPromise()
.then(function(result) {
this[propName + 'Result'] = result;
}.bind(this));
}.bind(this);
function createRandomPromise() {
var time = Math.round(Math.random() * 3000); // up to 3s
return $timeout(function() {
return time;
}, time);
}
});
.spinner {
width: 40px;
height: 40px;
background-color: #333;
margin: 10px auto;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
#-webkit-keyframes sk-rotateplane {
0% {
-webkit-transform: perspective(120px)
}
50% {
-webkit-transform: perspective(120px) rotateY(180deg)
}
100% {
-webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg)
}
}
#keyframes sk-rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
}
50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
}
100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<div ng-app="app" ng-controller="Example as Ex">
<loading promise="Ex.x">
x result = {{Ex.xResult}}
</loading>
<br>
<button type="button" ng-click="Ex.emitPromise('x')">emit x</button>
<br>
<loading promise="Ex.y">
y result = {{Ex.yResult}}
</loading>
<br>
<button type="button" ng-click="Ex.emitPromise('y')">emit y</button>
</div>
Or if you wish you can use directive to insert result to transcluded scope:
angular.module('app', []);
angular.module('app').directive('loading', function($parse) {
return {
restrict: 'E',
transclude: true,
scope: true,
template: `
<div class="spinner" ng-show="loading"></div>
<div class="target" ng-hide="loading"></div>
`,
link: function($scope, $element, $attrs, $ctrl, $transclude) {
$scope.loading = false;
var targetElem = angular.element($element[0].querySelector('.target'));
$scope.$watch(watchFn, function(promise) {
if (promise != null) {
$scope.loading = true;
promise.then(function(result) {
$scope.loading = false;
$scope.result = result;
$transclude($scope, function (content) {
targetElem.empty();
targetElem.append(content);
});
});
}
});
function watchFn() {
return $parse($attrs.promise)($scope);
}
}
};
});
angular.module('app').controller('Example', function($timeout) {
this.parentValue = 'parent Value';
this.emitPromise = function(propName) {
this[propName] = createRandomPromise();
}.bind(this);
function createRandomPromise() {
var time = Math.round(Math.random() * 3000); // up to 3s
return $timeout(function() {
return time;
}, time);
}
});
.spinner {
width: 40px;
height: 40px;
background-color: #333;
margin: 10px auto;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
#-webkit-keyframes sk-rotateplane {
0% {
-webkit-transform: perspective(120px)
}
50% {
-webkit-transform: perspective(120px) rotateY(180deg)
}
100% {
-webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg)
}
}
#keyframes sk-rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
}
50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
}
100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<div ng-app="app" ng-controller="Example as Ex">
<loading promise="Ex.x">
x result = {{result}}
</loading>
<br>
<button type="button" ng-click="Ex.emitPromise('x')">emit x</button>
<br>
<loading promise="Ex.y">
y result = {{result}}<br>
Ex.parentValue = {{Ex.parentValue}}
</loading>
<br>
<button type="button" ng-click="Ex.emitPromise('y')">emit y</button>
</div>

Having a two directions animation swap using ng-animation-swap

I would like to have a sort of slider (but more like a ppt in fact, and depending on the button you click the outcome you would have will be different).
I use ng-animate-swap efficiently to change the current displayed slide, and it works well when going only in one way.
My problem is when I try to go the other way, I change my animation class, but for the soon-to-be previous slide, the animation will still be the one of the state before...
You can find a working example here inspired by the ng-animate-swap doc:
http://plnkr.co/edit/dArF1W7eM7Znur7Myx3O?p=preview
As you can see the problem is the change on CSS class is only applied to the new slide, and not to the one that will be removed.
You can find the relevant code below :
index.html :
<body ng-app="ngAnimateSwapExample">
<div ng-controller="AppCtrl">
<div class="container">
<div ng-animate-swap="number" class="cell {{swapAnimation}}" ng-class="colorClass(number)">
{{ number }}
</div>
</div>
<a ng-click="previousNumber()">PREVIOUS</a>
<a ng-click="nextNumber()">NEXT</a>
</div>
</body>
script.js :
.controller('AppCtrl', ['$scope',function($scope) {
$scope.number = 0;
var colors = ['red','blue','green','yellow','orange'];
$scope.colorClass = function(number) {
return colors[number % colors.length];
};
$scope.nextNumber = function(){
$scope.swapAnimation = "swap-animation";
$scope.number += 1;
};
$scope.previousNumber = function(){
$scope.swapAnimation = "swap-animation-reverse";
$scope.number -= 1;
};
}]);
animations.css :
.container {
height:250px;
width:250px;
position:relative;
overflow:hidden;
border:2px solid black;
}
.container .cell {
font-size:150px;
text-align:center;
line-height:250px;
position:absolute;
top:0;
left:0;
right:0;
border-bottom:2px solid black;
}
.swap-animation.ng-enter, .swap-animation.ng-leave {
transition:0.5s linear all;
}
.swap-animation.ng-enter {
top:-250px;
}
.swap-animation.ng-enter-active {
top:0px;
}
.swap-animation.ng-leave {
top:0px;
}
.swap-animation.ng-leave-active {
top:250px;
}
.swap-animation-reverse.ng-enter, .swap-animation-reverse.ng-leave {
transition:0.5s linear all;
}
.swap-animation-reverse.ng-enter {
top:250px;
}
.swap-animation-reverse.ng-enter-active {
top:0px;
}
.swap-animation-reverse.ng-leave {
top:0px;
}
.swap-animation-reverse.ng-leave-active {
top:-250px;
}
Simply add a timeout after changed the cssClass in your nextNumber() and previousNumber() logic, so in the first cycle the element change the class and in the next cycle ng-animate-swap executes the animation.
$scope.nextNumber = function(){
$scope.swapAnimation = "swap-animation";
$timeout(function(){
$scope.number += 1;
});
};
$scope.previousNumber = function(){
$scope.swapAnimation = "swap-animation-reverse";
$timeout(function(){
$scope.number -= 1;
});
};
http://plnkr.co/edit/yEDmEWRGxIrAnalQF20u?p=preview

Switching tab makes CSS go crazy

Can anyone explain why this 3D works OK when you visit the page but disintegrates when you switch to another tab and then revert to the page?
But then...
... it disappears into the screen!
HTML:
<html>
<head>
<link href="styles/styles.css" rel="stylesheet" />
</head>
<body style='background-color: white; width: 900px;'>
<div style='margin: 50px auto;'>
<div id="img" style="background-image: url('img1.jpg'); width: 850px; height: 520px" />
</div>
<script src="js/libs/jquery/jquery-1.6.4.js" type="text/javascript"></script>
<script src="js/libs/jquery/jquery-slide-show-filter.js" type="text/javascript"></script>
</body>
</html>
CSS:
#container{
-webkit-perspective: 800;
width: 850px;
height: 520px;
}
#img, #s1 {
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat: no-repeat;
}
#cube{
-webkit-transform-style: preserve-3d;
-webkit-transform: translateZ(-425px);
-webkit-backface-visibility: hidden;
width: 850px;
height: 520px;
}
#cube.enable
{
-webkit-animation: flash 0.75s ease-in-out;
-moz-animation: flash 0.75s ease-in-out;
-ms-animation: flash 0.75s ease-in-out;
-o-animation: flash 0.75s ease-in-out;
animation: flash 0.75s ease-in-out;
}
#-webkit-keyframes flash {
100% { -webkit-transform: translateZ(-425px) rotateY(90deg); }
}
Script:
var getImage = function(){
var images = ["img1.jpg", "img2.jpg", "img3.jpg"];
$.each(images, function( index, value ) {
$('<img />').attr('src', value);
});
index = 0;
return function(){
if (++index == images.length){
index = 0;
}
return images[index];
};
}();
setInterval(function(){
transform($('#img'), getImage());
}, 1000);
function transform(img, newImg){
img
.wrap('<div id="container"><div id="cube"></div>')
.css('-webkit-transform', 'translateZ(425px)');
img
.clone()
.attr('id', 's1')
.insertBefore(img)
.css('background-image', 'url("' + newImg + '")')
.css('position', 'absolute')
.css('-webkit-transform', 'rotateY(-90deg) translateZ(425px)');
PrefixedEvent($('#cube')[0], "AnimationEnd", function () {
img.unwrap().unwrap();
img.remove();
$('#s1')
.attr('id', 'img')
.css('-webkit-transform', '');
});
$('#cube').addClass('enable');
}
function PrefixedEvent(element, type, callback) {
var pfx = ["webkit", "moz", "MS", "o", ""];
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}
You can fix the issue by calling transform only while the window has focus:
(function() {
var inTab= false;
$(window).blur(function() {
inTab= false;
});
$(window).focus(function() {
inTab= true;
});
setInterval(function() {
if(inTab) {
transform($('#img'), getImage());
}
}, 1000);
})();
Fiddle
Click the image to simulate the window being focused. You can then switch between tabs, and the animation will no longer break.
I think its because if you switch tab the AnimationEnd event doesn't fire so there's no clean up.

How to call a image class on a regular interval

I am having four classes inside each class a image is called
<div id="ban01" class="banner ban01">
</div>
<div id="ban02" class="banner ban02">
</div>
<div id="ban03" class="banner ban03">
</div>
<div id="ban04" class="banner ban04">
</div>
and my css class contains
.ban01 { background-image:url(../images/banner/01.jpg); }
.ban02 { background-image:url(../images/banner/02.jpg); }
.ban03 { background-image:url(../images/banner/03.jpg); }
.ban04 { background-image:url(../images/banner/04.jpg); }
and my Jquery is
$(document).ready(function () {
var totDivs = $(".banner ban03").length;
var currDiv = 0;
var myInterval = setInterval(function () {
if (currDiv > totDivs) {
clearInterval(myInterval);
return
}
$(".banner ban03").eq(currDiv).find('class').trigger("click");
currDiv++;
}, 2000);
});
how to call these classes in regular intervals sorry if i repeated the question again
html
<div id="ban01" class="banner ban01">
</div>
<div id="ban02" class="banner ban02">
</div>
<div id="ban03" class="banner ban03">
</div>
<div id="ban04" class="banner ban04">
</div>
style
.banner { height: 50px }
.ban01 { background: green }
.ban02 { background: blue }
.ban03 { background: red }
.ban04 { background: orange }
javascript
$(document).ready(function () {
var totDivs = $(".banner").length;
var currDiv = 0;
var myInterval = setInterval(change, 2000);
function change(){
$(".banner").hide().eq(currDiv).show();
currDiv = (currDiv + 1) % totDivs;
}
change();
});
http://jsfiddle.net/b2Btj/1/
Did you look on this answer... :-)
jquery-timed-change-of-item-class
Try this while I'm doing your coding. :-D
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style type="text/css">
.a, .b, .c, .d, .e {
height: 120px;
width: 200px;
}
.a {
background-color: red;
}
.b {
background-color: green;
}
.c {
background-color: blue;
}
.d {
background-color: black;
}
.e {
background-color: yellow;
}
</style>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
<h1>Testing</h1>
<div id="test" class="a">How Are You Buddy?</div>
<script type="text/javascript">
$( document ).ready(function() {
var array = ['a','b','c','d','e'];//Here is your classes
var len = array.length;
var i=0;
function changeDivClass(d) {
$("#test").removeClass();
$("#test").addClass(array[d]);
}
setInterval(function() {
if(len>=i){
return changeDivClass(i++);
}else{
i=0;
$("#test").removeClass();
$("#test").addClass('a');
}
}, 5000);
});
</script>
</body>
</html>
#Maikay yes I want to rotate the images
Why use JavaScript to rotate image ?
This is possible with only css. Use the property : animation.
.imageRotate {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-animation:spin 4s linear 1; // '1' for a single animation, if you need an infinite animation replace '1' by 'infinite'
-moz-animation:spin 4s linear 1;
animation:spin 4s linear 1;
}
#-moz-keyframes spin {
100% { -moz-transform: rotate(360deg); }
}
#-webkit-keyframes spin {
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
100% { -webkit-transform: rotate(360deg);
transform:rotate(360deg);
}
}
<div id="ban01">
<img class="imageRotate" src="http://socialtalent.co/wp-content/uploads/blog-content/so-logo.png">
</div>
not sure what exactly the click trigger on the banner element will do, but maybe this helps:
$(document).ready(function () {
var totDivs = $(".banner").length;
var currDiv = 0;
var myInterval = setInterval(function() {
if (currDiv > totDivs) {
clearInterval(myInterval);
return;
}
$(".banner").eq(currDiv).trigger("click");
currDiv++;
}, 2000);
});
what you could do is that you could run a for loop if you know the counts of the "div"
for(var count=0;count<3;count++)
{
var totDivs = $(".banner ban0"+count).length;
var currDiv = 0;
var myInterval = setInterval(function () {
if (currDiv > totDivs) {
clearInterval(myInterval);
return
}
$(".banner ban0"+count).eq(currDiv).find('class').trigger("click");
currDiv++;
}, 2000);
}
May this could solve your issue .

Categories