Sprite Animation using a for loop - javascript

I am trying to create an animation using a sprite sheet and a for loop to manipulate the background position until it has reached the total number or rows in the sheet. Ideally a reset back to the initial position would be practical, but I cannot even get the animation itself to trigger...
With the current function, no errors occur and the background position in my CSS does not change. I even recorded using Chrome DevTools Timeline and there was nothing either then everything related to my page loading. I have also tried using "background-position-y" as well as a simpler value rather then the math I currently have in place.
This is my function:
$(document).load(function() {
var $height= 324;
var $rows= 34;
for(var i=0; i<$rows; i++){
setTimeout(function() {
$('#selector').css("background-position", "0px ", "0" - ($height*i) + "px");
}, 10);
}
});
I hate to ask a question that is similar to previous issues, but I cannot seem to find another individual attempting sprite sheet animation with a for loop, so I suppose it is it's own problem.
p.s. I didn't include a snippet of my HTML and CSS because it is pretty standard and I don't see how that could be the problem. That being said, I am all ears to any potential thoughts!

I am completely revamping my answer
This issue is that the for() loop is not affected by the setTimeout so the function needs to be written on our own terms, not with a loop
Working Fiddle
Here it is..
var $height= 5;
var $rows= 25;
var i = 1; // Starting Point
(function animateMe(i){
if(i<=$rows){ // Test if var i is less than or equal to number of rows
var newHeight = 0-($height*i)+"px"; // Creat New Height Position
console.log(i); //Testing Purposes - You can Delete
$('#selector').css({"background-position": "0px "+ newHeight}); // Set New Position
i++; // Increment by 1 (For Loop Replacement)
setTimeout(function(){animateMe(i)}, 1000); // Wait 1 Second then Trigger Function
};
})(0);

Here is your solution
First Change
$(document).load() To $(document).ready()
And Change .css Syntex as
$('#selector').css("background-position",'0px '+(0 - ($height*i))+'px');
Here is fiddle Check it ihad implemented it on my recent project http://jsfiddle.net/krunalp1993/7HSFH/
Hope it helps you :)

Related

Counting up using jquery

So far I have a little script that detects the scroll top position and at a set level I want it to trigger a jquery counter. So far I have an array with the maximum number inside var = eightyS = [3]; then there is..
if (y > 630) {
$('.targetS').each(function() {
//counter
delay(1000);
});
} else {
return false;
}
Now I've made something similar in C++ years ago (couldn't do it now with a gun to my head) so I followed a similar logic. But this is where I'm stuck. The idea behind this function is that it will do a read out on screen of 0 then 1 then 2 then 3. Any help is greatly appreciated
You could use a setInterval() which executes a function ever second such as below:
var count = 0;
var interval = setInterval(function(){
count++;
$('#counter').text(count);
}, 1000);
I've created a quick JSFiddle
You should be able to wrap this in to your code fairly easily. You may also want to use clearInterval(interval) to stop the function executing when you scroll back up the page; or when you get in to your else block, which would have the same effect. I've added a clearInterval() example to the JSFiddle on click of the stop link. You'll need to make sure the interval variable is in scope when clearing it.

How to run a KineticJS animation once every second and apply easing to it?

I am creating a chronometer for which I already have all the code working. Now I'm trying to tie the rotation of a 'notch' to the passage of seconds. I have the following code-block:
var minutesNotchAnimation = new Kinetic.Animation(function(frame) {
var notch = self.minutesNotchLayer.get('#minutesNotchShape')[0];
notch.rotate(rotationAngle);
}, this.minutesNotchLayer);
minutesNotchAnimation.start();
How can I execute the animation once every second? Also how can I apply custom easing to it? And lastly... how do I control the length of the animation? I find the KineticJS documentation to be really lacking in places, also there are not a lot of comprehensive resources out there that explain the Animation class in depth.
Thanks in advance!
P.S. Here's a fiddle of the complete code in case anyone needs to check it out --> http://jsfiddle.net/k4xA8/
You can't set the animation interval because this object is not doing for that. If you want to make something more accurate (and use easing), it's a lot easier to employ a Tween instead.
By the way, you can use the frame.timeDiff property, or the frame.time in order to control the animation...
var minutesNotchCount = 0;
var minutesNotchAnimation = new Kinetic.Animation(function(frame) {
minutesNotchCount += frame.timeDiff;
var notch = self.minutesNotchLayer.get('#minutesNotchShape')[0];
if (minutesNotchCount >= 40) {
notch.rotate(0.25);
minutesNotchCount = 0;
}
}, this.minutesNotchLayer);
minutesNotchAnimation.start();

jQuery Color Cycle on a href links (Maximum call stack size exceeded and Firefox Issues.)

