run animation once while scroll down and up - javascript

I am working on one project and i am having difficultly to solve this issue. Here is problem:- When user scroll down and lime color div visible animation will start. when user scroll up animation will stop. But real problem is animation running multiple times when lime color div visible. I want to run animation only once when lime color div visible. Please see jsfiddle demo.
Here is javascript code snippet.
function scollPosition(){
var sotpScroll = 0;
$(window).scroll(function(){
if(sotpScroll == 0){
sotpScroll = 1;
var cPosition = $('.c').offset();
var animationStartPoint = cPosition.top - 100;
console.log(animationStartPoint);
// console.log('c class position' + cPosition.top);
var dPosition = $('.d').offset();
// console.log('d class position' + dPosition.top);
var windowPosition = window.pageYOffset;
console.log('window position:- ' + windowPosition + ' dPosition.top:- ' + dPosition.top);
if (windowPosition > animationStartPoint && windowPosition < dPosition.top){
animation();
}
}
setTimeout(function(){sotpScroll=0},10);
});
}
Thankx in advance and apologies for my english. Please help me to solve this bug

Add a global flag that indicates if the area is visible or not:
var areaVisible
[...]
if (windowPosition > animationStartPoint && windowPosition < dPosition.top) {
// Area is visible
if (!areaVisible) { // If just became visible
animation();
}
areaVisible = true; // Prevent more animations
} else {
areaVisible = false;
}
Fiddle: http://jsfiddle.net/bortao/BB2k5/

Related

Move element on page as user scrolls up and down

I am struggling to achieve what should be a simple task.
Page Loads
User freely scrolls down through different sections.
When a specific DIV reaches the centre of the page I would like to pause/prevent scrolling down until the DIV has been moved horizontally across to the left a fixed number of pixels.
Then the user can be allowed to continue scrolling down the page.
Also, I would like to achieve the opposite effect if the user scrolls up i.e. scroll the div to the right a fixed number of pixels before continuing up.
Below is a sample of my code.
$(window).scroll(function() {
sD = $(this).scrollTop();
// $('.features-2-item').width();
if (sD > (f2Pos.top + 100) && sD < f2Pos.top + 2000 + 100) {
// if scroll distance is greater than the top position of
// the statements when they are centred in the viewport,
// and less than the top position of statements centred
// plus the height of 4 statements, prevent user from
// scrolling, then run function to change statements.
sD = f2Pos.top + 100;
var scroll = $(window).scrollTop();
// console.log(('up or down: ' + xSlide + ' > - ' + statementWidth + ' || ' + scroll + ' < ' + position));
if (xSlide > -statementWidth || scroll < position) {
slideStatements();
}
}
if (sD > f2Pos.top + 2000) {
// if scroll distance is greater than the top positon of
// the statements, centred in the viewport, plus the
// height of 4 statements, the user has scrolled through
// all of the statements and should be allowed to resume
// scrolling. Scrolling should be adjusted to take away
// the distance equal to the height of 4 statements.
sD = sD - 2000 + 100;
}
});
var statementWidth = $('.features-2-item').width();
var xSlide = statementWidth;
var position = $(window).scrollTop();
function slideStatements() {
var st = $(this).scrollTop();
if (st > lST) {
// Going Down
if (cS) {
// disallow scrolling until after statement slides
cS = false;
xSlide = Math.floor(xSlide + 32);
$(window).one('scroll.slideStatements', function() {
$(".features-2-container").css("transform", "translateX(" + xSlide + "px)");
});
// allow scrolling after statement slides
cS = true;
}
} else {
// Going Up
if (cS) {
// disallow scrolling until after statement slides
cS = false;
xSlide = Math.floor(xSlide - 32);
$(window).one('scroll.slideStatements', function() {
// $sS.slick("slickPrev");
$(".features-2-container").css("transform", "translateX(" + xSlide + "px)");
});
// allow scrolling after statement slides
cS = true;
}
}
lST = st - 1;
}
Any suggestion swould be great.
regards
Hi I'm not an expert here but I would like to share my method.
In my opinion the hardest part is how to prevent the scrolling. So we are not going to prevent it, instead we are going to take some advantage of it.
Let's say we have 3 sections like
<section>...</section>
<section class='stuart'>
<div class='kevin'></div>
</section>
<section>...</section>
And style like
.stuart {
height: 600px;
}
.kevin {
position: absolute;
width: 50px;
height: 50px;
background: tomato;
}
So stuart is a our container and kevin is a box inside.
Our goal is simple, when kevin goes up and pass the middle of window we will keep it at that middle (vertical) and move it from left to right (horizontal) until the end of stuart pass.
Code will be like
if (stuart.top < windowHeight / 2 &&
stuart.top + stuart.height - kevin.height > windowHeight / 2) {
let distance = windowHeight / 2 - stuart.top
kevin.classList.add('fixed')
kevin.style.left = distance + 'px'
}
The important part is the distance which always relate to the position of stuart, so you will no need to do anything about opposite effect.
Final example here.
Bad news, you need to calculate the height of container by yourself or a fixed position may not work in your case or other things but I hope this idea will help you in some way. Thanks.

