Sorting images through swiping (using TouchSwipe) - javascript

I'm trying to get some pictures to display one by one to be sorted via swiping.
Only one picture should be shown at a time, with the next appearing after a swipe has been made to the left or right. I can get the swipe working with TouchSwipe (http://jsfiddle.net/MichelleGlauser/CR329/1), but once I put the swipe inside of a loop to get all of the pictures, neither the swipe nor the loop work (http://jsfiddle.net/MichelleGlauser/CR329/4/). Maybe I need to go about this a different way that I haven't thought of yet. I've tried several different versions and this is what I'm at now:
$(document).ready(function sort_options() {
var cafe = 'url("http://i1360.photobucket.com/albums/r653/brylans2013/Brylans%20Cafe%20Advertisment/9f34ef72-615e-45e9-a182-ec0c670f63a6_zps7d960dc7.jpg") no-repeat; background-position: center; background-size: cover;;';
var buffet = 'url("http://i1037.photobucket.com/albums/a452/drmadvertising/Peninsula%20Papers/Peninsula%20Puzzles/HibachiGrillPuzz.jpg") no-repeat; background-position: center; background-size: cover;;';
var fastfood = 'url("http://i242.photobucket.com/albums/ff231/bour3/things%20I%20made%20then%20ate/hamburger.jpg") no-repeat; background-position: center; background-size: cover;;';
var options = [cafe, buffet, fastfood];
for (var i = 0; i < options.length; i++)
$("#test").attr("background", i);
$(function() {
//Keep track of how many swipes
var count=0;
//Enable swiping...
$("#test").swipe( {
//Generic swipe handler for all directions
swipe:function(event, direction, distance, duration, fingerCount) {
if(direction=='left') {
$('#choice').text("Not this one." );
}
else if(direction=='right') {
$('#choice').text('Glad you like it.');
}
},
//Default is 75px, set to 0 for demo so any distance triggers swipe
threshold:0
});
});
});)
How can I get this code working?

I found a different solution that works involving no loops (not sure why they where there) but it just uses a function when scrolled to move the image to the next in the array. Basically adding the following code to your first example.
//Stripped CSS Styling leaving only URL
var cafe = 'http://i1360.photobuck...uzz.jpg';
var buffet = 'http://i1477.photobuck...erg.jpg';
var fastfood = 'http://i185.photobuck...grz.jpg';
var options = [cafe, buffet, fastfood];
var selectedoption = 0;
//Programatically set the first image
$('#test').css('background-image', "url('" + options[selectedoption] + "')");
Once the user swipes I increment the selectedoption (and if its on the last option return to start)
if (selectedoption == options.length) {
selectedoption = 0;
} else {
selectedoption++;
}
then after your if(direction=="left") code block I added the code to change images
$('#test').css('background-image', "url('" + options[selectedoption] + "')");
Here is a working JSFiddle
I would also recommend preloading the images, as im sure you will realise they are taking time to load.

Related

How to make autosliding carousel thumbnail change background image when active