I'm attempting to make a page that will animate the a href links through a table of colors nice and smoothly. I currently have 2 problems with the code that I'm using experiencing a whole mix of problems relating to bad code (please note that JavaScript and jQuery I'm pretty damn weak at). I'm hoping that some Guru can spend 2mins and let me know what the problem or supply a better solution. (thanks in advance.).
Problems Encountered:
Uncaught RangeError: Maximum call stack size exceeded
Firefox is not smooth while Chrome is (Firefox just changes color).
Some hues are too dark
Performance seems an issue, maybe this is because of the Maximum stack size error
Libraries:
jQuery.v1.10.2.min.js
jQuery.color-2.1.0.js
Code:
jQuery(document).ready(function() {
spectrum();
function spectrum(){
var hue = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
jQuery('body a').animate( { color: hue }, 2000);
spectrum();
}
});
What I need:
Basically all I need is a script that will animate all links on the page from one color to another every 2seconds or more... smoothly. Ideally, I'll like to be able to select 6 or more colors that I know that work but due to my limited knowledge in JavaScript I don't know where to begin.
JSFiddle of the Code in Action
I've made a jsfiddle to hopefully save anyone time or just check what the current output looks like: http://jsfiddle.net/ebZ3x/
Yeah, you're recursively calling indefinitely which will quickly run you out of stack space. What you want instead is for the browser to regularly call your color changing function. We'll use window.setInterval() to accomplish that.
Then we'll also create an array of the six colors you want and we'll just randomly index into it. To add more colors just add them to the array.
jQuery(document).ready(function() {
function spectrum(){
var colors = [
'rgb(256,0,0)', //red
'rgb(0,256,0)', //green
'rgb(0,0,256)', //blue
'rgb(256,256,0)', //orange
'rgb(256,0,256)', //magenta
'rgb(0,256,256)']; //cyan
var hue = colors[(Math.floor(Math.random() * colors.length))];
jQuery('body a').animate( { color: hue }, 2000);
}
var intervalId = window.setInterval(spectrum, 2000);
});
I've been working on your question since you posted it yesterday, and I thought I would give it a shot so I might learn a little about setTimeout. And boy, have I learned - about the complexity of such a "simple" command. It's probably the most difficult I've encountered in javascript.
So I present my "answer" just as something to be viewed, with JoeClacks' answer obviously superior.
This FIDDLE shows the initiation of the timer (runmytimer) after loading the DOM. It changes the background color of two divs randomly. I've let it run for over an hour and it seems not to crash.
I added the "extra" stuff to make sure other things on the page don't interfere with the timer. So when you type into an input box, the timer continues. When you click the "save" button (I just moved the input text to another div) the timer continues.
Here is the relevant JS
var randomcolors = ['#FF00FF','#00FFFF','#FFFF00','#0000FF','#00FF00','#FF0000','#000000','#C0C0C0','#C0C1C1','#CFCHCH','#CCFFCC'];
var timer;
//var timer_is_on = 0;
runmytimer();
$('#saveme').click(function(){
var moveme = $('#getme').val();
$('.movemehere').html(moveme);
});
function runmytimer()
{
t = setTimeout( function(){ runmytimer() }, 1000 );
random = Math.floor(Math.random() * (11 - 0 + 1)) + 0;
$('.putmehere1').css('background-color', randomcolors[random]);
$('.putmehere2').css('background-color', randomcolors[random+1]);
}
For other noobs such as myself who are reading this, I've learned a few things that aren't clearly stated in any documentation (I went to 30-40 sites, that weren't really that helpful).
If you try to put a timer in a loop - its behavior is NOT intuitive. I'm used to BASIC loops where when you do something to STOP the loop - oddly - it STOPS! :-). Not so with javascript. As an experiment I did a loop with a setTimeout in it, and put the i's of the loop in a div. What chaos! The loop printed out all the i's before the first setTimeout was done! I read that the loop is actually creating a different timer for each loop of the setTimeout. Disaster!
You can stop a timer with clearTimeout(nameoftimer).
I'm guessing if you have a routine that stops a timer, it could be restarted at the bottom of the routine with setTimeout(nameoftimer).
I still haven't figured out why a variable assignment such as var timer = setTimeout ( alert('hello'), 1000 ); would not only assign the variable to the code, but also run the code. Not intuitive.
After going to all the sites and trying their code, I went to W3Schools (not held in high esteem by many) and found code that actually worked! I derived my fiddle from that.
Anyway, thanks for the question. I learned a lot!

how to stop moving background-image position

I've background image and by using small javascript code, it moves from right to left.
HTML code
<div id="clouds_image"></div>
Javascript code
var g=0;
var speed=30;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
scroller=setTimeout(function(){rollClouds()},speed);
}
window.addEventListener?
window.addEventListener('load',rollClouds,false):
window.attachEvent('onload',rollClouds);
But i've noticed that, with time my PC CPU memory usage increased ! causing overload on my pc and if i disabled that javascript code, it back to normal.
My question
so i think i need to modify this javascript code that it not keep working forever, i mean, i want to make it to repeat that action only 5 times then stop , maybe i need to define value of g but i'm not good in javascript so any help ~ Thanks.
You need to use a variable to count how many times that function was executed, and use setInterval instead of setTimeout: See example
http://jsfiddle.net/EQDjx/206/ (my counter start from 100 and goes down to 0)
for a more nice effect i recomand you to use jquery. See animate function
http://api.jquery.com/animate/
var g = 1000;
var speed=300;
var counter = 100;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
if (counter < 1) clearInterval(interval);
}
interval = setInterval(function(){rollClouds()}, speed)
A cleaner solution might be to use jQuery to move the background:
function moveClouds() {
$("#clouds_image").css({left:"-2000px"});
$("#clouds_image").animate({left:"2000px"},10000);
}
Then you might set an interval to trigger it every x milliseconds.
setInterval(moveClouds,10000)
JSFiddle is here: http://jsfiddle.net/qXpVX/

