Log in

View Full Version : adding keyboard control to image slideshow



bornegraphics
08-20-2013, 03:24 PM
Good morning all,
I am trying to add the ability to give the user the option to use their keyboard arrows keys (left & right) to cycle through an image slideshow. Below is my HTML and CSS code. Any help would be greatly appreciated. Many thanks, Alan



<!-- slideshow -->
<div id="slideshow_container">
<div id="loader" class="loader_galleries"></div>
<div class="wrapper">
<div id="ps_container" class="ps_container">
<div class="ps_image_wrapper">
<!-- First initial image -->
<img src="jungle/large/jungle1.jpg"/><div class="ps_caption_title"><p class="captiontitle"></div></div>

<!-- Navigation items -->
<div class="ps_next"></div>
<div class="ps_prev"></div>
<!-- Dot list with thumbnail preview -->
<ul class="ps_nav">

<li><a href="jungle/large/jungle1.jpg" rel="jungle/thumbs/jungle1.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle2.jpg" rel="jungle/thumbs/jungle2.jpg">
<div class="ps_caption_title"><p class="captiontitle">Canadian Wildlife Magazine - Print Feature 2012</div>
</a></li>

<li><a href="jungle/large/jungle3.jpg" rel="jungle/thumbs/jungle3.jpg">
<div class="ps_caption_title"><p class="captiontitle">Canadian Wildlife Magazine - Print Feature 2012</div>
</a></li>

<li><a href="jungle/large/jungle4.jpg" rel="jungle/thumbs/jungle4.jpg">
<div class="ps_caption_title"><p class="captiontitle">Canadian Wildlife Magazine - Print Feature 2012</div>
</a></li>

<li><a href="jungle/large/jungle5.jpg" rel="jungle/thumbs/jungle5.jpg">
<div class="ps_caption_title"><p class="captiontitle">Canadian Wildlife Magazine - Print Feature 2012</div>
</a></li>

<li><a href="jungle/large/jungle6.jpg" rel="jungle/thumbs/jungle6.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle7.jpg" rel="jungle/thumbs/jungle7.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle8.jpg" rel="jungle/thumbs/jungle8.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle9.jpg" rel="jungle/thumbs/jungle9.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle10.jpg" rel="jungle/thumbs/jungle10.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle11.jpg" rel="jungle/thumbs/jungle11.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li><a href="jungle/large/jungle12.jpg" rel="jungle/thumbs/jungle12.jpg">
<div class="ps_caption_title"><p class="captiontitle"></div>
</a></li>

<li class="ps_preview">
<div class="ps_preview_wrapper">
<!-- Thumbnail comes here -->
</div>
<!-- Little triangle -->
<span></span>
</li>
</ul>
</div>
</div>
</div>
<!-- slideshow -->




#slideshow_container {
height: 600px;
width: 982px;
margin-bottom: 80px;
}
*{
margin:0;
padding:0;
}
.loader {
width: 900px;
height: 600px;
opacity: 0.7;
z-index: 1000;
background-color: #333;
background-image: url(images/loader.gif);
background-repeat: no-repeat;
background-position: center center;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
}
.loader_galleries {
width: 900px;
height: 600px;
opacity: 0.7;
z-index: 1000;
background-color: #333;
background-image: url(images/loader.gif);
background-repeat: no-repeat;
background-position: center center;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
}

/* Preview Slider Gallery Style */
.ps_container{
display:none;
width:900px;
height:600px;
position:relative;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
}
.ps_image_wrapper{
width: 900px;
height: 664px;
overflow: hidden;
position: relative;
margin-top: 0;
margin-right: auto;
margin-bottom: 0;
margin-left: auto;
}
.ps_image_wrapper img{
position:absolute;
left:0px;
top:0px;
overflow: hidden;
}
.ps_prev,
.ps_next{
width: 45px;
height: 600px;
position: absolute;
top: 0;
cursor: pointer;
opacity: 0.5;
}
.ps_prev{
left: -45px;
background-color: transparent;
background-image: url(images/prev.png);
background-repeat: no-repeat;
background-position: center center;
width: 45px;
}
.ps_next{
right: -45px;
background-color: transparent;
background-image: url(images/next.png);
background-repeat: no-repeat;
background-position: center center;
width: 45px;
}
.ps_prev:hover,
.ps_next:hover{
opacity: 0.9;
bottom: 0px;
width: 45px;
}
ul.ps_nav{
list-style: none;
padding: 0;
position: relative;
margin-top: 20px;
margin-right: auto;
margin-bottom: 40px;
margin-left: auto;
width: 204px;
}
ul.ps_nav li{
float:left;
}
ul.ps_nav li a{
display:block;
text-indent:-9000px;
width:11px;
height:11px;
outline:none;
padding:0px 3px;
background-color: transparent;
background-image: url(images/dot.png);
background-repeat: no-repeat;
background-position: center top;
}
ul.ps_nav li a:hover,ul.ps_nav li.selected a{
background-position:50% -11px;
}
ul.ps_nav li.ps_preview{
display:none;
width:85px;
height:91px;
top:-85px;
left:-34.5px; /*First item, next ones is leftDot - 0.5*wThis + 0.5*wDot, i.e. second one is (16 - 42.5 + 8) = -18.5 */
position:absolute;
}
ul.ps_nav li.ps_preview span{
width:15px;
height:6px;
position:absolute;
top:65px;
left:35px;
background-color: transparent;
background-image: url(images/triangle.png);
background-repeat: no-repeat;
background-position: center top;
}
.ps_preview_wrapper{
width:75px;
height:50px;
border:5px solid #fff;
overflow:hidden;
position:relative;
}
.ps_preview_wrapper img{
position:absolute;
top:0px;
left:0px;
}
.ps_caption_title {
position: absolute;
bottom: 4px;
left: 0;
text-align: left;
width: 100%;
padding-left: 20px;
letter-spacing: 1px;
overflow: hidden;
height: 60px;
padding-right: 20px;
}

