Start counting after scroll on specific element - javascript

I create a website and add a counter to my codes.
$(function() {
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 50);
}
}
$(".c-section4").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div class="section4">
<div class="section4-bg"></div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
</div>
Now i have a problem, i want to counter start when i scroll to this element
Demo
Sorry for my bad english

You can handle the window scroll event and use the function given here by Scott Dowding to determine if the element has been scrolled into view. An isCounting flag can be set on each element to prevent counting several times simultaneously.
In the following code snippet, the counting is performed only while the element is visible.
$(function () {
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 count($this) {
var current = parseInt($this.html(), 10);
if (isScrolledIntoView($this) && !$this.data("isCounting") && current < $this.data('count')) {
$this.html(++current);
$this.data("isCounting", true);
setTimeout(function () {
$this.data("isCounting", false);
count($this);
}, 50);
}
}
$(".c-section4").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
$(this).data("isCounting", false);
});
function startCount() {
$(".c-section4").each(function () {
count($(this));
});
};
$(window).scroll(function () {
startCount();
});
startCount();
});
.tallDiv
{
height: 800px;
background-color: silver;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div class="section4">
<div class="section4-bg"></div>
<div class="tallDiv">Scroll down to test</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="tallDiv"></div>
</div>

You need to give the target element and id, then get its postition from top var pos = document.getElementById('targetId').scrollHeight - element.clientHeight; and compare it to the scrolled height window.pageYOffset.
If widow offset is greater than the pos, you can start the counter. You should hook the comparison to the window.onscroll event.
Also you should memorize in a variable if you started the counter for an element already to avoid starting it twice.

Get the scroll Height and compare with the height of the start div(count start div) put a condition
$(function() {
var pos = document.getElementById('targetId').scrollHeight;
console.log(pos);
if(pos>="75"){
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 50);
}
}
$(".c-section4").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="counter-section" id="targetId">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>

Live Link
You can use this Plugin for it. Source LINK
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0'
data-max='82' data-delay='19' data-increment="2">0</span>
NB: data-max='**'give your max-number and data-delay='**' select a time for countdown running and select increment data-increment="**" .
/**
* jQuery scroroller Plugin 1.0
*
* http://www.tinywall.net/
*
* Developers: Arun David, Boobalan
* Copyright (c) 2014
*/
(function($){
$(window).on("load",function(){
$(document).scrollzipInit();
$(document).rollerInit();
});
$(window).on("load scroll resize", function(){
$('.numscroller').scrollzip({
showFunction : function() {
numberRoller($(this).attr('data-slno'));
},
wholeVisible : false,
});
});
$.fn.scrollzipInit=function(){
$('body').prepend("<div style='position:fixed;top:0px;left:0px;width:0;height:0;' id='scrollzipPoint'></div>" );
};
$.fn.rollerInit=function(){
var i=0;
$('.numscroller').each(function() {
i++;
$(this).attr('data-slno',i);
$(this).addClass("roller-title-number-"+i);
});
};
$.fn.scrollzip = function(options){
var settings = $.extend({
showFunction : null,
hideFunction : null,
showShift : 0,
wholeVisible : false,
hideShift : 0,
}, options);
return this.each(function(i,obj){
$(this).addClass('scrollzip');
if ( $.isFunction( settings.showFunction ) ){
if(
!$(this).hasClass('isShown')&&
($(window).outerHeight()+$('#scrollzipPoint').offset().top-settings.showShift)>($(this).offset().top+((settings.wholeVisible)?$(this).outerHeight():0))&&
($('#scrollzipPoint').offset().top+((settings.wholeVisible)?$(this).outerHeight():0))<($(this).outerHeight()+$(this).offset().top-settings.showShift)
){
$(this).addClass('isShown');
settings.showFunction.call( this );
}
}
if ( $.isFunction( settings.hideFunction ) ){
if(
$(this).hasClass('isShown')&&
(($(window).outerHeight()+$('#scrollzipPoint').offset().top-settings.hideShift)<($(this).offset().top+((settings.wholeVisible)?$(this).outerHeight():0))||
($('#scrollzipPoint').offset().top+((settings.wholeVisible)?$(this).outerHeight():0))>($(this).outerHeight()+$(this).offset().top-settings.hideShift))
){
$(this).removeClass('isShown');
settings.hideFunction.call( this );
}
}
return this;
});
};
function numberRoller(slno){
var min=$('.roller-title-number-'+slno).attr('data-min');
var max=$('.roller-title-number-'+slno).attr('data-max');
var timediff=$('.roller-title-number-'+slno).attr('data-delay');
var increment=$('.roller-title-number-'+slno).attr('data-increment');
var numdiff=max-min;
var timeout=(timediff*1000)/numdiff;
//if(numinc<10){
//increment=Math.floor((timediff*1000)/10);
//}//alert(increment);
numberRoll(slno,min,max,increment,timeout);
}
function numberRoll(slno,min,max,increment,timeout){//alert(slno+"="+min+"="+max+"="+increment+"="+timeout);
if(min<=max){
$('.roller-title-number-'+slno).html(min);
min=parseInt(min)+parseInt(increment);
setTimeout(function(){numberRoll(eval(slno),eval(min),eval(max),eval(increment),eval(timeout))},timeout);
}else{
$('.roller-title-number-'+slno).html(max);
}
}
})(jQuery);
.nm {
height: 400px;
background: #f5f5f5;
display: block;
}
.nm_1 {
background-color: #632525;
}
.nm_2 {
background-color: grad;
}
.nm_3 {
background-color: gray;
}
.nm_4 {
background-color: green;
}
.nm_5 {
background-color: georgian;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="nm nm_1">
</section>
<section class="nm nm_2">
</section>
<section class="nm nm_3">
</section>
<section class="nm nm_4">
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='192' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='282' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='82' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
</section>
<section class="nm nm_4">
</section>
<section class="nm nm_5">
</section>

Here's my solution which supports floats and a configurable animation duration. It will only animate the count one time - as soon the element appears in the viewport of the specified container.
const initAnimatedCounts = () => {
const ease = (n) => {
// https://github.com/component/ease/blob/master/index.js
return --n * n * n + 1;
};
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// Once this element is in view and starts animating, remove the observer,
// because it should only animate once per page load.
observer.unobserve(entry.target);
const countToString = entry.target.getAttribute('data-countTo');
const countTo = parseFloat(countToString);
const duration = parseFloat(entry.target.getAttribute('data-animateDuration'));
const countToParts = countToString.split('.');
const precision = countToParts.length === 2 ? countToParts[1].length : 0;
const startTime = performance.now();
const step = (currentTime) => {
const progress = Math.min(ease((currentTime - startTime) / duration), 1);
entry.target.textContent = (progress * countTo).toFixed(precision);
if (progress < 1) {
animationFrame = window.requestAnimationFrame(step);
} else {
window.cancelAnimationFrame(animationFrame);
}
};
let animationFrame = window.requestAnimationFrame(step);
}
});
});
document.querySelectorAll('[data-animateDuration]').forEach((target) => {
target.setAttribute('data-countTo', target.textContent);
target.textContent = '0';
observer.observe(target);
});
};
initAnimatedCounts();
div {
font-size: 30px;
text-align: center;
padding: 30px 0;
}
div > span {
color: #003d82;
}
div.scrollpad {
height: 100vh;
background-color: #eee;
}
<div>
<span>$<span data-animateDuration="1000">987.45</span></span> was spent on
about <span><span data-animateDuration="1000">5.8</span>M</span> things.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
There are <span><span data-animateDuration="1000">878</span>K</span> people involved.
<br/>
And <span><span data-animateDuration="1000">54</span></span> cakes.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
Additionally, <span>$<span data-animateDuration="3000">300</span>B</span> went to waste.
<br/>
Because <span>$<span data-animateDuration="2000">54</span></span> was spent on each cake.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
Lastly, <span><span data-animateDuration="4000">3.5334583</span>T</span> ants said hello.
<br/>
But <span><span data-animateDuration="2000">4</span></span> of them said goodbye.
</div>