Improving Efficiency in jQuery function

The while statement in this function runs too slow (prevents page load for 4-5 seconds) in IE/firefox, but fast in safari...
It's measuring pixel width of text on a page and truncating until text reaches ideal width:
function constrain(text, ideal_width){
$('.temp_item').html(text);
var item_width = $('span.temp_item').width();
var ideal = parseInt(ideal_width);
var smaller_text = text;
var original = text.length;
while (item_width > ideal) {
smaller_text = smaller_text.substr(0, (smaller_text.length-1));
$('.temp_item').html(smaller_text);
item_width = $('span.temp_item').width();
}
var final_length = smaller_text.length;
if (final_length != original) {
return (smaller_text + '…');
} else {
return text;
}
}
Any way to improve performance? How would I convert this to a bubble-sort function?
Thanks!
move the calls to $() outside of the loop, and store its result in a temporary variable. Running that function is going to be the slowest thing in your code, aside from the call to .html().
They work very very hard on making the selector engines in libraries fast, but it's still dog slow compared to normal javascript operations (like looking up a variable in the local scope) because it has to interact with the dom. Especially if you're using a class selector like that, jquery has to loop through basically every element in the document looking at each class attribute and running a regex on it. Every go round the loop! Get as much of that stuff out of your tight loops as you can. Webkit runs it fast because it has .getElementsByClassName while the other browsers don't. (yet).
Instead of removing one character at time until you find the ideal width, you could use a binary search.
I see that the problem is that you are constantly modifying the DOM in the loop, by setting the html of the temp_item, and then re reading the width.
I don't know the context of your problem, but trying to adjust the layout by measuring the rendered elements is not a good practice from my point of view.
Maybe you could approach the problem from a different angle. Truncating to a fixed width is common.
Other possibility (hack?) if dont have choices, could be to use the overflow css property of the container element and put the … in other element next to the text. Though i recommend you to rethink the need of solving the problem the way you are intending.
Hugo
Other than the suggestion by Breton, another possibility to speed up your algorithm would be to use a binary search on the text length. Currently you are decrementing the length by one character at a time - this is O(N) in the length of the string. Instead, use a search which will be O(log(N)).
Roughly speaking, something like this:
function constrain(text, ideal_width){
...
var temp_item = $('.temp_item');
var span_temp_item = $('span.temp_item');
var text_len_lower = 0;
var text_len_higher = smaller_text.length;
while (true) {
if (item_width > ideal)
{
// make smaller to the mean of "lower" and this
text_len_higher = smaller_text.length;
smaller_text = text.substr(0,
((smaller_text.length + text_len_lower)/2));
}
else
{
if (smaller_text.length>=text_len_higher) break;
// make larger to the mean of "higher" and this
text_len_lower = smaller_text.length;
smaller_text = text.substr(0,
((smaller_text.length + text_len_higher)/2));
}
temp_item.html(smaller_text);
item_width = span_temp_item.width();
}
...
}
One thing to note is that each time you add something to the DOM, or change the html in a node, the page has to redraw itself, which is an expensive operation. Moving any HTML updates outside of a loop might help speed things up quite a bit.
As other have mentioned, you could move the calls to $() to outside the loop. You can create a reference to the element, then just call the methods on it within the loop as 1800 INFORMATION mentioned.
If you use Firefox with the Firebug plugin, there's a great way of profiling the code to see what's taking the longest time. Just click profile under the first tab, do your action, then click profile again. It'll show a table with the time it took for each part of your code. Chances are you'll see a lot of things in the list that are in your js framework library; but you can isolate that as well with a little trial and error.

Categories