Responsive Carousel using Cycle2 - javascript

I'm working on a carousel using the cycle2 and cycle2-carousel plugins.
Found a solution here to display variable number of items depending on resized window width.
Problem is the carousel breaks due to another slideshow.
Everything is working until the main slideshow cycles it's first slide, then on page resize the carousel only displays one slide.
Demo
http://jsfiddle.net/yDRj4/1/
jQuery
function buildCarousel(visibleSlides) {
$('.caro').cycle({
fx: 'carousel',
speed: 600,
slides: 'img',
carouselVisible: visibleSlides,
carouselFluid: true
});
}
function buildSlideshow() {
$('.home-slideshow').cycle({
fx: 'fade',
slides: 'img',
timeout: 12000
});
}
function initCycle() {
var width = $(document).width();
var visibleSlides = 5;
if ( width < 400 ) {visibleSlides = 1}
else if(width < 700) {visibleSlides = 3}
else {visibleSlides = 5};
buildSlideshow();
buildCarousel(visibleSlides);
}
function reinit_cycle() {
var width = $(window).width();
var destroyCarousel = $('.caro').cycle('destroy');
if ( width < 400 ) {destroyCarousel;reinitCycle(1);}
else if ( width > 400 && width < 700 ) {destroyCarousel; reinitCycle(3);}
else {destroyCarousel;reinitCycle(5);}
}
function reinitCycle(visibleSlides) {
buildCarousel(visibleSlides);
}
var reinitTimer;
$(window).resize(function() {
clearTimeout(reinitTimer);
reinitTimer = setTimeout(reinit_cycle, 100);
});
$(document).ready(function(){
initCycle();
});
HTML
<div class='main' style="max-width: 950px;margin: auto;">
<div class="home-slideshow" style="margin-bottom: 150px;">
<img style="width: 100%" src="http://placehold.it/950x250" alt="">
<img style="width: 100%" src="http://placehold.it/950x250" alt="">
</div>
<div class="caro" >
<img src="http://placehold.it/300x300" alt="">
<img src="http://placehold.it/300x300" alt="">
<img src="http://placehold.it/300x300" alt="">
<img src="http://placehold.it/300x300" alt="">
<img src="http://placehold.it/300x300" alt="">
<img src="http://placehold.it/300x300" alt="">
</div>
</div>

For some reason, after the first slideshow transitions, when it recreates the Carousel, it is setting all of the images to have an opacity of 0.
Adding $('.caro img').css('opacity','1'); after initializing the carousel fixed it, but I'm sure there is a better solution for this, but you might have to dig into the source of the plugin.
http://jsfiddle.net/cZTxM/2/

You have the following line:
var destroyCarousel = $('.caro').cycle('destroy');
...which sets destroyCarousel to the result of that method call (a jQuery object), instead of creating a function you can call to perform the destruction.
I think this is what you meant to do:
function reinit_cycle() {
var width = $(window).width();
var destroyCarousel = function() { // create a function
$('.caro').cycle('destroy');
}
if (width < 400) {
destroyCarousel(); // call the function
reinitCycle(1);
} else if (width > 400 && width < 700) {
destroyCarousel();
reinitCycle(3);
} else {
destroyCarousel();
reinitCycle(5);
}
}
http://jsfiddle.net/mblase75/7eAk2/

Related

Javascript Images Cycle on Hover