Related

Animation and transition property with setTimeout() function

I'm fairly new to JS, and I'm trying to make a simple text slide animation. However, when the animation event is activated the first time, the transition property doesn't apply. Every time after that it works fine.
So I'm struggling with the first execution of the slide animation.
Here is the code:
function slide_animation(direction){
// Init
let text = document.querySelector(".story .box .right-part .text");
let text_html = text.innerHTML;
let text_slide = [
"Text n°1",
'Text n°2',
'Text n°3'
];
let current_slide = 0;
// Looking for the current_slide
for(let i=0;i<text_slide.length;i++){
if (text_slide[i]==text_html){current_slide = i};
}
// Calculating the next slide position
if (direction=='right'){
if (current_slide >= text_slide.length-1){
current_slide = 0;
}
else {current_slide+=1;}
}
else {
if (current_slide <= 0){
current_slide = text_slide.length-1;
}
else {
current_slide = current_slide-=1;
}
}
// Animation
setTimeout(()=>{
text.style.transition = '0.5s';
text.style.opacity = 0;
text.style.left = '100px';
},250);
setTimeout(()=>{
text.innerHTML = text_slide[current_slide];
text.style.opacity = 1;
text.style.left = '0px';
},750)
}
.story .box .right-part .text-container .text {
line-height: 1.25;
position: relative;
}
<div class="box">
<div class="left-part">
<div class="text-container">
<p class="text">
<span class="text-padding fontsize-md">----</span>
</p>
</div>
<div class="buttons-container">
<button class="backward" onclick="slide_animation('left')"></button>
<button class="forward" onclick="slide_animation('right')"></button>
</div>
</div>
<div class="right-part">
<div class="text-container">
<p class="text fontsize-sm">Text n°1</p>
</div>
</div>
</div>
Anyway , it is fixed. I added another setTimeOut that did nothing really useful on the text , i placed it just before the others setTimeOut and it seems to work out properly.
Here is what is inserted :
setTimeout(()=>{
text.style.left=0;
},0)

