I'm trying to workout an efficient way to cycle though in 25% increments the background image of an element, but when it gets to 100% it would go back to 0% on the next increment.
I can do something like this:
var currentPos = $('.ele1').css('background-position');
var elementPositions = currentPos.split(' ');
var x = Number(elementPositions[0].replace(/[^0-9-]/g, ''));
//var y = Number(elementPositions[1].replace(/[^0-9-]/g, ''));
// only want to do the x axis
x = (x == 100) ? 0 : x += 25;
$('.ele1').css('background-position', x + "%" + " 0");
But I don't like the fact I have to call the element twice. Is there a more efficient way to increment a % with jQuery and have it reset back to 0% after 100%?
I did think to do it with CSS .classes. But I don't really want to be restricted to what's in my style sheet.
You can pass a callback function to jQuery's .css() method:
$('.ele1').css('background-position', function (i, value) {
var x = parseInt(value, 10);
return (x == 100 ? 0 : x + 25) + "%" + " 0";
});
If you're calling this from within a loop/timer/event/whatever, you should cache the $('.ele1') object.
Related
I im quite confused in the negation of the functionality of my function. The original function takes 9 elements starting at nth index and decrease their transform position.
function pushIt(max, target, index, count) {
if (count == max || count == img.children ) {
running = false;
return;
}
var tmp = target[index];
var matrix = window.getComputedStyle(tmp).getPropertyValue("transform");
var translate_left = matrix.split(",")[4];
var translate_top = matrix.split(",")[5].split(")")[0]-215;
tmp.style.transform = "translate3d(" + translate_left + "px," + translate_top + "px,0)";
setTimeout(function(){
pushIt( max, target, index + 1, count + 1 );
},50)
}
What i wanted to do is to negate its functionality , e.g it wont decrease but increase transform position of (nth * 3) - 1 element ( counting down 9 elements )
function pushItDOWN(max, target, index , count) {
if ( count == max || index < 0 ) {
running = false;
return;
}
console.log("down");
var tmp = target[index];
var matrix = window.getComputedStyle(tmp).getPropertyValue("transform");
var translate_left = matrix.split(",")[4];
var translate_top = matrix.split(",")[5].split(")")[0]+215;
tmp.style.transform = "translate3d(" + translate_left + "px," + translate_top + "px,0)";
setTimeout(function(){
pushItDOWN(max, target, index - 1, count + 1 );
},50)
}
}
What second function does is takes elements and set their transform to oblivion (e.g out of viewport) and somehow break the functionality of first function.
Did i overlook some key fact that is causing the problem , i seem to fail to find the root of the problem.
Live demo for better understanding
I'm not 100% sure, but most likely this is your error:
This will result in a string:
matrix.split(",")[5].split(")")[0]
Lets say it is "500", then
matrix.split(",")[5].split(")")[0] + 215
// equals
"500" + 215
// results in (because + is both used as string concatenation as addition)
"500215"
// - will work, because it only has one meaning
"500" - 215 // results in 285
Parse the value as an int (or float if necessary) before adding the 215:
parseInt(matrix.split(",")[5].split(")")[0]) + 215
http://jsfiddle.net/fxLcy/ - example with setTimeout
http://jsfiddle.net/fxLcy/1/ - this is the demo without setTimeout. All elements on right place, but i really need that delayed animation =/
I want to place 6 cards per row via css transition and setTimeout. The point is, that i cant use increment for my left and top parameters inside setTimeout, because this thing just summarizes all my increments and sets elements onto final place.
var self = $(this);
if (increment % 6 === 0 && increment !== 0) {
topIncrement++;
leftIncrement = 0;
};
setTimeout(function() {
self.css({'left' : 10 + leftIncrement * (resizedWidth + 20),
'top' : $("#controlPanel").height() + 10 + topIncrement * (resizedHeight + 20)});
}, increment * 500)
leftIncrement++;
increment++;
So the issue is the variable is being shared accross the timeouts, you want to the javascript to close on each x and y position (you want each tmeout to take a snapshot of the x/y values - javascript closure).
So taking your above code and changing the setTimeout to the following I believe did the trick (please see updated fiddle)
var valuex = 10 + leftIncrement * (resizedWidth + 20);
var valuey = $("#controlPanel").height() + 10 + topIncrement * (resizedHeight + 20)
setTimeout(function() {
self.css({'left' : valuex,
'top' : valuey});
}, increment * 500)
I'm looking for a way to move a div from an array of position with javascript/jquery.
I have trying to do it with jquery.animate but he moved the div with a pause at each iteration of my array.
That could be something like move the div from 0,0 to 120px,230px passing by the 23px,35px;45px,50px etc...
That is for moving an game character on a Tile map
So as requested, some bit of code
First you have a global timer that call a function at short interval to see if it have any action to execute.
In this loop a routine look if some mobile tiles are waiting of any mouvement.
Mobiles are declared as Object class and have a sub function that do the deplacement like that
setPos:function(coord){
var pos = jQuery("#"+this.id).position();
var x = (coord[0] - 32 + this.screenOffX + this.xOffset) - pos.left;
var y =(coord[1] + this.yOffset) - pos.top;
//this.stopAnimation();
//this.startAnimation(this.walkingAnimation);
jQuery("#"+this.id).animate({
left: '+='+ x,
top: '+='+ y
}, 33, function() {
// Animation complete.
});
},
That is a bit messy cause i trying a lot of thing to do the smooth movement that i'm looking for.
so setPos is calling in another place like that
stepMobile:function(mobile){
var wp;/*TEST*/
mobile.changeState("idle");
var ind = mobile.getWayPointIndex();
while(ind < (mobile.getWayPoints()).length - 1){
if (ind < (mobile.getWayPoints()).length - 1) {
wp = (mobile.getWayPoints())[ind + 1];
if (getTime() > wp.time) {
mobile.setWayPointIndex(ind + 1);
ind = ind +1;
}
}
wp = (mobile.getWayPoints())[ind];
var x;
var y = 0;
var z;
x = this.tileWidth * (wp.getTile()).getCol();
z = this.tileHeight * (wp.getTile()).getRow();
var elapsed = getTime() - wp.getTime();
console.log(elapsed);
if (ind == (mobile.getWayPoints()).length - 1) {
console.log('checkForOnStopEvent()');
} else {
//x += 1 * mobile.getWalkSpeed() * mobile.getCosAngle();
//z += 1 * mobile.getWalkSpeed() * mobile.getSinAngle();
}
var coord = this.mapToScreen(x, y, -z);
mobile.setPos(coord);
ind = mobile.getWayPointIndex();
}
},
Again lot of junk code here cause i literally burned my brain but i didn't get any good result.
And you have that global function that run this function over all mobiles waiting for deplacement.
I've just made two simple functions which I linked to the onClick property of two buttons on a HTML page.
One function looks up the width of a div and then it should just add '1', but instead it adds '3'. The other function looks up the width of a div and then it should subtract '1'. Instead of doing that, it adds '1'
Could someone enlighten me why this happens and show me to correct this?
function bigger() {
var div_kubus = document.getElementById('kubus');
var x = div_kubus.offsetWidth;
var y = parseInt(x) + 1;
var tekst = document.getElementById('tekst');
tekst.value = y;
div_kubus.style.width = y + 'px';
/*div_kubus.setAttribute('style','width:'+y+'px');*/
}
function smaller() {
var div_kubus = document.getElementById('kubus');
var x = div_kubus.offsetWidth;
var tekst = document.getElementById('tekst');
x -= 1;
div_kubus.setAttribute("style", "width:" + x + "px");
tekst.value = x;
}
.offsetWidth will return the width including borders and padding:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetWidth
So I'm assuming that you've probably got a 1px border (or padding) that is adding 2 to your expected width (1px for the left, 1px for the right). Therefore, adding 1, adds 3; and subtracting 1, adds 1.
I have a button and onmouseover I want it to move right 100ish pixels at 10 pixels a move then stop. The moving isn't a problem its the stopping. I can do this no problem with jquery but I need to learn how to do it from scratch in javascript. this is my script to move right so far.
function rollRight() {
imgThumb.style.left = parseInt (imgThumb.style.left) + 10 + 'px';
animate = setTimeout(rollRight,20);
}
That moves it right just fine so to stop it i tried taking the amount of loops 5x10=50px and wrote it again as
function rollRight() {
var i=0;
while (i < 5) {
imgThumb.style.left = parseInt (imgThumb.style.left) + 10 + 'px';
animate = setTimeout(rollRight,20);
i++;
};
}
Now, I think I'm missing a piece to make it return the [] values for the while function, but I'm not sure how to make it work. Once I have the move right I can apply the same principle to move it back onmouseout.
If anyone can help me fix this that would be great. If you have a better script to do the animation that is just javascript, no libraries, that would be great too.
EDIT: Because leaving it as a comment didn't work well this is my current code
function rollRight() {
var left = parseInt (imgThumb.style.left);
if(left < 50) { // or any other value
imgThumb.style.left = left + 10 + 'px';
animate = setTimeout(rollRight,20);
}
}
function revert() {
var left = parseInt (imgThumb.style.left);
if(left < 50) { // or any other value
imgThumb.style.left = left + -10 + 'px';
animate = setTimeout(rollRight,20);
}
}
In the revert I'm having a problem getting it to move back. It's probably in the if(left<50) part.
var animate = null;
function rollRight() {
if(animate) clearTimeout(animate);
var left = parseInt (imgThumb.style.left);
if(left < 50) { // or any other value
imgThumb.style.left = left + 10 + 'px';
animate = setTimeout(rollRight,20);
}
}
function revert() {
if(animate) clearTimeout(animate);
var left = parseInt (imgThumb.style.left);
if(left > 0) {
imgThumb.style.left = (left - 10) + 'px';
animate = setTimeout(revert,20);
}
}
If you want to stick with setTimeout, you were close on your first one. I moved some hard coded numbers into variables:
var totalPixels = 100;
var increment = 10;
var frameTime = 20;
var numFrames = totalPixels / increment;
var curFrame = 0;
function rollRight() {
imgThumb.style.left = parseInt (imgThumb.style.left) + increment + 'px';
if(curFrame++ < numFrames) {
animate = setTimeout(rollRight,frameTime);
}
}
You could also switch to use setInterval and then every time the interval fires, decide if you should stop the interval based on some incrementing value.
Try this
var i = 0;
var moveInterval = setInterval(function(){
if(i>=5) clearInterval(moveInterval);
rollRight();
i++;
},20);
function rollRight() {
imgThumb.style.left = parseInt (imgThumb.style.left) + 10 + 'px';
}
Once it gets to 5, it will clear the interval out, and be done.