my question has 3 parts. Any assistance with any part of this JS problem would be greatly appreciated. I am attempting to learn and comprehend JS by trial and error.
I've created this nice looking travel landing page, https://portfolioprime.github.io/Nature%20carousel/glidejs.html with a thumbnail carousel which uses Glide.js, which is really cool and works well. The carousel moves to the left and has arrow buttons to manually control the slide.
But I've been trying to implement a vanilla JS carousel slider,but I am failing miserably. Been struggling for 2 days and the best I can achieve is getting a single carousel item moving left and right. See https://portfolioprime.github.io/Nature%20carousel/.
What I'd like is to get the carousel sliding left automatically, with arrow buttons to manually control the slider.
I'm targeting all the carousel-items with querySelectorAll('.carousel-items') and adding left:-274px to the carousel container glide__slides.
Here's my JS code.
// var & event-listener buttons
document.querySelector(".left").addEventListener("click", slideLeft);
document.querySelector(".right").addEventListener("click", slideRight);
// Function slide left
function slideLeft(left) {
document.querySelector('.glide__slides').style.left = left;
}
// Function slide left
function slideRight(right) {
document.querySelector('.glide__slides').style.left = right;
}
Secondly, I'd like to have an active carousel-item, which when active automatically changes the background Image.
Right now I have the hero.style.background = var; and I've got it changing onclick with onclick = function('01.jpg') on each carousel item.
Here's the code.
// Change Hero Img
function heroChange(hmmm) {
var hero = document.querySelector('.hero');
hero.style.background = hmmm;
}
So I guess I would add EventListeners to the carousel-items and add an active class to the carousel-item like so,
var slides = document.querySelectorAll('.carousel-items');
function changeBgImg() {
slides.forEach(s => s.classList.remove('active');
this.classList.add('active');
//change the bg image === this
//But I have no idea how to do that
}
Thirdly I've got the content, background and carousel indicators using the same functions above but it seems like really dirty code. The HTML has each .carousel-item, there are ten of them, calling 4 functions each. It looks like this:
<div class="glide hero-carousel">
<div class="glide__track" data-glide-el="track">
<ul class="glide__slides">
<li class="glide__slide carousel-item"
onclick="heroChange('url(images/02.jpg) bottom/cover no-repeat');
number('01');
h4('Destination Shire');
h1('Valley<br> of Dreams');">
<div class="carousel-text">
<p>Destination Shire</p>
<h3>Valley<br> of Dreams</h3>
</div>
</li>
<li class="glide__slide carousel-item"
onclick="heroChange('url(images/03.jpg) bottom/cover no-repeat');
number('02');
h4('Destination Westwood');
h1('Misty<br> Woodlands');">
<div class="carousel-text">
<p>Destination Westwood</p>
<h3>Misty<br> Woodlands</h3>
</div>
</li>
</ul>
</div>
</div>
So it looks pretty yucky. It works though, but I would love to find a more elegant way of achieving this by putting all of these functions into one function that does each part in sequence.
Lastly, I'd want to get transition on-click animations going but that's another kettle of fish entirely.
So that's it. Whew!
Thanks for taking the time guys, I appreciate it. Any help you can provide is going to make me a better designer. There are actually a bunch of projects I have will benefit from the answers.
If you can provide help with at least Part 2 & 3: cleaning up the code into 1 function and getting the bg-image changing on the active class that would be a big big help.
There's just so much that JS can do and I'm not finding the answers on Google and youTube.
Thank you again.
An Update:
I have edited the slider by by using margin-left as shown by this question:
vanilla javascript carousel not sliding
// var & event-listener buttons
document.querySelector(".left").addEventListener("click", slideLeft);
document.querySelector(".right").addEventListener("click", slideRight);
let marginLeft = 0;
const slides = document.querySelector('.glide__slides');
// Function slide left
function slideLeft() {
marginLeft += 264;
slides.style.marginLeft = marginLeft + 'px';
console.log(getComputedStyle(slides).marginLeft);
}
// Function slide Right
function slideRight() {
marginLeft -= 264;
slides.style.marginLeft = marginLeft + 'px';
console.log(getComputedStyle(slides).marginLeft);
}
This has now got the carousel moving manually 1 slide at a time.
Still not fully understanding why my previous code above didn't work. If anyone can explain that to me that would be great.
I'm still left with some issues:
Autosliding and looping at the end of the slides.
Having the active slider change the background automatically. At this point it only changes onclick.
Finding a way to tidy up the function calls and functions.
The question asks for various ideas on how to simplify code and how to use native JavaScript to create a slider that rolls continuously.
The code originally used glider and it may be something simpler would be sufficient to get the desired result, for example using animationend event to change the background when a slide gets to the left hand side. However, eating the elephant slowly I'll tackle the yucky code (part 3) first.
Although the HTML looks rather daunting, 4 calls on a click for every li element for example, it is currently what is required so let's investigate creating it at run time. This gives us more easily maintainable code. For example, if we want to remove a slide, or alter the order of slides or add one we can just alter the slider array defined below and JavaScript will do the rest.
Part 1 of the question asked about sliding. We slide the whole ul element using CSS animation defined something like this, where 33vw is the total width of a slide (inc. margins/padding)
#keyframes sliding0 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
and we add an event listener to the element to trap animationend events because when the ul has slid one slide's width we want to change the hero image, and we want to put the slide that has just disappeared onto the back of the infinie sliding will work. We then set the animation running again.
See the snippet for details on how this and other events are dealt with. It also shows how the changeHero function can work which was part 2 of the question. Note, the snippet works more or less in the SO environment, though occasionally hover action is partially ignored. Running the code on your own machine it should be fine though.
<!DOCTYPE html>
<html>
<head>
<style>
#keyframes sliding0 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
#keyframes sliding1 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
body {
background-repeat: no-repeat no-repeat;
background-size: cover;
background-position: center center;
}
div .glide_track {
position: relative;
width: 100vw;
overflow-x: hidden;
}
ul {
position:relative;
left: 0;
width: 330vw;
height:100vh;
animation-name: sliding0;
animation-duration: 3s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-timing-function: linear;
margin: 0;
padding: 0;
list-style-type: none;
}
li {
position: relative;
left:0;
top:0;
float:left;
width: 32vw;
height:30vw;
display: inline-block;
margin: 0;
margin-right: 1vw;
padding: 0;
background-size: cover;
background-repeat: no-repeat no-repeat;
background-position: center center;
}
</style>
</head>
<body>
<script>
// we put the two lots of text and the image url for each slide in an array in the order they are to be shown
// this makes it easier to maintain when you want to add or remove a slide or change their order
// we only have one slider at the moment but this makes it more general
// these are the offsets in the array describing a slide. Done as indexes rather than named as easier to set up sliders array
const img = 0;
const text1 = 1;
const text2 = 2;
const sliders = [
[
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams']
]
];
// go through each slider and create its outer divs and its ul element
sliders.forEach(createSlider);
function createSlider(slider,sliderno) {
const div1 = document.createElement('DIV');
const div2 = document.createElement('DIV');
const ul = document.createElement('UL');
div1.classList.add("glide","hero-carousel");
div2.classList.add("glide_track");
div2.setAttribute("data-glide-el","track");
div1.appendChild(div2);
div2.appendChild(ul);
document.body.appendChild(div1);
ul.classList.add("glide__slides");
ul.addEventListener("animationend", animationEnd);
slider.forEach(createLi);
function createLi(slide,slideNo) {
const li = document.createElement('LI');
li.classList.add("glide__slide","carousel-item");
li.style.backgroundImage='url('+slide[img]+')';
li.addEventListener("click",slideClicked);
li.addEventListener("mouseover",slideHovered);
li.addEventListener("mouseout",slideUnhovered);
li.setAttribute('data-slideno','0' + slideNo);//! needs generalising if you have >10 slides !
ul.appendChild(li);
const div = document.createElement('DIV');
const p = document.createElement('P');
const h3 = document.createElement('H3');
p.innerHTML = slide[text1];
div.appendChild(p);
h3.innerHTML = slide[text2];
div.appendChild(h3);
li.appendChild(div);
}
}
// this is for testing, in real version use whatever required (i.e. whichever element is to have the hero image)
function ahHeroChange(backgroundImage) {
document.body.style.background = backgroundImage + " bottom/cover no-repeat";
}
function slideClicked(event) {
var slide = event.target;
var slideNo = slide.getAttribute('data-slideno');
// make the hero image the same as the slide's
ahHeroChange(slide.style.backgroundImage);
/* I don't know what these functions do - they were executed in the original on a click
number(slideno);
h4(slide.firstElementChild.querySelector('p').innerHTML);// text1 of the slide is passed to h4
h1(slide.firstElementChild.querySelector('h3').innerHTML;// text2 of the slide is passed to h1
*/
}
function slideHovered(event) {
var slide = event.target;
var slider = slide.parentElement;
slider.style.animationPlayState = 'paused';
ahHeroChange(slide.style.backgroundImage);
}
function slideUnhovered(event) {
var slide = event.target;
var slider = slide.parentElement;
//restore the hero image to the first one in the slider
ahHeroChange(slider.firstElementChild.style.backgroundImage);
//get the animation running again
slider.style.animationPlayState = 'running';
}
function animationEnd(event) {
//find the element that was clicked (it will be a ul element representing a slider)
var slider = event.target;
//take the first slide off the list and put it back at the end
slider.append(this.firstElementChild);
//change the hero image to the slide which is now the leftmost - use modified heroChange in the final version
document.body.style.backgroundImage = this.firstElementChild.style.backgroundImage;
// toggle the animationName (to an identical keyframes action) to force the animation to start again
slider.style.animationName='sliding'+(Number(event.animationName.replace('sliding',''))+1)%2;
}
</script>
</body>
</html>

scroll to a div when scrolling, and scroll to top when div disappear

I have 2 divs on my webpage. first div is "#pattern" (red one), and second on is "#projets".(blue one)
when use scrolls for the first time, the window scrolls automaticaly to the the second div "#projets". I'm using jquery scroll-To plugin.
it works nice, even if when the users scroll with a large amount of scroll there could be on offset from the "#projets" div... If someone has an idea to correct this would be nice, but that's not my main trouble...
Now i'm trying to scroll back to the top of the page ("#pattern" div) as soon as "#pattern" div reappears when scrolling, the red one. so basically it should be as soon as the offset from the top of my screen of my div "#projets" is supperior to 1.
I've tried so many solutions without results, using flags, multiple conditions... it can be the same kind of thing as on this page, but user should be abble to scroll freely inside the page, not scrolling from hash to hash :
http://www.thepetedesign.com/demos/onepage_scroll_demo.html
here is my html :
<div id="pattern"></div>
<div id="projets"></div>
my css :
#pattern {
height:300px;
width: 100%;
background-color:red
}
#projets {
height:800px;
width: 100%;
background-color:blue
}
and my jquery :
var flag=0 ;
$(window).on('scroll',function(){
var top_projets_position = $("#projets").offset().top - $(window).scrollTop();
if((flag==0) && $(window).scrollTop()>1){
$(window).scrollTo('#projets', 500);
flag=1;
}
if($(window).scrollTop()==0){
flag=0;
}
});
here is jsfiddle :
http://jsfiddle.net/jdf9q0sv/
hope someone can help me with this, I can't figure out what I'm doing wrong, maybe a wrong method ! thanks
It looks like you need to track 3 things:
The scroll direction occurs.
The area you are currently viewing.
If scroll animation is currently happening (we need to wait until it's done, or problems will occur).
http://jsfiddle.net/vx69t5Lt/
var prev_scroll = 0; // <-- to determine direction of scrolling
var current_view ="#pattern"; // <-- to determine what element we are viewing
var allowed = true; // <-- to prevent scrolling confusion during animation
var top_projets_position = $("#projets").offset().top + 1;
$(window).on('scroll',function(){
var current_scroll = $(window).scrollTop();
if(current_scroll < top_projets_position && current_view=="#projets" && current_scroll < prev_scroll){
scrollToTarget("#pattern");
}
if($(window).height() + current_scroll > top_projets_position && current_view=="#pattern" && current_scroll > prev_scroll){
scrollToTarget("#projets");
}
prev_scroll = current_scroll;
});
function scrollToTarget(selector){
if(allowed){
allowed = false;
$(window).scrollTo(selector, {
'duration':500,
'onAfter': function(){ allowed = true; current_view = selector;}
});
}
}
This is just a quick solution based on your original code. A better solution would be to do something more Object Oriented (OOP) and track values in an object. Perhaps take an array of elements on object creation, grab all the boundaries and use the boundaries in your scroll handler to determine when to scroll to the next div.

how to change background images with fade

so far (with the help of this comm :)) I created a full viewport background, thats able to switch on click.
Since I'm a beginner I have two questions:
1) Is the code "good", or did I wrote it to complicated?
and the Mainquestion:
How can I put a fade effect into my code? Now it's kinda ugly, because the images are loading slow (stuttering). I imagine something like this:
Image--Click--Fading black--Fading in new Image--Click--Fading black---Fading in new Image--..
Here is the code I wrote:
HTML:
<div class="t1">
</div>
CSS:
.t1 {
background: url(pics/homescreen.JPG) no-repeat center center fixed ;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width: 100%;
height: 100%;
}
jQuery:
$(function () {
var y = 1;
$('.t1').click(function () {
var x = ['url(pics/screen1.jpg) no-repeat center center fixed',
'url(pics/screen2.jpg) no-repeat center center fixed',
'url(pics/schild.jpg) no-repeat center center fixed'
]
$('.t1').css('background', x[y]);
$('.t1').css('background-size', 'cover');
if (y == 2) {
y = 0;
} else {
y = y + 1;
}
});
})
Demo: http://jsfiddle.net/bSAm2/
This doesn't include preloading, but the effect is quite nice.
If you are interested in a preloader, you probably want to preload images one at a time, when they are needed: loading all images upfront or worse in the head of your document, will likely slow down page loading beyond what's an acceptable UX.
Also, transition won't work on older browsers (see here)
To animate CSS properties, you can use http://api.jquery.com/animate/
In particular, you can fade out the current image by animating its opacity (to 0), then, when this animation is completed change the image source (while it is not visible) and start the fade-in animation.
For best appearance, you can preload images "Just in Time", for example you can preload the next image to show, so there won't be any latency
EDIT
This example works, and uses closure so that you can have multiple images rotating independently:
$(function () {
var images = ['url(http://lorempixel.com/output/people-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/nature-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/fashion-q-c-640-480-9.jpg) no-repeat center center fixed'
];
function bindSwitcher (elem) {
var imageIndex = 0;
return function switchImage () {
elem.fadeOut(function (){
elem.css('background', images[imageIndex]);
if (imageIndex == images.length - 1) {
imageIndex = 0;
} else {
imageIndex += 1;
}
elem.css('background-size', 'cover');
elem.fadeIn();
});
};
}
var imageSwitcher = bindSwitcher($('#t1'));
$('#t1').click(imageSwitcher);
$('#t2').click(bindSwitcher($('#t2')));
});
And the HTML, with a little change to show the difference:
<div id="t1" class="t1" style="position: absolute; left:0%">
</div>
<div id="t2" class="t1" style="position: absolute; left:50%">
</div>
Demo: http://jsfiddle.net/abhitalks/FNUx8/8/
Is the code "good", or did I wrote it to complicated?
A couple of things which you could do is:
Take your image array outside of click handler. You woudn't want to create that array every time a click happens.
Reduce the code to cycle the array by using a modulus.
Refer to the element using this.
Use an id instead of class to target the element directly if that is unique.
So, effectively your code reduces to:
var x = ['url(...1.jpg) no-repeat center center fixed',
'url(...2.jpg) no-repeat center center fixed',
'url(..3.jpg) no-repeat center center fixed'
];
var index = 0;
$('#t1').click(function () {
index = (index + 1) % x.length;
$(this).css('background', x[index]);
});
How can I put a fade effect into my code? Now it's kinda ugly, because
the images are loading slow (stuttering)
(1.) You can put a fade effect using CSS3 transition:
#t1 {
...
transition: 1s;
}
(2.) There is stuttering because the images are loaded at runtime. You could avoid that by pre-loading images:
One way could be like this:
var d = []; // create an array for holding dummy elements
for (var i = 0; i < x.length; i++) {
d[i] = $("<img>"); // create an img and add to the array
d[i].attr('src', x[i]).hide(); // add src to img and hide it
$("body").append(d[i]); // add the img to body to start load
}
Ideally wrap this code in the head so that this is done by the time DOM is ready. Put rest of your code either wrapped in body at the end or in .ready.
Edit:
Changed the preloading code to use img. Updated the fiddle.
The code is not complicated, in time you'll learn to write cleaner (good) code. Here is my suggestions:
1. move the x definition outside the click event, put it right after y and y should be 0 initially;
2. if(y == 2) is too static, beter take the length of the array if(y == x.length);
3. remove background-size from script, it's set in css;
4. For fade effect you can do something like this:
$('.t1').fadeOut(300, function() {
$(this).css('background', x[y]).fadeIn(300);
});
I haven't tested it, but should do the job.

