making a function works on specific widths - javascript

I am trying to make this function works only when the screen size is above 1024px.
//Parallax background image
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};$(window).bind('scroll', update); update();
Here is what I have tried to do:
//Parallax background image
var velocity = 0.5;
$(window).on("ready resize", function() {
if ($(window).width() < 770) {
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};});$(window).bind('scroll', update); update();
I really don't know what I am doing wrong...

You haven't stated what the problem you're coming across is. If it's "my code doesn't work", then perhaps you should check your syntax first. Your braces are messed up.
//Initialize velocity and empty update function
var velocity = 0.5;
var update = function () {};
//When window is ready (content loaded) OR resized, execute the following function
$(window).on("ready resize", function () {
if ($(window).width() >= 1024) { //Check if window width is 1024px wide or larger
update = function () { //Set update to run this function when executed.
var pos = $(window).scrollTop(); //Get scrollbar position https://api.jquery.com/scrollTop/
//For each element with 'parallax' class, execute the following function
$('.parallax').each(function () {
var $element = $(this); //Get the current parallax-classed element
var height = $element.height(); //Save the current height of this element
//Set the CSS of this parallax-classed element set the background position
$(this).css('background-position', '40% + ' + Math.round((height - pos) * velocity) + 'px');
});
};
} else { //Execute if screen width is < 1024px
update = function () {}; //Set update to do nothing
}
});
//When window is scrolled through, run the update function
$(window).bind('scroll', update);
//update();
Last line is unnecessary, as resize will handle function value, and scroll will handle the execution.
You were missing a + or - within the background-position setting.
So for example, if the result of your Math.round() was "30", then Javascript would interpret that line as $(this).css('background-position', '40%30px'); which obviously would cause issues. I'm sure you wanted it to say something like $(this).css('background-position', '40% + 30px');.

Related

Delay svg onscroll animation from animating right after it appears on the screen

i am currently developing a website where i used some svg technology! However, i have some svg icons that are animated on scroll but this happens as soon as they appear on the screen! The problem is that i need these icons to appear on the screen and instead of getting triggered straight away i need it to wait for the user to scroll i little bit more and then start animating! this is the js i used:
$(window).scroll(function() {
drawLines();
});
function drawLines(){
$.each($(".red-line"), function(i, val){
var line = val;
drawLine($(this), line);
});
}
function drawLine(container, line){
var length = 0;
var pathLength = line.getTotalLength();
var distanceFromTop = container.offset().top - $(window).scrollTop();
var percentDone = 1 - (distanceFromTop / $(window).height());
length = percentDone * pathLength - 500;
line.style.strokeDasharray = [length,pathLength].join(' ');
}
Measure the scroll distance with .scrollTop() and set the drawLines() to start after a specified distance (in the example 200):
$(window).scroll(function (event) {
var sc = $(window).scrollTop();
if (sc>200){drawLines();}
});

execute jquery function for each element containing class