I'm new to coding and would like to adapt a code I got from CodePen for my website.
It is to hover over an image and the images below will automatically cycle.
However this code works for only one set of images and doesn't work if I have two sets of images.
I would really like to learn why please??? Thank you.
<html>
<style>
.js-animated figure.active {
opacity: 1;
}
.image-deck {
position: relative;
height: 12rem;
width: 18rem;
}
.image-deck figure {
opacity: 0;
height: 100%;
width: 100%;
position: absolute;
}
.image-deck figure img {
height: 100%;
width: 100%;
}
</style>
<body>
<!--Working-->
<div class="image-deck js-animated">
<figure>
<img src="https://picsum.photos/300/300">
</figure>
<figure>
<img src="https://picsum.photos/301/301">
</figure>
<figure>
<img src="https://picsum.photos/302/302">
</figure>
<figure>
<img src="https://picsum.photos/303/303">
</figure>
</div>
<!--Not Working-->
<div class="image-deck js-animated">
<figure>
<img src="https://picsum.photos/304/304">
</figure>
<figure>
<img src="https://picsum.photos/305/305">
</figure>
<figure>
<img src="https://picsum.photos/306/306">
</figure>
<figure>
<img src="https://picsum.photos/307/307">
</figure>
</div>
</body>
<script>
// get the image wrapper
const imageDeck = document.querySelector(".image-deck.js-animated");
// get the set of images within the wrapper
const images = imageDeck.children;
// reveal the first image
images[0].classList.add("active");
// set up the iterator
let i = 0;
// set up the function that we will call from our repeater
function cyclePhotos() {
// remove the active class from the current image
images[i].classList.remove("active");
// if the iterator is less than the total number of images
// go to the next number, otherwise reset to 0
i = i + 1 < images.length ? i + 1 : 0;
// add the active class to the next image
images[i].classList.add("active");
}
// instantiate the repeater
let repeater;
// when you hover over the image wrapper, start the reapeater
// repeat every 500ms
imageDeck.addEventListener("mouseover", (e) => {
repeater = setInterval(cyclePhotos, 500);
});
// when you are no longer hovering, clear the repeater
imageDeck.addEventListener("mouseout", (e) => {
clearInterval(repeater);
});
</script>
</html>

Animated gif alternative using jQuery to animate an image sequence