adding image to different div upon change/removal of another div

I have a game which involves a dog chasing cats; upon the dog touching the cat div, the class changes so that a "dead" cat appears and is then removed. I would also like to have a smaller version of the dead cat image show up in a div in the upper right corner as a sort of score keeper.
So essentially every time a cat is killed a small image pops up in the score div.
The problem is if I have the prepend for the small image placed where it is now, it continues to add the image indefinitely as opposed to only one for each dead cat. I'm guessing it's because it's within this if statement for the collision detection but I can't figure out a way around it.
I've tried making it a function, moving it outside of the getCollision function, tried to attach a trigger...nothing I've done seems to work to solve what I assume to be a relatively simple problem.
If anyone can help or point me in the right direction I'd greatly appreciate it! Below is the code:
"use strict";
$(document).ready(function() {
console.log("linked");
var $dog = $('.dog'); //global variables
var body = $('body');
var $cat = $('.cat');
function newCat() { //creates a div w/ class cat, appends to body
var cat = $('<div class="cat"></div>');
body.append(cat);
setInterval(function() { //moves cats randomly
cat.css("top", Math.random() * window.innerHeight);
cat.css("left", Math.random() * window.innerWidth);
}, 1500)
}
for(var i=0; i<10; i++) { //create multiple cats
newCat();
}
function getCollision(cat) { //collision detection for elements
$(cat).each(function(index, cat) { //loops through each cat div
var $dogH = $dog.outerHeight(true);
var $dogW = $dog.outerWidth(true);
var $dogX = $dog.position();
var $dogY = $dog.position();
var $catH = parseInt($(cat).css('height').replace('px', ''))
var $catW = parseInt($(cat).css('width').replace('px', ''))
var $catX = parseInt($(cat).css('left').replace('px', ''))
var $catY = parseInt($(cat).css('top').replace('px', ''))
if ($dogX.left < $catX + $catW &&
$dogY.top < $catY + $catH &&
$catX < $dogX.left + $dogW &&
$catY < $dogY.top + $dogW) {
$(cat).addClass('dead');
$('.score').prepend('<img src="images/cat_dead_sm.png" />');
setTimeout(function() {
$('.dead').remove(); //removes dead cat
}, 2500);
console.log('boom');
};
});
};
$(document).mousemove(function(event) { //moves dog div to follow cursor
$('.dog').css({
'top': event.pageY,
'bottom': event.pageX,
'left': event.pageX,
'right': event.pageY
});
$cat = $('.cat')
getCollision($cat); //calls getcollision to check distance
})();
// function keepScore() {
// $('.score').prepend('<img src="images/cat_dead_sm.png" />');
// }
// };
});
I think the problem is that a dead cat can still die - another iteration of the collision detection can occur before the setTImeout that removes the dead cat is triggered. You could check if the current cat is already dead before prepending the score image.
We just need to check if it's already dead to avoid this:
if ($dogX.left < $catX + $catW &&
$dogY.top < $catY + $catH &&
$catX < $dogX.left + $dogW &&
$catY < $dogY.top + $dogW &&
!$(cat).hasClass('dead')
) {
$(cat).addClass('dead');
$('.score').prepend('<img src="images/cat_dead_sm.png" />');
setTimeout(function () {
$('.dead').remove(); //removes dead cat
}, 2500);
console.log('boom');
}
Or even better - you could avoid collision detection on dead cats entirely:
$cat = $('.cat:not(.dead)');
getCollision($cat);

how to use Javascript for slide left

