How do I increment CSS Y position coordinates using jQuery? - javascript

I am creating an animation that changes the value of a background image. It is working perfectly if I hard code in the coordinates, but I am trying to modify it so that it simnply increments the position by 20px.
Here's the code I am using to retrieve the original Y position - works perfectly:
$('.rss,.twitter,.jquery').each(function(){
// Returns "##px" and "##px"
var backgroundPositions = $(this).css('background-position').split(" ");
// Retrieve the original Y position
$(this).data("originalYpos", backgroundPositions[1].slice(0, -2));
});
Now I am trying to increment the value of originalYpos by 20px but this isn't working:
var animateNum = function() {
$('.rss,.twitter,.jquery').animate({
var YPos = $(this).data('originalYpos')+20;
backgroundPosition: 0 + "px " + YPos + "px"}, 400, "easeOutCirc");
};
I do believe it is because the declaration of var Ypos isn't allowed inside the .animate(), but I need to refer to $(this), meaning the value of each of the 3 individual selectors as they are being animated.
Any suggestions are greatly appreciated!

Try:
var animateNum = function() {
$('.rss,.twitter,.jquery').animate({
backgroundPosition: "0 " + ($(this).data('originalYpos')+20) + "px"
}, 400, "easeOutCirc");
};

Why store the old value at all:
From http://api.jquery.com/animate/
Animated properties can also be relative. If a value is supplied with a leading += or -= sequence of characters, then the target value is computed by adding or subtracting the given number from the current value of the property.
So, the code below should work (although I haven't tried it myself)
var animateNum = function() {
$('.rss,.twitter,.jquery').animate({
backgroundPosition: "+=20px"
}, 400, "easeOutCirc");
};

Should be like this:
var animateNum = function() {
$('.rss,.twitter,.jquery').animate({
backgroundPosition: $(this).data('originalYpos')+20 + "px"}, 400, "easeOutCirc");
};

Related

Panzoom, set div position to zoom focal point when zooming

I would like to monitor visually the zooming focal point in the panzooom jquery plugin. in order to do so, I would like to position a little 10x10 div on the same coordinates as the focal point, but somehow it is placing it in a totally different location. Here is my code:
(only posting relevant parts)
$panzoom.panzoom("option", {
contain: false,
increment: 10,
duration: 2000,
animate: true,
exponential: false,
minScale: minScale,
maxScale: maxScale,
panOnlyWhenZoomed : false,
focal: {
clientX: position.left, //coordinates of an existing div.
clientY: position.top
}
});
$panzoom.panzoom('zoom');
var d = document.getElementById('zoomcenter');
d.style.left = position.left+'px';
d.style.top = position.top+'px'; // I expect this div to be
// placed in the same position as the above,
// where I am zooming to. Instead it is placed
// somewhere totally different.
// probably affected by the transform Matrix.
// but not able to figure out why.
var matrix = $panzoom.panzoom("getMatrix");
console.debug("boxl:" + position.left + " boxt:" + position.top + " zcl:" + $('#zoomcenter').offset().left + " zct:" + $('#zoomcenter').offset().top + " Matrix:" + matrix.toString())
//returns this:
// boxl:986.6997680664062 boxt:343.0241394042969 zcl:692.1810302734375 zct:285.1896057128906 Matrix:1.6775,0,0,1.6775,-1133.01,-244.451
EDIT: Additional info:
- the div zoomcenter has absolute positioning.
- the position of $panzoom.panzoom('zoom') does not affect the result.

Show/Hide Text Every Time An Arrow Is Clicked

I need help showing/hiding text on a button click (specifically an arrow). I have a block of text that I have hidden and I need to slide it down in a time consistent with the arrow rotating 180 degrees. I also want it to do this only for the post above the arrow that was clicked. The solution I have come up with in this fiddle has many problems.
Here is the code:
$(function () {
var angle = -180,
height = "100%";
$(".down-arrow").click(function () {
$(".down-arrow").css({
'-webkit-transform': 'rotate(' + angle + 'deg)',
'-moz-transform': 'rotate(' + angle + 'deg)',
'-o-transform': 'rotate(' + angle + 'deg)',
'-ms-transform': 'rotate(' + angle + 'deg)',
});
$(".blog-post").animate({
'height' : height
});
angle -= 180;
height = "50px";
});
});
And these are the issues I am having:
It slides down way too fast
Once it slides back up it won't slide down again.
It does it for every post
This would be more dynamic and clean to use:
First we will take height's of all the .blog-post div's in an array.
Now making height: 50px of the div, after once we know actual height of all the div's. Which will helpful in making div smooth slide as we know height's.
Next on click of arrow class, we will toggle class which holds transform:rotate properties. Along with that we would check corresponding .blog-post div's height. So if it is more than 50px we would make it 50px, else we would take it's actual height from array and give to it.
Here is the JS/JQuery Code:
var totalNum = $('.blog-post').length; // Counting number of .blog-post div on page.
var i, myArray = [];
for (i = 0; i < totalNum; i++) {
var curHeight = $('.blog-post:eq(' + i + ')').outerHeight();
myArray.push(curHeight);
}
$('.blog-post').css('height', '50px');
$('.down-arrow').click(function () {
$(this).toggleClass('invert');
var index = $('.down-arrow').index(this);
var heightCheck = $('.blog-post:eq(' + index + ')').outerHeight();
if (heightCheck < 51) {
$('.blog-post:eq(' + index + ')').css('height', myArray[index] + 'px');
} else {
$('.blog-post:eq(' + index + ')').css('height', '50px');
}
});
Working : Fiddle
If you still do not understand feel free to ask.
I guess you should convert the 100% to pixels (with $(this).parent().innerHeight() or something like that, then it works well.
You should build some sort of toggle: keep track of which blog-post/arrow is up and which one is down (flag the blog posts or the arrows with some sort of class) and based on that, you should let it slide up or down.
Of course, you're referring to the post with a css selector. You should use a combination of $(this), .next() and .prev() functions in order to get the right post(s).
"It slides down way too fast"
Just set an animation duration. See the jquery.animate() documentation.
It seems that jquery is pretty buggy when it comes to animating using percentages. http://bugs.jquery.com/ticket/10669 http://bugs.jquery.com/ticket/9505 Try using pixels instead of percentage http://jsfiddle.net/8obybt1d/1/
"Once it slides back up it won't slide down again."
Because you are not changing the value of height back to hundred%
A rough piece of code:
if (height == "50px") {
height = "100%";
}
else {
height == "50px"
}
"It does it for every post"
Try using the 'this' keyword.
To solve point 2:
$(".blog-post").animate({
...
height = (height === "50px") ? height = "100%": height = "50px";
});

Add to width using setInterval

I am trying to add to the width of the element everytime the setInterval function is invoked
function setProgress(){
var bar = document.getElementById('progress-bar');
var width = 20;
bar.style.width += width + 'px';
//console.log(bar.style.width);
}
window.onload = function(){
setInterval(setProgress, 10);
}
I tried using parseInt(), but everytime I console.log() to the window i see the same width. My end goal is for the width to increase by 20
You need to remove px part from width style and then cast string to number before incrementing it:
function setProgress(){
var bar = document.getElementById('progress-bar');
var width = 20;
bar.style.width = Number(bar.style.width.replace('px', '')) + width + 'px';
//console.log(bar.style.width);
}
Make width a global var, like shown below:
var width = 0;
function setProgress(){
var bar = document.getElementById('progress-bar');
width+= 20;
bar.style.width += width + 'px';
//console.log(bar.style.width);
}
window.onload = function(){setInterval(setProgress, 10);}
Also, you should specify the max width to prevent the progress bar moving outside the working area (for example, modifying the increment line: if(width<500) {width+= 20;} else {return;}).
Alternatively, you can use your original solution by adding couple more statements, namely: removing the "px" unit from style property bar.style.width, then parsing it (converting to Number), then incrementing it and then adding "px" (otherwise, "+" operator will cause a concatenation of strings with output like: 20px20px, 20px20px20px, etc). Such alternative solution will slow down the process and put additional load on CPU (thus, it's not recommended).
Hope this may help. Best regards,
The problem is that width returns a string with units.
Instead, consider storing the number of pixels in a variable:
var bar = document.getElementById('progress-bar'),
width = parseFloat(getComputedStyle(bar).width);
setInterval(function() {
width += 20;
bar.style.width = width + 'px';
}, 10);
var bar = document.getElementById('progress-bar'),
width = parseFloat(getComputedStyle(bar).width);
setInterval(function() {
width += 20;
bar.style.width = width + 'px';
}, 200);
#progress-bar {
background: #0f0;
display: inline-block;
}
<div id='progress-bar'>Progress bar</div>
var width = 0;
function setProgress(){
var bar = document.getElementById('bar');
width+= 20;
bar.style.width = width + 'px';
console.log(bar.style.width);
if(width==200){
width=0;
}
}
window.onload = function(){
setInterval(setProgress, 1000);
}

add up positions from css in javascript

I am trying to code a little game and therefore trying to move an object in a certain area. To get somewhat of a border I am trying to add up positions. However I will simplify this for you and this is what does not work: (in JS)
parseInt( $('#w'+w ).css( 'top' ) + $('#w'+w ).css( 'height' ) )
this should just add up the top position with the height of this element. When I print this out it will tell me it is 100. But when I print height and top without adding them up its height = 500 and top = 100 ( This is how it is in the css code ).
If i swap height and top and add this up the result is 500, so the first element. I got similar calculations, which fit. Any suggestions what went wrong in my code?
You are probably concatenating strings:
// $('#w' + w).css('top') returns the string "100px"
// $('#w' + w).css('height') returns the string "500px"
parseInt("100px" + "500px") // 100
parseInt("500px" + "100px") // 500
I suggest that you change your code to this:
parseInt($('#w' + w).css('top')) + parseInt($('#w' + w).css('height'))
for top use position:
var position = $('#w'+w ).position();
console.log( "left: " + position.left + ", top: " + position.top );
for height or width use jQuery width() and height():
console.log( "width: " +$('#w'+w ).width() + ", height: " + $('#w'+w ).height() );

Change sprites scroll speed

I'm creating a parallax website but I'm using the code of some nice tutorial that I found.
This tutorial came with some JS to change the scroll speed of some sprites using the tag "data-" but even though I already have the sprites with a different scrolling speed compared to the background, I can't modify this speed to my own preference.
This is the JavaScript code:
$(document).ready(function(){
// Cache the Window object
$window = $(window);
// Cache the Y offset and the speed of each sprite
$('[data-type]').each(function() {
$(this).data('offsetY', parseInt($(this).attr('data-offsetY')));
$(this).data('Xposition', $(this).attr('data-Xposition'));
$(this).data('speed', $(this).attr('data-speed'));
});
// For each element that has a data-type attribute
$('section[data-type="background"]').each(function(){
// Store some variables based on where we are
var $self = $(this),
offsetCoords = $self.offset(),
topOffset = offsetCoords.top;
// When the window is scrolled...
$(window).scroll(function() {
// If this section is in view
if ( ($window.scrollTop() + $window.height()) > (topOffset) &&
( (topOffset + $self.height()) > $window.scrollTop() ) ) {
// Scroll the background at var speed
// the yPos is a negative value because we're scrolling it UP!
var yPos = -($window.scrollTop() / $self.data('speed'));
// If this element has a Y offset then add it on
if ($self.data('offsetY')) {
yPos += $self.data('offsetY');
}
// Put together our final background position
var coords = '50% '+ yPos + 'px';
// Move the background
$self.css({ backgroundPosition: coords });
// Check for other sprites in this section
$('[data-type="sprite"]', $self).each(function() {
// Cache the sprite
var $sprite = $(this);
// Use the same calculation to work out how far to scroll the sprite
var yPos = -($window.scrollTop() / $sprite.data('speed'));
var coords = $sprite.data('Xposition') + ' ' + (yPos + $sprite.data('offsetY')) + 'px';
$sprite.css({ backgroundPosition: coords });
}); // sprites
// Check for any Videos that need scrolling
$('[data-type="video"]', $self).each(function() {
// Cache the video
var $video = $(this);
// There's some repetition going on here, so
// feel free to tidy this section up.
var yPos = -($window.scrollTop() / $video.data('speed'));
var coords = (yPos + $video.data('offsetY')) + 'px';
$video.css({ top: coords });
}); // video
}; // in view
}); // window scroll
}); // each data-type
}); // document ready
and this is the HTML markup of a single sprite:
<div class="stars" data-type="sprite" data-speed="10">
<img class="star1" src="img/cenas/1.PNG">
</div>
I tried changing the data-speed value but there aren't any changes. What can I do to have different sprites with different scroll speed?

Categories

Resources