jQuery queue does not work - javascript

What I'm trying to accomplish:
Let multiple cards in the queue slide in after each other on document ready and for the elements that arent visible on page load I want the same for them on scroll.
The problem:
All elements slide in at the same time. (Even though I'm using an each loop)
Example:
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
What I did so far:
My markup looks like this:
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
And I want them so slide in after each other by using something like this:
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
I add a class that resets their css to normal, the elements have the transition property
This function is called like this
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
The isScrolledIntoView function is from stackoverflow and looks like this
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}

Some thoughts:
Remember that animations on separate elements run in parallel; each element has its own animation queues.
You've said that you had an issue when more elements come into view. That's because you weren't eliminating them from the selection of elements to animate.
Your if (elem.hasClass(animationClass)) check is unnecessary, as you've selected only elements that have that class.
So (see *** commented lines):
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0; // ***
$("." + animationClass).not("." + resetAnimationClass).each(function() { // ***
var elem = $(this);
// *** No `if (elem.hasClass(animationClass))` here, we know it does
if (isScrolledIntoView(elem) == true) {
++counter; // ***
elem.delay(500 * counter).queue(function() { // ***
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
$(document).ready(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0;
$("." + animationClass).not("." + resetAnimationClass).each(function() {
var elem = $(this);
if (isScrolledIntoView(elem) == true) {
++counter;
elem.delay(500 * counter).queue(function() {
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...

Related

Jquery ui double image slider single command

I'm trying to make a double image slider commanded by the same button, but, with the code I have, I can't find how to select two different elements or all the instance on an element
html:
<div class="slider-box">
<div class="slider" id="slider">
<div class="slider__item">
<img src="https://placeimg.com/960/540/animals" alt="">
<h2 class="slider__item__title">Slide 1 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/arch" alt="">
<h2 class="slider__item__title">Slide 2 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/nature" alt="">
<h2 class="slider__item__title">Slide 3 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/people" alt="">
<h2 class="slider__item__title">Slide 4 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/tech" alt="">
<h2 class="slider__item__title">Slide 5 Title</h2>
</div>
</div>
<div class="slider" id="slider">
<div class="slider__item">
<img src="https://placeimg.com/960/540/animals" alt="">
<h2 class="slider__item__title">Slide 1 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/arch" alt="">
<h2 class="slider__item__title">Slide 2 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/nature" alt="">
<h2 class="slider__item__title">Slide 3 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/people" alt="">
<h2 class="slider__item__title">Slide 4 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/tech" alt="">
<h2 class="slider__item__title">Slide 5 Title</h2>
</div>
</div>
</div>
<div class="slider-nav">
<div class="slider-nav__prev" id="prev"><i class="fa fa-angle-left"></i></div>
<div class="slider-nav__next" id="next"><i class="fa fa-angle-right"></i></div>
<div class="slider-nav__dots" id="dots"></div>
</div>
Js:
(function($) {
'use strict';
var pluginName = 'slider',
defaults = {
next: '.slider-nav__next',
prev: '.slider-nav__prev',
item: '.slider__item',
dots: false,
dotClass: 'slider__dot',
};
function slider(element, options) {
this.$document = $(document);
this.$window = $(window);
this.$element = $(element);
this.options = $.extend({}, defaults, options);
this.init();
}
slider.prototype.init = function() {
this.setup();
this.attachEventHandlers();
this.update();
}
slider.prototype.setup = function(argument) {
this.$slides = this.$element.find(this.options.item);
this.count = this.$slides.length;
this.index = 0;
this.$next = $(this.options.next);
this.$prev = $(this.options.prev);
this.$canvas = $(document.createElement('div'));
this.$canvas.addClass('slider__canvas').appendTo(this.$element);
this.$slides.appendTo(this.$canvas);
this.$dots = $(this.options.dots);
this.$dots.length && this.createDots();
};
slider.prototype.createDots = function() {
var dots = [];
for (var i = 0; i < this.count; i += 1) {
dots[i] = '<span data-index="' + i + '" class="' + this.options.dotClass + '"></span>';
}
this.$dots.append(dots);
}
slider.prototype.attachEventHandlers = function() {
this.$element.on('prev.slider', this.prev.bind(this));
this.$document.on('click', this.options.prev, (function(e) {
this.$element.trigger('prev.slider');
}).bind(this));
this.$element.on('next.slider', this.next.bind(this));
this.$document.on('click', this.options.next, (function(e) {
this.$element.trigger('next.slider');
}).bind(this));
this.$element.on('update.slider', this.update.bind(this));
this.$window.on('resize load', (function(e) {
this.$element.trigger('update.slider');
}).bind(this));
this.$element.on('jump.slider', this.jump.bind(this));
this.$document.on('click', ('.' + this.options.dotClass), (function(e) {
var index = parseInt($(e.target).attr('data-index'));
this.$element.trigger('jump.slider', index);
}).bind(this));
};
slider.prototype.next = function(e) {
this.index = (this.index + 1) % this.count;
this.slide();
};
slider.prototype.prev = function(e) {
this.index = Math.abs(this.index - 1 + this.count) % this.count;
this.slide();
};
slider.prototype.jump = function(e, index) {
this.index = index % this.count;
this.slide();
}
slider.prototype.slide = function(index) {
undefined == index && (index = this.index);
var position = index * this.width * -1;
this.$canvas.css({
'transform': 'translate3d(' + position + 'px, 0, 0)',
});
this.updateCssClass();
};
slider.prototype.update = function() {
this.width = this.$element.width();
this.$canvas.width(this.width * this.count);
this.$slides.width(this.width);
this.slide();
};
slider.prototype.updateCssClass = function() {
this.$slides
.removeClass('active')
.eq(this.index)
.addClass('active');
this.$dots
.find('.' + this.options.dotClass)
.removeClass('active')
.eq(this.index)
.addClass('active');
}
$.fn[pluginName] = function(options) {
return this.each(function() {
!$.data(this, pluginName) && $.data(this, pluginName, new slider(this, options));
});
};
})(window.jQuery);
$('#slider').slider({
prev: '#prev',
next: '#next',
dots: '#dots',
autoplay: true,
});
I'm a javascript noob, I understand what I'm reading/using, but not sure when it's time to write.
Here is my fiddle : https://jsfiddle.net/Fromager/zkgfzbcv/
1) id should be unique, so replace both id="slider" with id="slider1" and id="slider2".
2) Replace #slider with .slider at
$('.slider').slider({
prev: '#prev',
next: '#next',
dots: '#dots',
autoplay: true,
});
to set the slider() to both slides you have.
(function($) {
'use strict';
var pluginName = 'slider',
defaults = {
next: '.slider-nav__next',
prev: '.slider-nav__prev',
item: '.slider__item',
dots: false,
dotClass: 'slider__dot',
};
function slider(element, options) {
this.$document = $(document);
this.$window = $(window);
this.$element = $(element);
this.options = $.extend({}, defaults, options);
this.init();
}
slider.prototype.init = function() {
this.setup();
this.attachEventHandlers();
this.update();
}
slider.prototype.setup = function(argument) {
this.$slides = this.$element.find(this.options.item);
this.count = this.$slides.length;
this.index = 0;
this.$next = $(this.options.next);
this.$prev = $(this.options.prev);
this.$canvas = $(document.createElement('div'));
this.$canvas.addClass('slider__canvas').appendTo(this.$element);
this.$slides.appendTo(this.$canvas);
this.$dots = $(this.options.dots);
this.$dots.length && this.createDots();
};
let isInit = false; // check if the first slider is initialized
slider.prototype.createDots = function() {
if(isInit){
return; // if the first slider is initialized, do nothing.
}
var dots = [];
for (var i = 0; i < this.count; i += 1) {
dots[i] = '<span data-index="' + i + '" class="' + this.options.dotClass + '">';
// $(this.$slides[i]) is the slider__item div
dots[i] += i + '/' + $(this.$slides[i]).find('img').attr('src') + '</span>';
}
this.$dots.append(dots);
isInit = true; // after the first slider is initialized, set to true
}
slider.prototype.attachEventHandlers = function() {
this.$element.on('prev.slider', this.prev.bind(this));
this.$document.on('click', this.options.prev, (function(e) {
this.$element.trigger('prev.slider');
}).bind(this));
this.$element.on('next.slider', this.next.bind(this));
this.$document.on('click', this.options.next, (function(e) {
this.$element.trigger('next.slider');
}).bind(this));
this.$element.on('update.slider', this.update.bind(this));
this.$window.on('resize load', (function(e) {
this.$element.trigger('update.slider');
}).bind(this));
this.$element.on('jump.slider', this.jump.bind(this));
this.$document.on('click', ('.' + this.options.dotClass), (function(e) {
var index = parseInt($(e.target).attr('data-index'));
this.$element.trigger('jump.slider', index);
}).bind(this));
};
slider.prototype.next = function(e) {
this.index = (this.index + 1) % this.count;
this.slide();
};
slider.prototype.prev = function(e) {
this.index = Math.abs(this.index - 1 + this.count) % this.count;
this.slide();
};
slider.prototype.jump = function(e, index) {
this.index = index % this.count;
this.slide();
}
slider.prototype.slide = function(index) {
undefined == index && (index = this.index);
var position = index * this.width * -1;
this.$canvas.css({
'transform': 'translate3d(' + position + 'px, 0, 0)',
});
this.updateCssClass();
};
slider.prototype.update = function() {
this.width = this.$element.width();
this.$canvas.width(this.width * this.count);
this.$slides.width(this.width);
this.slide();
};
slider.prototype.updateCssClass = function() {
this.$slides
.removeClass('active')
.eq(this.index)
.addClass('active');
this.$dots
.find('.' + this.options.dotClass)
.removeClass('active')
.eq(this.index)
.addClass('active');
}
$.fn[pluginName] = function(options) {
return this.each(function() {
!$.data(this, pluginName) && $.data(this, pluginName, new slider(this, options));
});
};
})(window.jQuery);
let isInitialized = false;
$('.slider').slider({
prev: '#prev',
next: '#next',
dots: '#dots',
autoplay: true,
});
img {
max-width: 100%;
height: auto;
}
.slider-box,
.slider__item {
position: relative;
}
.slider-box{
display:flex;
}
.slider {
width:40vw;
display:inline-block;
overflow: hidden;
}
.slider__canvas {
transition: transform 0.5s;
}
.slider__item {
float: left;
}
.slider__item__title {
opacity: 0;
position: absolute;
top: 50px;
left: 50px;
/*transition: opacity 0.3s, transform 0.3s;
transform: translate3d(-50%, -60%, 0);*/
}
.active .slider__item__title {
opacity: 1;
/*transition-delay: 0.5s;
transform: translate3d(-50%, -50%, 0);*/
}
.slider-nav {
color: #fff;
text-align: center;
}
.slider-nav__dots {
position: absolute;
bottom: 20px;
left: 20px;
right: 20px;
}
.slider-nav__prev,
.slider-nav__next,
.slider__dot {
background:green;
/*backface-visibility: hidden;
transition: transform 0.3s, box-shadow 0.3s;*/
}
.slider-nav__prev,
.slider-nav__next {
position: absolute;
top: 50%;
width: 3rem;
height: 3rem;
margin-top: -1.5rem;
line-height: 3rem;
}
.slider-nav__prev {
left: 7%;
}
.slider-nav__next {
right: 7%;
}
.slider__dot {
display: inline-block;
width: 1rem;
height: 1rem;
margin: 0 1rem;
}
/*
.slider-nav__prev:hover,
.slider-nav__next:hover,
.slider__dot.active,
.slider__dot:hover {
transform: scale3d(1.5, 1.5, 1);
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slider-box">
<div class="slider" id="slider1">
<div class="slider__item">
<img src="https://placeimg.com/960/540/animals" alt="">
<h2 class="slider__item__title">Slide 1 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/arch" alt="">
<h2 class="slider__item__title">Slide 2 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/nature" alt="">
<h2 class="slider__item__title">Slide 3 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/people" alt="">
<h2 class="slider__item__title">Slide 4 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/tech" alt="">
<h2 class="slider__item__title">Slide 5 Title</h2>
</div>
</div>
<div class="slider" id="slider2">
<div class="slider__item">
<img src="https://placeimg.com/960/540/animals" alt="">
<h2 class="slider__item__title">Slide 1 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/arch" alt="">
<h2 class="slider__item__title">Slide 2 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/nature" alt="">
<h2 class="slider__item__title">Slide 3 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/people" alt="">
<h2 class="slider__item__title">Slide 4 Title</h2>
</div>
<div class="slider__item">
<img src="https://placeimg.com/960/540/tech" alt="">
<h2 class="slider__item__title">Slide 5 Title</h2>
</div>
</div>
</div>
<div class="slider-nav">
<div class="slider-nav__prev" id="prev"><i class="fa fa-angle-left"></i></div>
<div class="slider-nav__next" id="next"><i class="fa fa-angle-right"></i></div>
<div class="slider-nav__dots" id="dots"></div>
</div>

How to make an element scroll between two points [duplicate]

This question already has answers here:
Stop div scrolling once it reaches another div
(2 answers)
Closed 5 years ago.
I need to heading to scroll with the user, however only between two points. So scroll from its starting position with the user, to a certain position (above the contact us container) and then back with the user up.
Here is the current code used, this allows the heading to scroll until a certain point as required however does not scroll back up when the user scrolls up.
HTML:
<div id="header" class="row">
<div class="col-sm-5">
<h1 id="scrollwith">Our Services.</h1>
</div>
<div class="col-sm-6 col-sm-offset-1">
<img src="images/backdroppattern.png" style="width: 100%; height: 3000px;">
</div>
</div>
</div>
<div id="contact-container">
<div class="row">
<div class="col-sm-12">
<a class="contact-link" href="#"><h2>Contact us ➔</h2></a>
</div>
</div>
</div>
JS:
$(document).ready(function(){
var windw = this;
$.fn.followTo = function ( pos ) {
var $this = this,
$window = $(windw);
$window.scroll(function(e){
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed'
});
}
});
};
$('#scrollwith').followTo(2700);
});
All credits to this answer goes to #MicronXD from the post here.
jQuery.fn.extend({
followTo: function(elem, marginTop) {
var $this = $(this);
var $initialOffset = $this.offset().top;
setPosition = function() {
if ($(window).scrollTop() > $initialOffset) {
if (elem.offset().top > ($(window).scrollTop() + $this.outerHeight() + marginTop)) {
$this.css({
position: 'fixed',
top: marginTop
});
}
if (elem.offset().top <= ($(window).scrollTop() + $this.outerHeight() + marginTop)) {
$this.css({
position: 'absolute',
top: elem.offset().top - $this.outerHeight()
});
}
}
if ($(window).scrollTop() <= $initialOffset) {
$this.css({
position: 'relative',
top: 0
});
}
}
$(window).resize(function() {
setPosition();
});
$(window).scroll(function() {
setPosition();
});
}
});
$('#scrollwith').followTo($('#contact-container'), 0);
#contact-container {
background: red;
height: 900px;
}
#scrollwith {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header" class="row">
<div class="col-sm-5">
<h1 id="scrollwith">Our Services.</h1>
</div>
<div class="col-sm-6 col-sm-offset-1">
<img src="images/backdroppattern.png" style="width: 100%; height: 3000px;">
</div>
</div>
<div id="contact-container">
<div class="row">
<div class="col-sm-12">
<a class="contact-link" href="#">
<h2>Contact us ➔</h2>
</a>
</div>
</div>
</div>

Angular + jQuery, trigger scroll when src of image changes

I am trying to use jQuery to scroll to a particular thumbnail (inside a modal) when right/left arrows have been pressed (modal should pop up when user clicks on a image). I was able to make the scroll working when user clicks on a thumbnail but I could not trigger a click when variable current2 changes. Any help would be appreciated.
I am new in Angular.js so if there are other suggestions to improve the code, it would be appreciated.
jsbin link
<body ng-app="mediaGallery" class="ng-cloak" ng-controller="mediaGalleryCtrl">
<div class="row">
<div class="small-8 columns">
<div class="small-3 columns">
<div ng-repeat="obj in array">
<div ng-if="$index < 4">
<img ng-click="changeMainMedia($index, 'current1')" class="thumbnail" ng-src="{{obj.src}}" />
</div>
<div ng-if="$index == 4">
<div class="thumbnail" data-open="media-gallery">
<label class="text-right success label">{{array.length - 3}} +</label>
</div>
</div>
</div>
</div>
<div class="small-9 columns">
<img data-open="media-gallery" class="main-gallery" ng-src="{{array[current1].src}}" />
</div>
</div>
</div>
<div ng-keydown="key($event)" id="media-gallery" class="small reveal text-center media-gallery" data-reveal>
<div class="modal-body">
<div class="main-media">
<img class="main-gallery media-gallery-main" ng-src="{{array[current2].src}}" />
<hr>
<div class="nested-media" scroll-thumbnail>
<img ng-click="changeMainMedia($index, 'current2')" ng-repeat="obj in array" class="thumbnail media-gallery-thumbnail" ng-src="{{obj.src}}" />
</div>
</div>
<button class="close-button" data-close aria-label="Close reveal" type="button">
<span aria-hidden="true">x</span>
</button>
</div>
</div>
<script>
var app = angular.module("mediaGallery", []);
app.controller("mediaGalleryCtrl", ['$scope', function(scope) {
var array = [{
src: "https://placeimg.com/640/480/any"
}, {
src: "https://placeimg.com/640/480/tech"
}, {
src: "https://placeimg.com/640/480/animals"
}, {
src: "https://placeimg.com/640/480/nature"
}, {
src: "https://placeimg.com/640/480/arch"
}, {
src: "https://placeimg.com/640/480/people"
}];
scope.array = array;
scope.current1 = 0
scope.current2 = 0;
scope.changeMainMedia = function(index, key) {
scope[key] = index;
}
scope.key = function($event) {
var previous = -1;
var current = scope.current2;
if ($event.keyCode == "39") {
previous = current;
current = (current + 1) % array.length;
} else if ($event.keyCode == "37") {
previous = current;
current = (current - 1) % array.length;
}
current = current < 0 ? (array.length + current) : current;
scope.current2 = current;
}
}]);
app.directive('scrollThumbnail', function() {
return {
link: function(scope, elem, attrs) {
elem.on("click", function(event) {
$(this).animate({
scrollLeft: $(event.target).position().left
}, "slow");
});
}
};
});
$(document).foundation()
</script>
</body>
This is a solution which does not need jQuery. I commented the changes that I have made to your code.
<!DOCTYPE HTML>
<html>
<head>
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" />
<meta name="author">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/css/foundation.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/js/foundation.js"></script>
<style>
.media-gallery .media-gallery-thumbnail {
max-height: 5em;
display: inline-block
}
.media-gallery .media-gallery-main {
height: auto;
width: auto;
max-height: 20em;
}
.media-gallery .nested-media {
overflow-x: scroll;
white-space: nowrap;
}
.media-gallery .media-gallery-main {
max-width: 100%;
-moz-transition: all 0.3s;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.media-gallery .media-gallery-main:hover {
-moz-transform: scale(1.5);
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
display: none !important;
}
</style>
</head>
<body ng-app="mediaGallery" class="ng-cloak" ng-controller="mediaGalleryCtrl">
<div class="row">
<div class="small-8 columns">
<div class="small-3 columns">
<div ng-repeat="obj in array">
<div ng-if="$index < 4">
<img ng-click="changeMainMedia($index, 'current1', $event)" class="thumbnail" ng-src="{{obj.src}}" />
</div>
<div ng-if="$index == 4">
<div class="thumbnail" data-open="media-gallery">
<label class="text-right success label">{{array.length - 3}} +</label>
</div>
</div>
</div>
</div>
<div class="small-9 columns">
<img data-open="media-gallery" class="main-gallery" ng-src="{{array[current1].src}}" />
</div>
</div>
</div>
<div ng-keydown="key($event)" id="media-gallery" class="small reveal text-center media-gallery" data-reveal>
<div class="modal-body">
<div class="main-media">
<img class="main-gallery media-gallery-main" ng-src="{{array[current2].src}}" />
<hr>
<div class="nested-media" scroll-thumbnail>
<img ng-click="changeMainMedia($index, 'current2', $event)" ng-repeat="obj in array" class="thumbnail media-gallery-thumbnail" ng-src="{{obj.src}}" />
</div>
</div>
<button class="close-button" data-close aria-label="Close reveal" type="button">
<span aria-hidden="true">x</span>
</button>
</div>
</div>
<script>
var app = angular.module("mediaGallery", []);
app.controller("mediaGalleryCtrl", ['$scope', function (scope) {
var array = [{
src : "https://placeimg.com/640/480/any"
}, {
src : "https://placeimg.com/640/480/tech"
}, {
src : "https://placeimg.com/640/480/animals"
}, {
src : "https://placeimg.com/640/480/nature"
}, {
src : "https://placeimg.com/640/480/arch"
}, {
src : "https://placeimg.com/640/480/people"
}
];
scope.array = array;
scope.current1 = 0
scope.current2 = 0;
scope.changeMainMedia = function (index, key, $event) {
scope[key] = index;
// Use scroll function to scroll to element after click
// $event parameter is added to retrieve the node value
scope.scroll($event.target);
}
// Animate scrolling
// Midified from: http://stackoverflow.com/a/8918062/529024
scope.scrollTo = function (element, to, duration) {
if (duration <= 0)
return;
var difference = to - element.scrollLeft;
var perTick = difference / duration * 10;
setTimeout(function () {
element.scrollLeft = element.scrollLeft + perTick;
if (element.scrollLeft === to)
return;
scope.scrollTo(element, to, duration - 10);
}, 10);
}
// calculate scroll position and starting scroll animation
scope.scroll = function (element) {
// Get center of parent
var left = element.offsetLeft;
var scroll = left - element.parentElement.scrollLeft;
// Start scroll
scope.scrollTo(element.parentElement, scroll, 300);
}
scope.key = function ($event) {
var previous = -1;
var current = scope.current2;
if ($event.keyCode == "39") {
previous = current;
current = (current + 1) % array.length;
} else if ($event.keyCode == "37") {
previous = current;
current = (current - 1) % array.length;
}
current = current < 0 ? (array.length + current) : current;
scope.current2 = current;
// Scroll to element
scope.scroll(scope.getElement());
}
// get the element that is matching current2 value
scope.getElement = function () {
var parent = scope.parentElement;
var children = parent.children();
return children.eq(scope.current2)[0];
}
// This function is used by directive scrollThumbnail to set the parent element
// and use it to get element sibilings
scope.setElement = function (element) {
scope.parentElement = element;
}
}
]);
app.directive('scrollThumbnail', function () {
return {
scope : true,
link : function (scope, elem, attrs) {
// set element to scope.parentElement.
scope.setElement(elem);
}
};
});
$(document).foundation()
</script>
</body>
</html>
And this a JSBin link: https://jsbin.com/ruzikilexe/1/edit?html,output

Angular js make slider with infinite effect

I created a simple photo slider but i does not how to make this infinite.
How can i make this effect with the angular way, please help.
I does not want to use jquery, but if it is the only way so whatever.
var app = angular.module('stack', []);
app.controller('MainCtrl', function($scope) {
$scope.images = ["http://lorempixel.com/600/200/sports/", "http://lorempixel.com/600/200/city/",
"http://lorempixel.com/600/200/nature/"
];
$scope.index = 0;
var IMG_WIDTH = -600;
$scope.next = function() {
++$scope.index;
if ($scope.images.length <= $scope.index) {
$scope.index = 0;
}
var pos = ($scope.index > 0) ? $scope.index * IMG_WIDTH : 0;
$scope.listPosition = {
transform: "translateX(" + pos + "px)"
};
}
$scope.prev = function() {
--$scope.index;
if ($scope.index < 0) {
$scope.index = $scope.images.length - 1;
}
var pos = ($scope.index > 0) ? $scope.index * IMG_WIDTH : 0;
$scope.listPosition = {
transform: "translateX(" + pos + "px)"
};
}
});
.mt {
margin-top: 2em;
}
.outer {
max-width: 600px;
overflow: hidden;
}
.slider {
width: 90000px;
position: relative;
transition: all 1s;
}
.slider div {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link data-require="bootstrap#3.3.2" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
<body ng-app="stack" ng-controller="MainCtrl">
<div class="container-fluid">
<div class="row mt">
<div class="col-sm-6 col-sm-push-3">
<div class="outer clearfix">
<div class="slider clearfix" ng-style="listPosition">
<div ng-repeat="image in images track by $index">
<img ng-src="{{image}}" />
</div>
</div>
</div>
</div>
</div>
</div>
<a class="btn btn-default" ng-click="next()">Next</a>
<a class="btn btn-default" ng-click="prev()">Prev</a>
<div></div>
</body>
Easiest way would be to shuffle $scope.images array.
Once transition has been done, disable them, either by creating something like .no-transition class and adding it to the slider or by any other way you can imagine
$scope.images.push($scope.images.shift()) should put first item to last position, $scope.images.unshift($scope.images.pop()) should reverse it.
After that, you'll probably have to re-adjust transform value and re-apply transitions
Hope that helps.

Run a JS function while in viewport.

I've found on here how to do a counter, and I will be using it on a scrolling site.
I'm using the following code:
$(function() {
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 10);
}
}
$("span").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
I've tried to include the following code, but I'm not sure I'm adding it correctly:
if ($('element').visible(true)) {
}
Heres a link to the Jfiddle that is currently working without the if statement. Any help would be appreciated.
http://jsfiddle.net/WpJxn/257/
This is what you should look at: Check if element is visible after scrolling
Here is an example for you that demonstrates this technique: http://jsfiddle.net/XYS2G/ - just try to scroll the Result window.
HTML:
<div class="indicators">
<span class="indicator" data-id="section1">section1</span>
<span class="indicator" data-id="section2">section2</span>
<span class="indicator" data-id="section3">section3</span>
<span class="indicator" data-id="section4">section4</span>
<span class="indicator" data-id="section5">section5</span>
<span class="indicator" data-id="section6">section6</span>
</div>
<div class="sections">
<div class="section" id="section1">section1</div>
<div class="section" id="section2">section2</div>
<div class="section" id="section3">section3</div>
<div class="section" id="section4">section4</div>
<div class="section" id="section5">section5</div>
<div class="section" id="section6">section6</div>
</div>
CSS:
.indicators { position: fixed; }
.section { height: 150px; }
JavaScript:
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
function refreshIndicators() {
$('.indicator').each(function () {
if (isScrolledIntoView($('#' + $(this).attr('data-id')))) {
$(this).css('color', 'red');
} else {
$(this).css('color', 'black');
}
});
}
refreshIndicators();
$(window).bind('scroll', refreshIndicators);

Categories