jscheuer1
08-20-2013, 04:01 PM
Without javascript, probably not. That markup looks like it might be using jQuery, is it? If so it would be easy to add the arrow keys to that. Even if it's not, if I could see the page I could figure out how to add them. But that's not always the best idea because the arrow keys are for moving the page left and right if it's too narrow for the window, you would lose that functionality for the page.

If you're using jQuery for the slideshow and the prev/next buttons are activated on click:


<script type="text/javascript">
jQuery(function($){
$(document).keydown(function(e){
switch(e.keyCode){
case 37: {//left arrow
$('.ps_prev').trigger('click');
break;
}
case 39: {//right arrow
$('.ps_next').trigger('click');
break;
}
}
if(Math.abs(e.keyCode - 38) === 1){
e.preventDefault();
}
});
});
</script>



should do the trick.

The browser cache may need to be cleared and/or the page refreshed to see changes.

If you want more help, please include a link to the page on your site that contains the problematic code so we can check it out.

bornegraphics
08-20-2013, 07:54 PM
John,

Thanks for your reply. The slideshow is generated using the Javascript below. Would I still be able to use the code you provided or is there a better method? Your help would be greatly appreciated.

Here's a link to view the slideshow in action: http://neileverosborne.com/portfolios/blackturtle.html

Many thanks,
Alan