i have use the javascript for sliding the element up and down as fallow
<script type="text/javascript">
$(function () {
var $divSlide = $("div.slide");
$divSlide.hide().eq(0).show();
var panelCnt = $divSlide.length;
setInterval(panelSlider, 3000);
function panelSlider() {
$divSlide.eq(($divSlide.length++) % panelCnt)
.slideUp("slow", function () {
$divSlide.eq(($divSlide.length) % panelCnt)
.slideDown("slow");
});
}
});
</script>
which slide the panel up and down having slide tag panals are added as fallow
//protion
DataTable promo = SQl.ExecuteSelectCommand("select Promo_Code,Promo_Discription,Promo_Min_Ammount,Persent_Off,Start_Date,End_Date,Supp_Name from Prommosion_Details_View ");
if (promo.Rows.Count > 0)
{
for (int i = 0; i <= promo.Rows.Count - 1; i++)
{
Panel p = new Panel();
p.CssClass = "slide";
PromoUC PUC = (PromoUC)Page.LoadControl("PromoUC.ascx");
PUC.setText(promo.Rows[i][3].ToString(), promo.Rows[i][1].ToString(), promo.Rows[i][4].ToString(), promo.Rows[i][5].ToString(), promo.Rows[i][0].ToString(), " From " + promo.Rows[i]["Supp_Name"].ToString());
p.Controls.Add(PUC);
searchBoxPromoPlaceHolder.Controls.Add(p);
}
}
above code is working fine but the problem is tat i have to scroll it left and right with elastic effect
You should check the jQuery.animate() which helps you to do any animation effect.
you can animate any css property,in your case the width could fit your needs.check the examples online.

Get scroll position to set variable

I am using this to scroll the page. However I would like it to stop scrolling at set positions on the page.
var t;
var scrolling = false;
function doScroll() {
$('body').scrollTop($('body').scrollTop() + 20);
}
$('#pause').on('click',function(){
scrolling = !scrolling;
if(!scrolling){
clearInterval(t);
return;
}
t = setInterval(doScroll, 10);
});
I was hoping that by adding this to the doScroll function would stop the scroll at positions between 100 and 150 but, it does not.
if($("#pause").offset().top >=100 && <150){
clearInterval(t);
}
Any ideas?
Got it! if condition was incorrect, scrolling had to be set to false to allow restart...
function doScroll() {
$('body').scrollTop($('body').scrollTop() + 20);
if($("#pause").offset().top >=100 && $("#pause").offset().top < 150){
clearInterval(t);
scrolling = false;
return;
}
}
Thanks to zvona

javascript 'over-clicking' bug

I have a bug in Javascript where I am animating the margin left property of a parent container to show its child divs in a sort of next/previous fashion. Problem is if clicking 'next' at a high frequency the if statement seems to be ignored (i.e. only works if click, wait for animation, then click again) :
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
//roll margin back to 0
}
An example can be seen on jsFiddle - http://jsfiddle.net/ZQg5V/
Any help would be appreciated.
Try the below code which will basically check if the container is being animated just return from the function.
Working demo
$next.click(function (e) {
e.preventDefault();
if($contain.is(":animated")){
return;
}
var marLeft = $contain.css('margin-left'),
$this = $(this);
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
$contain.animate({
marginLeft: 0
}, function () {
$back.fadeOut('fast');
});
} else {
$back.fadeIn(function () {
$contain.animate({
marginLeft: "-=" + regWidth + "px"
});
});
}
if (marLeft > -combinedWidth) {
$contain.animate({
marginLeft: 0
});
}
});
Sometimes is better if you create a function to take care of the animation, instead of writting animation code on every event handler (next, back). Also, users won't have to wait for the animation to finish in order to go the nth page/box.
Maybe this will help you:
if (jQuery) {
var $next = $(".next"),
$back = $(".back"),
$box = $(".box"),
regWidth = $box.width(),
$contain = $(".wrap")
len = $box.length;
var combinedWidth = regWidth*len;
$contain.width(combinedWidth);
var currentBox = 0; // Keeps track of current box
var goTo = function(n) {
$contain.animate({
marginLeft: -n*regWidth
}, {
queue: false, // We don't want animations to queue
duration: 600
});
if (n == 0) $back.fadeOut('fast');
else $back.fadeIn('fast');
currentBox = n;
};
$next.click(function(e) {
e.preventDefault();
var go = currentBox + 1;
if (go >= len) go = 0; // Index based, instead of margin based...
goTo(go);
});
$back.click(function(e) {
e.preventDefault();
var go = currentBox - 1;
if (go <= 0) go = 0; //In case back is pressed while fading...
goTo(go);
});
}
Here's an updated version of your jsFiddle: http://jsfiddle.net/victmo/ZQg5V/5/
Cheers!
Use a variable to track if the animation is taking place. Pseudocode:
var animating = false;
function myAnimation() {
if (animating) return;
animating = true;
$(this).animate({what:'ever'}, function() {
animating = false;
});
}
Crude, but it should give you the idea.
Edit: Your current code works fine for me as well, even if I jam out on the button. On firefox.

Categories

Resources