I put together this very simple jQuery code to animate a sequence of images. It works perfectly. you can view it here.
But now I am trying to update the code so it could work on multiple image sequences at once as long as it has its own class that is referenced in the jQuery code. So I updated it - view below. Unfortunately my updates are not working. Can you guys help me resolve this issue? Thank you in advance!
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let currentImg = 0;
function changeImg(allImg){
$(allImg[currentImg]).fadeOut(0, function(){
if(currentImg == allImg.length -1){
currentImg = 0;
}else {
currentImg++;
}
$(allImg[currentImg]).fadeIn(0)});
}
setInterval(changeImg(aniOne), 0050);
setInterval(changeImg(aniTwo), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>
As Chris G stated above:
The working code uses setInterval(changeImg, 50) which will work fine. The problem with your current attempt is setInterval(changeImg(aniOne), 50) which evaluates to a call to changeImg(aniOne), then a call to setInterval(undefined, 50) (since changeImg doesn't return anything). If you want this to work, you need to make changeImg into a function that returns a function. – Chris G
After we add these problems, we then have the issue of both animations sharing the currentImg variable, so instead I made two different variables and passed them along with the images. You can handle this many different ways.
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let num1 = 0;
let num2 = 0;
function changeImg(allImg, num){
function main(){
$(allImg[num]).fadeOut(0, function(){
if(num == allImg.length -1){
num = 0;
}else {
num++;
}
$(allImg[num]).fadeIn(0)});
}
return main;
}
setInterval(changeImg(aniOne, num1), 0050);
setInterval(changeImg(aniTwo, num2), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>

jQuery append for each item

I'm moving divs around based on a responsive layout that requires them to be in different places at different viewports. In the below example I want them to move as so, they do as expected... except, when I have more than one 'release' div on the page it takes each 'soundcloud' div and appends it to each 'release'. So if I have 3 'release' divs each one has 3 'soundcloud' divs. How can I edit the code so that the 'soundcloud' div within each 'release' is appended and nothing else.
$(function () {
var mobile = false;
var desktop = false;
var $window = $(window);
function checkWidth() {
var windowsize = $window.width();
if (windowsize <= 1024) {
if (!mobile) {
$(".release .soundcloud").appendTo(".release .info");
}
mobile = true;
desktop = false;
} else {
if (!desktop) {
$(".release .soundcloud").appendTo(".release .show-hide");
}
mobile = false;
desktop = true;
}
}
checkWidth();
$(window).resize(checkWidth);
});
Edited to add HTML:
<div class="release clearfix">
<span class="show-details open-close">➕</span>
<figure class="artwork">
<img src="assets/images/artwork1.jpg" alt="Album Artwork">
</figure>
<div class="info">
<h1 class="title">Title</h1>
<div class="soundcloud">
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/12345678"></iframe>
</div>
</div>
<div class="show-hide">
<div class="options clearfix">
<p>£9.99</p>
<p><span></span>Buy</p>
</div>
<div class="tracks">
<h3>Tracklisting</h3>
<ul>
<li>Track 1</li>
</ul>
<h3>Produced by</h3>
<p>Author</p>
</div>
<div class="further-info">
<h3>Release Date</h3>
<p>14/12/2013</p>
</div>
</div>
</div>
As #Cuberto mentioned it is not a good idea to achieve it using javascript.
But to try it out you can iterate over each release element and perform the append for the corresponding child elements inside the release div.
function checkWidth() {
var windowsize = $window.width();
var $releaseDivs = $('.release');
if (windowsize <= 1024) {
if (!mobile) {
$('.release').each(function() {
$('.soundcloud', this).appendTo($('.info', this));
});
}
mobile = true;
desktop = false;
} else {
if (!desktop) {
$('.release').each(function() {
$('.soundcloud', this).appendTo($('.show-hide', this));
});
}
mobile = false;
desktop = true;
}
}
I have not tried it but you can try this
#media (max-width: 1024px) {
.hide-mobile {
display: none;
}
}
HTML
<div class="soundcloud hide-mobile">
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/12345678"></iframe>
</div>

How do I create a JQuery content slider that uses 4 images to navigate rather than text?

I have for images with a number on it. Those numbers are 1-4. I want to place them numerically and when the user clicks on 1, i want them to go to slide 1 and if they click on 2, then slide 2. This also needs to have a sliding effect.
I am using this particular javascript code below for left and right options but i am not sure if I can re-use this for my purpose:
HTML would be something like:
<img src="#" class="image_one">
<img src="#" class="image_two">
<img src="#" class="image_three">
<img src="#" class="image_four">
<div class="content_for_image_One" id="slide1">
You see this when you click on image 1
</div>
<div class="content_for_image_two" id="slide2">
You see this when you click on image 2
</div>
<div class="content_for_image_three" id="slide3">
You see this when you click on image 3
</div>
<div class="content_for_image_four" id="slide4">
You see this when you click on image 4
</div>
<script type="text/javascript">
$(document).ready(function () {
var $sliderMask = $('#slider_mask');
var $slideContainer = $('#slide_container');
var $slides = $slideContainer.find('.slide');
var slideCount = $slides.length;
var slideWidth = $sliderMask.width();
$slideContainer.width(slideCount * slideWidth);
$slides.width(slideWidth);
var currentSlide = 0;
function animate() {
$slideContainer.stop().animate({ marginLeft: -(currentSlide * slideWidth) + 'px' }, 'slow');
}
$('#left_button').on('click', function () {
currentSlide = (currentSlide - 1 + slideCount) % slideCount;
animate();
});
$('#right_button').on('click', function () {
currentSlide = (currentSlide + 1) % slideCount;
animate();
});
$('#click_left').on('click', function () {
currentSlide = (currentSlide - 1 + slideCount) % slideCount;
animate();
});
$('#click_right').on('click', function () {
currentSlide = (currentSlide + 1) % slideCount;
animate();
});
});
</script>
Your provided html does not fit to your code, but let's assume you have the following html:
<div id="slidesWrapper">
<div id="slidesContainer">
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
</div>
</div>
<div id="thumbnails">
<img src="#" class="thumb" />
<img src="#" class="thumb" />
<img src="#" class="thumb" />
<img src="#" class="thumb" />
</div>
with the following css:
#slidesWrapper {
width: 1000px;
height: 400px;
overflow: hidden;
position: relative;
}
#slidesContainer {
width: auto;
position: aboslute;
}
.slide {
float: left;
height: 400px;
}
you could use something like:
(function($){
$(function() {
var wrapper = $('#slidesWrapper'),
container = $('#slidesContainer'),
slides = container.children(),
thumbs = $('#thumbnails').children();
container.css('left', '0');
thumbs.click(function() {
var index = $('thumbnails').children().index(this);
container.stop().animate({
left: '-' + slides.eq(index).position().left + 'px'
}, 1000);
});
});
})(jQuery);
its not tested though and I dont quite get what you want. This example fits if you have a wrapper with slides in it and only one can be visible, fixed width and height
function next()
{
var mar=$("#img_ul").css("margin-left");
var nm=mar.replace("px","");
if(nm==0)
{
$("ul").animate({"marginLeft":"-500px"},"slow");
}
else if(nm>0 || nm!=-2000)
{
nm=nm-500;
$("ul").animate({"marginLeft":nm+"px"},"slow");
}
else if(nm==-2000)
{
$("ul").animate({"marginLeft":"0px"},"slow");
}
}
function previous()
{
var mar=$("#img_ul").css("margin-left");
var nm=mar.replace("px","");
if(nm==0)
{
$("ul").animate({"marginLeft":"-2000px"},"slow");
}
else
{
nm=+nm + +500;
$("ul").animate({"marginLeft":nm+"px"},"slow");
}
}
</script>
</head>
<body>
<div id="slide_wrapper">
<ul id="img_ul">
<li>
<q>
Learn everything you can, anytime you can, from anyone you can there will always come a time when you will be grateful
you did.
</q>
</li>
<li>
<q>
Make it simple. Make it memorable. Make it inviting to look at. Make it fun to read.
</q>
</li>
<li>
<q>
If plan A fails, remember there are 25 more letters.
</q>
</li>
<li>
<q>
Do not go where the path may lead, go instead where there is no path and leave a trail.
</q>
</li>
<li>
<q>
A journey of a thousand miles must begin with a single step.
</q>
</li>
</ul>
</div>
<input type="button" id="previous" value="Previous" onclick="previous();">
<input type="button" id="next" value="Next" onclick="next();">
code from TalkersCode complete tutorial here http://talkerscode.com/webtricks/content-slider-using-jquery-and-css.php

