Reputation: 15501
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?
Upvotes: 1
Views: 98
Reputation: 191976
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>
Upvotes: 1
Reputation: 886
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;
});
});
});
}
}
});
Upvotes: 0