Step 1: Creating the AngularJS Directive
When it comes to AngularJS it’s all about architecting the app first and then using the appropriate markup/design. Since we want our slider to be self contained and easily plugged into an existing AngularJS app, creating a directive is the correct way to go. So, let’s get started with an empty directive namedslider
:
var sliderApp = angular.module('sliderApp', []);
sliderApp.directive('slider', function($timeout) {
return {
restrict: 'AE',
replace: true,
scope: {
images: '='
},
link: function(scope, elem, attrs) {},
templateUrl: 'templates/templateurl.html'
};
});
The important thing to note is that we have isolated the scope of our directive. Since we will need several functions/properties only for the internal usage, we’ve chosen to create an isolated scope instead of polluting the parent scope. Also we should be able to accept a list of images from the parent scope for displaying. That’s why we are using a =
binding. Finally, the template for the directive goes inside the templateurl.html
file.
Step 2: Set Up the Controller to Supply Images
Next, let’s create a controller that creates an array of five image objects in its scope. We will pass these images to the directive later.sliderApp.controller('SliderController', function($scope) {
$scope.images = [{
src: 'img1.png',
title: 'Pic 1'
}, {
src: 'img2.jpg',
title: 'Pic 2'
}, {
src: 'img3.jpg',
title: 'Pic 3'
}, {
src: 'img4.png',
title: 'Pic 4'
}, {
src: 'img5.png',
title: 'Pic 5'
}];
});
Step 3: Write the Directive Markup
Now let’s return to our directive and produce the markup. Since the directive needs to render each image in the array, we will useng-repeat
. Also we will have two buttons: prev
and next
to navigate the images. The content of templates/templateurl.html
is shown below.
<div class="slider">
<div class="slide" ng-repeat="image in images" ng-show="image.visible">
<img ng-src="img/{{image.src}}" />
</div>
<div class="arrows">
<a href="#" ng-click="prev()">
<img src="img/left-arrow.png" />
</a>
<a href="#" ng-click="next()">
<img src="img/right-arrow.png" />
</a>
</div>
</div>
The markup is pretty simple. The src
property of the image
points to the image location. The image.visible
property indicates if the image is visible. When we move forward/backward to the next image, we need to set the visible
property of that particular image to true
. The rest of the image
objects should have this property set to false
. We have also passed the next()
and prev()
functions to ng-click
so as to perform navigation. The image.title
property is important in case you want to display the description for each image.
Step 4: Update the Directive
We need to keep track of the currently visible image. For this we will use a property calledcurrentIndex
in the directive’s isolated scope. We also have the next()
function which increments currentIndex
and prev()
function which decrements it. Let’s update the link
function of the directive with the following code:
scope.currentIndex = 0; // Initially the index is at the first image
scope.next = function() {
scope.currentIndex < scope.images.length - 1 ? scope.currentIndex++ : scope.currentIndex = 0;
};
scope.prev = function() {
scope.currentIndex > 0 ? scope.currentIndex-- : scope.currentIndex = scope.images.length - 1;
};
This just increments/decrements the currentIndex
based on the arrow button (next/prev) click. But, we need to detect when this change occurs and appropriately make the image at currentIndex
visible by setting the visible
property to true
. As we have already passed image.visible
to the ng-show
directive in our HTML markup, any change in this property will automatically show/hide the images. We should also watch the directive scope for changes to currentIndex
. Append the following code to the end of the previous code snippet:
scope.$watch('currentIndex', function() {
scope.images.forEach(function(image) {
image.visible = false; // make every image invisible
});
scope.images[scope.currentIndex].visible = true; // make the current image visible
});
Step 5: Animate the Slider
Angular 1.2 introduced a new animation framework that can be used to associate CSS3 animations with various events seamlessly. You just need to specify the animation and Angular takes care of the rest. For example, when an element is being hidden Angular will automatically add classes likeng-hide-add
and ng-hide-active
. You can write CSS against these classes to perform the desired animations. Angular animation is beyond the scope of this tutorial. However, I encourage you to go through this resource to learn about animations. To add animations, update the module like this:
var sliderApp = angular.module('sliderApp', ['ngAnimate']);
And include the following script in the HTML after the Angular script:
<script src="http://code.angularjs.org/1.2.9/angular-animate.min.js"></script>
Next, add the following CSS rules to describe the transitions:
.slide.ng-hide-add,
.slide.ng-hide-remove {
-webkit-transition: all linear 0.5s;
-moz-transition: all linear 0.5s;
-o-transition: all linear 0.5s;
transition: all linear 0.5s;
display: block!important;
}
.slide.ng-hide-add.ng-hide-add-active,
.slide.ng-hide-remove {
opacity: 0;
}
.slide.ng-hide-add,
.slide.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
}
Step 6: Use the Directive
Now it’s time to use the directive in HTML. While using the directive we also need to pass theimages
array declared in the controller scope to the directive.
<body ng-controller="SliderController">
<h1>Slider Using AngularJS</h1>
<slider images="images" />
</body>
That’s all! Our brand new Angular slider is ready. For styling purposes, we can include the following CSS:
* {
font-family: 'Open Sans', sans-serif;
}
.center-grey {
background: #f2f2f2;
}
.slider {
position: relative;
padding: 5px;
width: 610px;
margin: auto;
margin-top: 40px;
}
.slide {
position: absolute;
top: 0;
left: 0;
box-shadow: 0px 0px 15px #999;
}
.arrows {
position: absolute;
top: 10px;
right: 20px;
}
.arrows img {
height: 32px;
}
h1 {
text-align: center;
padding: 10px;
font-size: 40px;
color: #222;
}
Bonus
In addition to responding to the next/prev clicks we might also want our slider to automatically slide to the next image after an interval. To do that we can use Angular’s$timeout
service. Modify the directive as shown below to declare a dependency on $timeout
:
sliderApp.directive('slider', function($timeout) {
...
// configuarations here
});
And append the following snippet to the link
function which calls the next()
function every five seconds:
var timer;
var sliderFunc = function() {
timer = $timeout(function() {
scope.next();
timer = $timeout(sliderFunc, 5000);
}, 5000);
};
sliderFunc();
scope.$on('$destroy', function() {
$timeout.cancel(timer); // when the scope is getting destroyed, cancel the timer
});
Conclusion
We’ve reached the end of the tutorial, and we’ve learned how to create an AngularJS image slider using a directive (with a little animation). We achieved this with a minimum amount of JavaScript code and no jQuery DOM manipulation. There can be many ways to achieve the same thing in Angular and this tutorial has shown just one way. If you can think of a better method or have something to add/ask feel free to comment. The source code for the complete app is available on GitHub for download. You can also check out a live demo of the app.Frequently Asked Questions (FAQs) about Creating a Slide Show Plugin with AngularJS
How can I add transition effects to my AngularJS slide show plugin?
Adding transition effects to your AngularJS slide show plugin can enhance the visual appeal and user experience. You can use AngularJS’s built-in $animate service to add CSS-based animations. First, you need to include the ngAnimate module in your application. Then, you can define your CSS transitions or animations and apply them to your slide show elements. Remember to add the ‘ng-enter’, ‘ng-leave’, and ‘ng-move’ classes to control the animations during different stages of the view lifecycle.
Can I use external images for the slide show plugin?
Yes, you can use external images for your slide show plugin. When defining your image array in the AngularJS controller, you can simply use the URLs of the external images. Make sure the URLs are correct and the images are allowed to be loaded on your website to avoid any cross-origin resource sharing (CORS) issues.
How can I make the slide show plugin responsive?
To make your slide show plugin responsive, you can use CSS media queries. These allow you to apply different styles depending on the screen size. You can adjust the width and height of the slide show container and the images to fit different screen sizes. Additionally, AngularJS allows you to conditionally apply classes or styles based on scope data, which can be used to dynamically adjust the layout.
How can I add navigation controls to the slide show?
Navigation controls can be added to your slide show by creating previous and next buttons. In your AngularJS controller, you can define functions to increment or decrement the current slide index. These functions can be triggered by ng-click directives on your buttons. Remember to handle the edge cases where the slide show reaches the beginning or the end.
Can I add captions to the images in the slide show?
Yes, you can add captions to the images in your slide show. In your image array, you can include a caption property for each image. Then, in your HTML template, you can use the AngularJS double curly brace syntax {{ }} to bind the caption property to the view. You can style and position the captions using CSS.
How can I add a carousel effect to the slide show?
A carousel effect can be achieved by continuously looping through the images. In your AngularJS controller, when incrementing the current slide index, if it exceeds the last index, reset it to the first index. Similarly, when decrementing, if it goes below the first index, set it to the last index. This will create a seamless loop effect.
How can I add a fade effect between slides?
A fade effect can be added between slides using CSS transitions. You can apply a transition effect on the opacity property of the slide show images. When changing slides, adjust the opacity from 1 (fully visible) to 0 (fully transparent) over a certain duration to create a fade out effect, and vice versa for a fade in effect.
Can I use the slide show plugin with other AngularJS directives?
Yes, the slide show plugin can be used with other AngularJS directives. You can include it inside other directive templates, or use other directives inside the slide show template. However, be aware of the scope hierarchy and isolate scope if necessary to avoid unexpected behavior.
How can I preload images for the slide show?
Preloading images can improve the performance of your slide show. You can create a new Image object for each image URL in your image array and set the src property to the URL. This will start loading the images in the background. However, be aware that this might consume more bandwidth and might not be suitable for users with slow internet connections.
Can I add a timer to automatically change slides?
Yes, you can add a timer to automatically change slides. You can use the $timeout service in AngularJS to schedule a function to increment the current slide index after a certain delay. Remember to cancel the timer when the scope is destroyed to avoid memory leaks.
Sandeep is the Co-Founder of Hashnode. He loves startups and web technologies.