Loading images asynchronously when in viewport in div with overflow: scroll;

I have this structure for my content:
<div id="content" style="overflow:scroll;height:500px; width: 500px;">
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/user1/picture?width=50&height=50'>
</div>
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/user2/picture?width=50&height=50'>
</div>
...
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/userN/picture?width=50&height=50'>
</div>
</div>
So basically I have a div with overflow:scroll; which contains pictures of all the Facebook user's friends. For performance reasons, I think it's better to load images when they become visible in the viewport. I've tried everything including jquery.lazyload but I think because the images are inside my div with overflow:scroll the plugin doesn't function correctly.
I used this post to elaborate the following code.
First of all change your html to get image only from the first:
<div id="content" style="overflow:scroll;height:100px; width: 100px;">
<div style="width:500px;height:100px;">
<img src='http://graph.facebook.com/user1/picture?width=50&height=50' />
</div>
<div style="width:500px;height:100px;">
<img msrc='http://graph.facebook.com/user2/picture?width=50&height=50'/>
</div>
...
<div style="width:500px;height:100px;">
<img msrc='http://graph.facebook.com/userN/picture?width=50&height=50'/>
</div>
</div>
Then use this js to trigger scroll event from #content div and check if all the image is visible:
$(function(){
var content = $("#content");
function isScrolledIntoView(elem)
{
var divViewTop = content.scrollTop();
var divViewBottom = divViewTop + content.height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= divViewBottom) && (elemTop >= divViewTop));
}
content.scroll(function(e){
content.find("img").each(function(i,e){
if(isScrolledIntoView(e)){
$(e).attr("src",$(e).attr("msrc"));
}
});
});
});
Please don't use this in production, the code should be optimized first.
Here is a link to the jsfiddle:
If you think its because of the divs, why not remove them:
<div id="content" style="overflow:scroll;height:500px; width: 500px;">
<img height='100' width='500' src='http://graph.facebook.com/user1/picture?width=50&height=50'>
<img height='100' width='500' src='http://graph.facebook.com/user2/picture?width=50&height=50'>
...
</div>

Categories

Resources