jQuery animtion stops when user scrolls

I'm using multiple number elements on my site which are counting up after hitting the visible area of the viewport.
That part works until the user manually scrolls the page. If the user scrolls up or down, the animation stops for a second and repeats when the user don't scroll anymore. It looks very buggy.
If I try to replicate the problem in a fiddle, the same code always works without the "stuttering"?
jQuery(function($) {
$(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var H = $(this).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$(".fig-number").inViewport(function(px) {
// if px>0 (entered V.port) and
// if prop initNumAnim flag is not yet set = Animate numbers
if (px > 0 && !this.initNumAnim) {
this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 10000,
step: function(now) {
$(this).text(Math.ceil(now));
}
});
}
});
});
html,
body {
height: 100%;
}
.spacer {
height: 100%;
width: 100%;
display: block;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">1000</h1>
<h1 class="fig-number">1500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">2000</h1>
<h1 class="fig-number">2500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">3000</h1>
<h1 class="fig-number">3500</h1>
</div>
The working fiddle (same code): https://jsfiddle.net/JSCray/r7g0vn93/3/

Change CSS of inner div when scroll reaches that div

I am attempting to implement a scroll function where the CSS of the inner div's change when it reaches a certain height from the top.
var $container = $(".inner-div");
var containerTop = $container.offset().top;
var documentTop = $(document).scrollTop();
var wHeight = $(window).height();
var minMaskHeight = 0;
var descriptionMax = 200;
var logoMin = -200;
var maskDelta = descriptionMax - minMaskHeight;
var $jobOverview = $container.find(".right");
var $jobLogo = $container.find(".left");
var curPlacementPer = ((containerTop - documentTop) / wHeight) * 100;
var topMax = 85;
var center = 20;
var bottomMax = -15;
//console.log("Placement: " + curPlacementPer);
function applyChanges(perOpen) {
var maskHeightChange = maskDelta * (perOpen / 100);
var opacityPer = perOpen / 100;
var newDescriptionLeft = descriptionMax - maskHeightChange;
var newLogoLeft = logoMin + maskHeightChange;
if (newDescriptionLeft <= 0) newDescriptionLeft = 0;
if (newLogoLeft >= 0) newLogoLeft = 0;
if (opacityPer >= 1) opacityPer = 1;
$jobOverview.css({
transform: "translate(" + newDescriptionLeft + "%,-50%)",
opacity: opacityPer
});
$jobLogo.css({
transform: "translate(" + newLogoLeft + "%,-50%)",
opacity: opacityPer
});
}
if (window.innerWidth > 640) {
$container.removeClass("mobile");
// console.log("Placement: " + curPlacementPer);
if (curPlacementPer <= topMax /*&& curPlacementPer >= center*/ ) {
var perOpen = ((topMax - curPlacementPer) / 25) * 100;
applyChanges(perOpen);
} else if (curPlacementPer < center /*&& curPlacementPer >= bottomMax*/ ) {
var perOpen = (((bottomMax - curPlacementPer) * -1) / 25) * 100;
applyChanges(perOpen);
} else {
$jobOverview.css({
transform: "translate(200%,-50%)",
opacity: "0"
});
$jobLogo.css({
transform: "translate(-300%,-50%)",
opacity: "0"
});
}
<div class="outer-div">
<div class="inner-div first">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div second">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div third">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div fourth">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
Currently, all of the inner div's gets changed at the same time.
I noticed that when I change the $container class to equal '.first' and specify it more, it works.
Is there any way to make the inner div's change separately, relative to its height from the top? Any way I can iterate the scroll function so I can add more inner div's in the future and not have to worry about changing my scroll function?
In raw JavaScript, this is my answer:
// Define the element -- The '#fooBar' can be changed to anything else.
var element = document.querySelector("#fooBar");
// Define how much of the element is shown before something happens.
var scrollClipHeight = 0 /* Whatever number value you want... */;
// Function to change an element's CSS when it is scrolled in.
const doSomething = function doSomething() {
/** When the window vertical scroll position plus the
* window's inner height has reached the
* top position of your element.
*/
if (
(window.innerHeight + window.scrollY) - (scrollClipHeight || 0) >=
element.getBoundingClientRect().top
)
// Generally, something is meant to happen here.
element.style = "/* Yay, some CSS! */"
};
// Call the function without an event occurring.
doSomething();
// Call the function when the 'window' scrolls.
addEventListener("scroll", doSomething, false)
This is the method I use. If there are other methods, I'd love to see them as well but this is my answer for now.
consider using 3rd party jQuery plugin for easier job, like one of these:
https://github.com/xobotyi/jquery.viewport
or
https://github.com/zeusdeux/isInViewport
then you can have additional element selector e.g.: ":in-viewport"
so you can:
$(window).on('scroll',function() {
$('div').not(':in-viewport').html('');
$('div:in-viewport').html('hello');
});
Check if current scroll offset from top is bigger than the element offset from the top:
$(window).scroll(function() {
var height = $(window).scrollTop();
var element = $('#changethis'); //change this to your element you want to add the css to
if(height > element.offset().top) {
element.addClass('black'); //add css class black (change according to own css)
}
});
Html:
<div id="changethis">Test</div>
Css:
body
{
height:2000px;
}
.black
{
background-color:black;
color:white;
padding:20px;
}
Demo:
https://codepen.io/anon/pen/WZdEap
You could easily implement this in your existing code.
Below is the sample snippet code, Hope it'll work for you:
$(document).ready(function(){
topMax = 100;
topMin = 25;
$(document).scroll(function(){
$('.inner-div').each(function(){
if($(this).offset().top-$(window).scrollTop()<=topMax && $(this).offset().top-$(window).scrollTop()>=topMin){
$(this).css({'background':'#c7c7c7'});
}else{
$(this).css({'background':'inherit'});
}
});
});
});
div{
width:100%;
border:1px solid red;
padding:5px;
}
div.inner-div{
border: 1px dashed green;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer-div">
<div class="inner-div first">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div second">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div third">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div fourth">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
Happy to help you! :)

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

Slideshow that increases z-index and decreases opacity

First time posting, please bear with me.
I'm trying to create a slideshow that:
assigns a z-index to each <section>
sets all slides with an opacity of 0.7
assigns the currently top slide an opacity of 1
Here is the HTML:
<div id="slides">
<section class="slide">
<article>
<h1>6</h1>
</article>
</section>
<section class="slide">
<article>
<h1>5</h1>
</article>
</section>
<section class="slide">
<article>
<h1>4</h1>
</article>
</section>
<section class="slide">
<article>
<h1>3</h1>
</article>
</section>
<section class="slide">
<article>
<h1>2</h1>
</article>
</section>
<section class="slide">
<article>
<h1>1</h1>
</article>
</section>
</div>
<div id="prev">
←
</div>
<div id="next">
→
</div>
Here is the JS so far:
$(document).ready(function() {
var z = 0;
var inAnimation = false;
$('section.slide').each(function() {
z++;
$(this).css('z-index', z);
});
function swapFirstLast(isFirst) {
if(inAnimation) return false;
else inAnimation = true;
var processZindex, direction, newZindex, inDeCrease;
if(isFirst) {
processZindex = z; direction = '-'; newZindex = 1; inDeCrease = 1;
} else {
processZindex = 1; direction = ''; newZindex = z; inDeCrease = -1;
}
$('section.slide').each(function() {
if($(this).css('z-index') == processZindex) {
$(this).animate({ 'top' : direction + $(this).height() + 'px' }, 'slow', function() {
$(this).css('z-index', newZindex)
.animate({ 'top' : '0' }, 'slow', function() {
inAnimation = false;
});
});
} else {
$(this).animate({ 'top' : '0' }, 'slow', function() {
$(this).css('z-index', parseInt($(this).css('z-index')) + inDeCrease);
});
}
return false;
}
$('#next a').click(function() {
return swapFirstLast(true);
});
$('#prev a').click(function() {
return swapFirstLast(false);
});
});
});
I thought I could insert the following code into the script:
if($(this).css('z-index') == processZindex) {
$(this).css('opacity', 1);
} else {
$(this).css('opacity', 0.7);
}
The problem is I can't seem to get the opacity at 1 to keep up with the z-index value of 6. So I thought about writing $(this).css('z-index') == processZindex as $(this).css('z-index') != 6 but the issue occurs.
Is there a simpler way to code this?
I just used the ordering of elements instead of z-index, using appendTo,preprendTo:
http://jsfiddle.net/jtbowden/RAT8N/1/
I couldn't decide if one function or separate functions was better. Here is two separate functions:
http://jsfiddle.net/jtbowden/5LJcA/3/
Is that what you are going for?

Categories