As part of a project we wanted to have the front page with a nice rotating background for the jumbotron. There are a number of carousel components and scripts that can be easily found online but mostly they use the img tag and/or require a root absolute div which means it won’t automatically resize to the jumbotron content. I wanted a jumbotron that would resize to the content and also provide a nice seamless transition for the images. So, I sat down and rolled my own.
Firstly you need to set up a jumbotron component:
background-color: transparent; // replace the standard bootstrap background color
background-repeat: no-repeat;
background-position: 50% 50%;
/* Layer the images so that the visible one is below all the others,
* but the previously active one fades out to reveal the visible one
.jumbotron-slideshow {
position: relative;
background-color: transparent; // replace the standard bootstrap background color
.slideshow {
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
/* Layer the images so that the visible one is below all the others,
* but the previously active one fades out to reveal the visible one
* below */
transition: opacity 1s;
opacity: 0;
&.visible {
transition: none;
opacity: 1;
z-index: -1;
}
}
}
.jumbotron-slideshow {
position: relative;
background-color: transparent; // replace the standard bootstrap background color
.slideshow {
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
/* Layer the images so that the visible one is below all the others,
* but the previously active one fades out to reveal the visible one
* below */
transition: opacity 1s;
opacity: 0;
&.visible {
transition: none;
opacity: 1;
z-index: -1;
}
}
}
And then the HTML:
<div class="jumbotron jumbotron-slideshow">
<div ng-bg-slideshow="[ 'images/bg1.jpg', 'images/bg2.jpg', ... ]" interval=5000></div>
... content that you want ...
<div class="jumbotron jumbotron-slideshow">
<div ng-bg-slideshow="[ 'images/bg1.jpg', 'images/bg2.jpg', ... ]" interval=5000></div>
... content that you want ...
<div class="jumbotron jumbotron-slideshow">
<div ng-bg-slideshow="[ 'images/bg1.jpg', 'images/bg2.jpg', ... ]" interval=5000></div>
... content that you want ...
Create the angular template to generate the image divs:
<div ng-repeat="img in images"
class="slideshow" ng-class="{ visible: active_image == $index }" ng-style="{ 'background-image': 'url(' + img + ')' }">
<div ng-repeat="img in images"
class="slideshow" ng-class="{ visible: active_image == $index }" ng-style="{ 'background-image': 'url(' + img + ')' }">
</div>
<div ng-repeat="img in images"
class="slideshow" ng-class="{ visible: active_image == $index }" ng-style="{ 'background-image': 'url(' + img + ')' }">
</div>
And finally the Angular component:
app.directive("ngBgSlideshow", function($interval) {
templateUrl: 'views/components/slideshow.html',
link: function( scope, elem, attrs ) {
scope.$watch( 'ngBgSlideshow', function(val) {
var change = $interval(function() {
if( scope.active_image >= scope.images.length )
}, scope.interval || 1000 );
scope.$on('$destroy', function() {
$interval.cancel( change );
app.directive("ngBgSlideshow", function($interval) {
return {
restrict: 'A',
scope: {
ngBgSlideshow: '&',
interval: '=',
},
templateUrl: 'views/components/slideshow.html',
link: function( scope, elem, attrs ) {
scope.$watch( 'ngBgSlideshow', function(val) {
scope.images = val();
scope.active_image = 0;
});
var change = $interval(function() {
scope.active_image++;
if( scope.active_image >= scope.images.length )
scope.active_image = 0;
}, scope.interval || 1000 );
scope.$on('$destroy', function() {
$interval.cancel( change );
});
}
};
});
app.directive("ngBgSlideshow", function($interval) {
return {
restrict: 'A',
scope: {
ngBgSlideshow: '&',
interval: '=',
},
templateUrl: 'views/components/slideshow.html',
link: function( scope, elem, attrs ) {
scope.$watch( 'ngBgSlideshow', function(val) {
scope.images = val();
scope.active_image = 0;
});
var change = $interval(function() {
scope.active_image++;
if( scope.active_image >= scope.images.length )
scope.active_image = 0;
}, scope.interval || 1000 );
scope.$on('$destroy', function() {
$interval.cancel( change );
});
}
};
});
Note: If you want to be able to programatically change the interval you’ll need to add a watch that recreates the interval when the interval attribute changes.
I am stuck trying to get the images to appear on the screen. My question is:
Does the list of images come from –> ng-bg-slideshow=”[ ?
So when you reference the images in the ng-repeat –> ng-repeat=”img in images” each img is coming from the above list provided to “ng-bg-slideshow”?
Or are you initializing the list in a controller which is not shown in the provided code?
images is the contents of ng-bg-slideshow – it’s copied over by the following code:
scope.$watch( 'ngBgSlideshow', function(val) {
scope.images = val();