Loop with trigger (which contains animation) not working

So I seem to have run into a bit of a dead end. I'm making a page which has an image slider. The slider has three images, one centered on the screen, the other two overflow on the left and right. When you click on the button to advance the slides it runs this code....
$('#slideRight').click(function() {
if ($('.container').is(':animated')) {return false;}
var next=parseInt($('.container img:last-of-type').attr('id')) + 1;
if (next == 12) {
next = 0;
}
var diff = galsize() - 700;
if ($('.thumbs').css("left") == "0px") {
var plus = 78;
} else {
var plus = 0;
}
var app='<img id="' + next + '" src="' + imgs[next].src + '">';
$('.container').width('2800px').append(app);
$('.container').animate({marginLeft: (diff + plus) + "px"}, 300, function() {
$('.container img:first-of-type').remove();
$('.container').width('2100px').css("margin-left", (galsize() + plus) + "px");
});
}); // end right click
This works just fine, not a problem..... I also have an interval set up to run this automatically every 5 seconds to form a slideshow...
var slideShow = setInterval(function() {
$('#slideRight').trigger("click");
}, 5000);
This also works perfectly, not a problem.... However my problem is this.... I have thumbnails, when you click on a thumbnail, it should run this code until the current picture is the same as the thumbnail.... here is the code....
$('img.thumbnail').click(function() {
clearInterval(slideShow);
var src = $(this).attr("src");
while ($('.container img:eq(1)').attr('src') != src) {
$('#slideRight').trigger("click");
}
});
When I click on the thumbnail nothing happens... I've used alert statements to try and debug, what ends up happening is this....
The while loop executes, however nothing happens the first time. The slide is not advanced at all. Starting with the second execution, the is('::animated') is triggered EVERY TIME and the remainder of the slideRight event is not executed...
So my first problem, can anyone shed some light on why it doesn't run the first time?
And my second question, is there any way to wait until the animation is complete before continuing with the loop?
Any help would be appreciated. Thank you!
I'm going to start with the second part of your question, regarding completing the animation before continuing with the loop.
I have done something similar in the past, and what I did was set two global variables to control the animation. One variable is for how long you want the period to be, the other is a counter for how much time since the last loop.
So, for example:
$timeToChange = 5; // in Seconds
$timeSinceReset = 0; // also in Seconds
Set your interval for one second and call a new function (autoAdvance()):
var slideShow = setInterval(function() {
autoAdvance();
}, 1000); // only one second
and then use the counter variable to count each time the interval is called (each second). Something like:
function autoAdvance(){
if($timeSinceReset == $timeToChange){
$timeSinceReset = 0;
$('#slideRight').trigger("click"); // execute click if satisfied
}
else{$timeSinceReset++;}
}
To stop from looping until the animation is done, reset $timeSinceReset back to 0 (zero) when you click on the thumbnail. Something like:
$('#thumbnail').click(function(){
$timeSinceReset = 0;
});
That'll give you a nice 5 second buffer (or whatever you set $timeToChange) before the loop continues.
As for the first part of your question, grab the number of the particular thumbnail, and use that to scroll to the appropriate image. Something like:
$('.thumb').click(function (each) {
$childNumber = $(this).index();
});
which you cansee in this fiddle. Click in one of the grey boxes and it'll tell you which one you clicked in. Use that info to scroll to the appropriate image (1, 2 or 3 if you only have three images).
Hope this helps.
Here is a full solution for one possible way of doing it at this fiddle.
HTML:
The top container holds the images. In this particular example I've included three, using divs instead of images. Whether you use images or divs doesn't change anything.
<div class="holder_container">
<div class="img_container">
<div class="photo type1">ONE</div>
<div class="photo type2">TWO</div>
<div class="photo type3">THREE</div>
</div>
</div>
.img_container holds all the images, and is the same width as the sum of the widths of the images. In this case, each image (.photo) is 150px wide and 50px tall, so .img_container is 450px wide and 50px tall. .holder_container is the same dimensions as a single image. When this runs, the .holder_container is set to hide any overflow while .img_container moves its position left or right.
Included also are two nav buttons (forward and back)
<div class="nav_buttons">
<div class="nav back"><<<</div>
<div class="nav forward">>>></div>
</div>
As well as three thumbnail images - one for each image in the top container
<div class="top">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
CSS:
Refer to the JS Fiddle for all CSS rules.
The most important are:
.holder_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 150px;
position: relative;
overflow: hidden;
}
.img_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 450px;
position: relative;
left: 0px;
top: 0px;
}
In the example, .type1, .type2 and .type3 are only used to color the image divs so you can see the animation. They can be left out of your code.
JavaScript:
The javascript contains the following elements…
Variables:
var timeToChange = 3; // period of the image change, in seconds
var timeSinceReset = 0; // how many seconds have passed since last image change
var currentImage = 1; // Which image you are currently viewing
var totalImages = 3; // How many images there are in total
Functions:
autoAdvance - called once every second via setInterval. Counts the number of seconds since the last image change. If the number of seconds that has passed is equal to the period, a function is called that switches the images.
function autoAdvance() {
if (timeSinceReset == timeToChange) {
timeSinceReset = 0;
moveNext();
} else {
timeSinceReset++;
}
}
moveNext() - moves to the next image. If the current image is the last (currentImage == totalImages) then currentImages is set back to 1 and the first image is displayed.
function moveNext(){
if(currentImage == totalImages){
currentImage = 1;
var newPos = 0 + 'px';
$('.img_container').animate({left: newPos}, 300);
}else{
currentImage++;
var newPos = -((currentImage-1) * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
}
}
Rest of code:
If one of the thumbs is clicked, move to the corresponding image.
$('.thumb').click(function (each) {
timeSinceReset = 0;
var childNumber = $(this).index();
currentImage = childNumber + 1; // child numbers are zero-based
var newPos = -(childNumber * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
});
If one of the navigation buttons is clicked, move accordingly. If "back" is clicked, move one image backwards (or to last image if currently on first). If "first" is clicked, move one image forwards (or to first image if currently on last).
$('.nav').click(function(){
timeSinceReset = 0;
if($(this).hasClass('back')){ // Back button
if(currentImage == 1){
currentImage = totalImages;
}else{
currentImage--;
}
}else{ // Forward button
if(currentImage == totalImages){
currentImage = 1;
}else{
currentImage++;
}
}
var newPos = -((currentImage-1) * 150) + 'px';
$('.img_container').animate({left: newPos}, 300);
});
Here is the link to the fiddle example.

Repeating an image based on div size

I have been working on a site that requires cross browser compatibility (including earlier IEs) and I have a sidebar that uses gradients but it turned out that it is about a million times easier to use a set background image, I have the height of the image repeating properly by taking the height of it based off the main container but I want to do the same the width of it.
I am aware of how to stretch the div based on the size of others but I want to know how I can have a conditional statement that will repeat the image y until the end of the div so it doesn't just move the set image!
I am achieving the height based repeating using this:
<script type="text/javascript">
var theHeight = $('#Container').height() - 260;
$('#SecondaryContent').css('min-height', theHeight);
</script>
I am attempting to use this code:
<script type="text/javascript">
var divWidth = $('#SecondaryContent').width() + 1;
if (divWidth.width() > 200) {
alert('hello');
$('#SecondaryContent').css('background', 'url(../images/background_slice.png)', 'repeat-x 18% 0%');
}
</script>
However it seems unable to find anything within the div.
these css may help
background-repeat: repeat; // repeats x and y
background-repeat: repeat-x; // repeats x
background-repeat: repeat-y; // repeats y
Just thought I would update that I managed to get this working using this:
<script type="text/javascript">
$(document).ready(function () {
divExpander();
divLineExpander();
divWindowLineExpander();
})
function divExpander() {
var theHeight = $('#Container').height() - 260;
$('#SecondaryContent').css('min-height', theHeight);
}
function divLineExpander() {
var theWidth = $('#SecondaryContent').width() + 2;
$('#Navigation').css('min-width', theWidth);
}
$(window).bind("resize", divWindowLineExpander);
function divWindowLineExpander(e) {
var theLineWidth = $('#SecondaryContent').width() + 1;
$('#Navigation').css('min-width', theLineWidth);
}
</script>

Categories

Resources