<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
/*
the images preload plugin
*/
(function($) {
$.fn.preload = function(options) {
var opts = $.extend({}, $.fn.preload.defaults, options),
o = $.meta ? $.extend({}, opts, this.data()) : opts;
return this.each(function() {
var $e = $(this),
t = $e.attr('rel'),
i = $e.attr('href'),
l = 0;
$('<img/>').load(function(i){
++l;
if(l==2) o.onComplete();
}).attr('src',i);
$('<img/>').load(function(i){
++l;
if(l==2) o.onComplete();
}).attr('src',t);
});
};
$.fn.preload.defaults = {
onComplete : function(){return false;}
};
})(jQuery);
</script>
<script type="text/javascript">
$(function() {
var caption_bg_opacity = 0.4;
$('.ps_caption_title_bg').css({opacity:caption_bg_opacity});
//some elements..
var $ps_container = $('#ps_container'),
$ps_image_wrapper = $ps_container.find('.ps_image_wrapper'),
$ps_next = $ps_container.find('.ps_next'),
$ps_prev = $ps_container.find('.ps_prev'),
$ps_nav = $ps_container.find('.ps_nav'),
$tooltip = $ps_container.find('.ps_preview'),
$ps_preview_wrapper = $tooltip.find('.ps_preview_wrapper'),
$links = $ps_nav.children('li').not($tooltip),
total_images = $links.length,
currentHovered = -1,
current = 0,
$loader = $('#loader');

/*check if you are using a browser*/
var ie = false;
if ($.browser.msie && $.browser.version < 9) {
ie = true;//you are not!Anyway let's give it a try
}
if(!ie)
$tooltip.css({
opacity : 0
}).show();


/*first preload images (thumbs and large images)*/
var loaded = 0;
$links.each(function(i){
var $link = $(this);
$link.find('a').preload({
onComplete : function(){
++loaded;
if(loaded == total_images){
//all images preloaded,
//show ps_container and initialize events
$loader.hide();
$ps_container.show();
//when mouse enters the pages (the dots),
//show the tooltip,
//when mouse leaves hide the tooltip,
//clicking on one will display the respective image
$links.bind('mouseenter',showTooltip)
.bind('mouseleave',hideTooltip)
.bind('click',showImage);
//navigate through the images
$ps_next.bind('click',nextImage);
$ps_prev.bind('click',prevImage);
}
}
});
});

function showTooltip(){
var $link = $(this),
idx = $link.index(),
linkOuterWidth = $link.outerWidth(),
//this holds the left value for the next position
//of the tooltip
left = parseFloat(idx * linkOuterWidth) - $tooltip.width()/2 + linkOuterWidth/2,
//the thumb image source
$thumb = $link.find('a').attr('rel'),
imageLeft;

//if we are not hovering the current one
if(currentHovered != idx){
//check if we will animate left->right or right->left
if(currentHovered != -1){
if(currentHovered < idx){
imageLeft = 75;
}
else{
imageLeft = -75;
}
}
currentHovered = idx;

//the next thumb image to be shown in the tooltip
var $newImage = $('<img/>').css('left','0px')
.attr('src',$thumb);

//if theres more than 1 image
//(if we would move the mouse too fast it would probably happen)
//then remove the oldest one (:last)
if($ps_preview_wrapper.children().length > 1)
$ps_preview_wrapper.children(':last').remove();

//prepend the new image
$ps_preview_wrapper.prepend($newImage);

var $tooltip_imgs = $ps_preview_wrapper.children(),
tooltip_imgs_count = $tooltip_imgs.length;

//if theres 2 images on the tooltip
//animate the current one out, and the new one in
if(tooltip_imgs_count > 1){
$tooltip_imgs.eq(tooltip_imgs_count-1)
.stop()
.animate({
left:-imageLeft+'px'
},150,function(){
//remove the old one
$(this).remove();
});
$tooltip_imgs.eq(0)
.css('left',imageLeft + 'px')
.stop()
.animate({
left:'0px'
},150);
}
}
//if we are not using a "browser", we just show the tooltip,
//otherwise we fade it
//
if(ie)
$tooltip.css('left',left + 'px').show();
else
$tooltip.stop()
.animate({
left : left + 'px',
opacity : 1
},150);
}

function hideTooltip(){
//hide / fade out the tooltip
if(ie)
$tooltip.hide();
else
$tooltip.stop()
.animate({
opacity : 0
},150);
}

function showImage(e){
var $link = $(this),
idx = $link.index(),
$image = $link.find('a').attr('href'),
$caption = $link.find('a').html() || '',
$currentImage = $ps_image_wrapper.find('img'),
currentImageWidth = $currentImage.width();

//if we click the current one return
if(current == idx) return false;

//add class selected to the current page / dot
$links.eq(current).removeClass('selected');
$link.addClass('selected');

//the new image element
var $newImage = $('<img/>').css('left',currentImageWidth + 'px')
.attr('src',$image);

//if the wrapper has more than one image, remove oldest
if($ps_image_wrapper.children().length > 1)
$ps_image_wrapper.children(':last').remove();

//prepend the new image
$ps_image_wrapper.prepend($('<div></div>').append($('<div class="ps_caption_title_bg"></div>').css({opacity:caption_bg_opacity})).append($newImage).append('<div class="ps_caption_title">'+$caption+'</div>'));

//the new image width.
//This will be the new width of the ps_image_wrapper
var newImageWidth = $newImage.width();
$newImage.next('div').css({left: currentImageWidth, width: newImageWidth});

//check animation direction
if(current > idx){
$newImage.add($newImage.next('div')).css('left',-newImageWidth + 'px');
currentImageWidth = -newImageWidth;
}
current = idx;
//animate the new width of the ps_image_wrapper
//(same like new image width)
$ps_image_wrapper.stop().animate({
width : newImageWidth + 'px'
},350);
//animate the new image in
$newImage.add($newImage.next('div')).stop().animate({
left : '0px'
},350);
//animate the old image out
$currentImage.add($currentImage.next('div')).stop().animate({
left : -currentImageWidth + 'px'
},350);

e.preventDefault();
}
var gotoLoop = 0;
var backLoop = 1;

function nextImage(){
$links.eq(current+1).trigger('click');
backLoop = 0;
if (gotoLoop == 1) {
$links.eq(0).trigger('click');
gotoLoop = 0;
}
if (current == total_images-1){
gotoLoop = 1;
}

}

function prevImage(){
if(current > 0){
$links.eq(current-1).trigger('click');
}
if (backLoop == 1) {
$links.eq(total_images-1).trigger('click');
backLoop = 0;
}

if (current == 0) {
backLoop = 1;
}

}

});


</script>

jscheuer1
08-20-2013, 09:11 PM
Not unless it gives you trouble.

bornegraphics
08-21-2013, 02:01 PM
Hi John, the script you provided works perfectly. Thank you for all your help.

- Alan

bornegraphics
08-21-2013, 05:51 PM
Hi John,
One last question regarding the slideshow, do you know of a tutorial or code that would help the user be able to touch scroll through the images while on an iPhone/iPad?
Any thoughts, suggestions or info you could provide would be very helpful and appreciated.

Many thanks,
Alan

jscheuer1
08-21-2013, 06:54 PM
I'm still looking for a good script for that. There are two jQuery plugins that I'm aware of for mobile devices:

http://jquerymobile.com/

and:

http://labs.rampinteractive.co.uk/touchSwipe/demos/

They both seem pretty thick to me, and I'm supposed to be an expert. I have no mobile device to test on though, I bet I would get it much more quickly if I did.

bornegraphics
08-22-2013, 12:08 AM
Hi John,
Thanks for the links. I'll read over them and if I figure anything out I'll be sure to pass on my findings to you. Thanks again for all your help.

- Alan