The below function mostly works - it moves the backgrounds as I need, however I would like the function to run on any element with a class of "animate", rather than having to call each element down the bottom. I tried $('.animate').load(function(){}; but it just wont work... Thanks
JAVASCRIPT
$(window).load(function(){
(function(){
$.fn.move = function(){
var $this = $(this);
var offset = $this.offset().top;
var start = 0;
var end = offset + $this.height();
var speed = $this.attr("speed");
return this.each(function(){
$(window).bind('scroll', function() {
var windowPos = $(window).scrollTop();
if((windowPos >= start) && (windowPos <= end)) {
var newCoord = windowPos * speed;
$this.css({'background-position': '0 '+ newCoord + 'px'});
};
});
});
};
})(jQuery);
$('.animate').move();
});
HTML
<div class="welcome_6"></div>
<div class="welcome_5"></div>
<div class="welcome_4"></div>
<div class="welcome_3"></div>
<div class="welcome_2 animate" speed="-1"></div>
<div class="welcome_1 animate" speed="0"></div>
EDIT:
When I scroll the page the elements move according to the scroll location. Each element moves at a different speed (set as html attribute). This code moves them all at the same speed.. I'm assuming the $('.animate') should be somewhere up the top replacing the $.fn.move but i cant figure it out..
Should be $('.animate') instead of $('animate') note the dot at the start of the query which says to the jQuery that you are looking for a class.
I think the issue is with the way you are using the immediately invoked function inside the load function and you are passing in jQuery at the bottom and not into the immediately invoke function. This will update the background position as long as you script tag is placed after the jquery script tag
Here is a link to js fiddle:
UPDATE: https://jsfiddle.net/kriscoulson/pnrx34wp/1/
I do not have your exact code for styling so I improvised but if you inspect the elements the background position is being updated;
AND UPDATE :
$.fn.move = function() {
var $this = $(this);
var offset = $this.offset().top;
var start = 0;
var end = offset + $this.height();
return this.each(function(index, element) {
var $element = $(element);
var speed = $element.attr("speed");
$(window).bind('scroll', function() {
var windowPos = $(window).scrollTop();
if ((windowPos >= start) && (windowPos <= end)) {
var newCoord = windowPos * speed;
$element.css({
'background-position': '0 ' + newCoord + 'px'
});
};
});
});
};
$(document).ready(function() {
$('.animate').move();
});
EDIT: Your 'this' binding was off and your speed was declared outside of the this.each

Firing an animation when aligned

I am creating a splitscrolling website and it's working great. But i have one problem, when the user stops scrolling it fires a function called alignWhenIdle and what this does is align the columns so they become "one".
Now that is working nicely but i can't seem to target a specific part of the column that aligns. let's say when the number 2 column aligns ( see image ) i want to be able to fire an animation. I tried using a callback but that fires a function every time the columns are aligned.
This is my JS:
(function ($) {
var top = 0;
var contentHeight, contents, totalHeight;
var locked = false;
var timeout;
var align = function () {
var pos = (top + $(window).scrollTop());
var snapUp = 0 - (pos % contentHeight) < (contentHeight / 2);
var multiplier = snapUp
? Math.ceil(pos / contentHeight)
: Math.floor(pos / contentHeight);
var newTop = contentHeight * multiplier;
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200);
locked = false;
};
var reset = function () {
contentHeight = $('.right').height();
contents = $('.right > .content').length;
totalHeight = contentHeight * (contents - 1);
top = (0 - totalHeight);
};
var scrollRight = function () {
$('.right').css('top', (top + $(window).scrollTop()) + 'px');
};
var alignWhenIdle = function (delay) {
clearTimeout(timeout);
timeout = setTimeout(align, delay);
};
$(document).on('ready', function () {
reset();
scrollRight();
});
$(window).on('scroll', function () {
locked = true;
scrollRight();
});
$(window).on('mouseup', function (e) {
if (locked) {
align();
}
});
$(window).resize(function () {
locked = true;
reset();
scrollRight();
alignWhenIdle(300);
});
$(window).on('mousewheel', function (e) {
alignWhenIdle(300);
});
$(window).on("keyup", function (e) {
alignWhenIdle(300);
});
})(jQuery);
http://jsfiddle.net/ev3B8/
Any help is much appreciated,
Cheers
See http://jsfiddle.net/5T9Y8/
Scroll till the column 2 and see result...
In the method align I've added a callback:
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200, function(){
$(".animate").animate({ marginLeft: "200px" },300);
});
Works well, did you need exactly that?
EDIT
You should just check for some condition.
E.g. based on this solution Check if element is visible after scrolling you can build this:
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200, function(){
if (isScrolledIntoView(".animate")) $(".animate").animate({ marginLeft: "200px" },300);
});
See updated solution here http://jsfiddle.net/5T9Y8/1/
This is only one way, I'm really sure there is a way to do it even better. E.g. you can calculate the current elements which are shown and then just find the things only inside of them.
I tried using a callback but that fires a function every time the columns are aligned.
Use one method for functioning only once instead of on.

I can't put some delay/animation

I have a function to set a top in a div, for show the notices.
Now i just want to put a delay to this function (effect), because the "top" is set to fast, and it's so horrible.
var rolarbaixo = function() {
var newtop = $('.plugin-noticias-rolar').position().top - 80;
$('.plugin-noticias-rolar').css('top', newtop + 'px').delay( 800 );
}
I tried to use .delay, but doesn't work.
Any help?
I gues what you want here is animate() to keep a smooth transition, try this:
var rolarbaixo = function() {
var newtop = $('.plugin-noticias-rolar').position().top - 80;
$('.plugin-noticias-rolar').animate({top : newtop + 'px'},800);
}

jQuery - Fixing the animation

I am creating a new "whack-a-mole" style game where the children have to hit the correct numbers in accordance to the question.
I have the numbers animating from a set top position to another with a random width so that they look like they are floating up like bubbles.
The only problem I am having with it is that sometimes the numbers glitch and the width on them changes suddenly making it appear to jump from one side of the container to the other.
The only explanation I can think of is the width must be resetting somewhere which I have tried to look for.
Either I am blind or it is something else, can someone help me to find the source of the problem.
Here is the code that maps the numbers...
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function scramble() {
var children = $('#container').children();
var randomId = randomFromTo(1, children.length);
moveRandom("char" + randomId);
}
function moveRandom(id) {
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css(
'top', '400px'
).fadeIn(1000).animate({
' top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
window.cont++;
}, 1000);
});
Here is also a working fiddle so you can see the issue I am talking about: http://jsfiddle.net/pUwKb/26/
The problem is that you are re-entering your moveRandom function for an ID that is already animated. The new width calculation causes the piece to seem to jump when it is reassigned during the already animated movement. One way to fix this is to reject new piece movements for pieces you are already animating. I modified your jsFiddle and fixed it with this code:
// Keep track of the pieces actually moving
var currentMoving = [];
function moveRandom(id) {
// If this one's already animating, skip it
if ($.inArray(id, currentMoving) !== -1) {
return;
}
// Mark this one as animating
currentMoving.push(id);
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css('top', '400px').fadeIn(1000).animate({
'top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
// Mark this as no longer animating
var ix = $.inArray(id, currentMoving);
if (ix !== -1) {
currentMoving.splice(ix, 1);
}
window.cont++;
}, 1000);
});
}
Forked jsFiddle here.
Edit: The OP wanted to show more divs at once without speeding the animation up. To do this I added 20 more character divs (each a duplicate of the first 10 numbers), fixed the guarding code a bit, altered the CSS to specify the image of the character by class, and then put a limit of 20 animations at a given time. I also put a loop around the rejection of an already animated piece, to pick another. I made some other minor improvements. Updated JSFiddle here.

Categories