stopping a for loop- jquery - javascript

previous question
I was looking at this question but I can't get it to apply to my problem.
Here's what I want to do:
loop through a set of html tables using a button to start
pause the animation using another pause button
resume the animation where it left off
this is something similar to what I'm working on: fiddle
My current version is too cumbersome to make an updated fiddle, but the concept is the same. I'll just be changing the content of the table like the right-most slider does.
Here's the code:
$('#Animate1').click(function(e){ //controls the tabR animation (top small table)
for(i = 1; i < 37; i++){ //number of frames in the animation
(function(i){
setTimeout(function(){
$('#amount1').val(i); //this changes the number corresponding to the slider position
updateTable2(i); //this updates the contents of the html table
updateHighlightedCell(); //this controls the "highlighted cells"
$('#hSlider').slider({ animate:true,value: i});}, 1000 ); //this animates the slider
}(i));
}
});
I'm also having trouble with the delay. I was trying to work the delay into the loop, but it seems it's just the starting delay. I'd like to be able to control the frame rate a bit.
Many of the examples I've seen stop infinite loops, but mine is finite. How can I stop this loop and start it again? My ultimate loop will have 365 "frames" in it so it won't be quite as fast.
Any help would be appreciated. Thanks!

I made a simple version in a JSFiddle of what you may be interested in, and hopefully extract the components that will be helpful to you. Also threw in a ton of comments to help understand the pieces.
The basic idea behind my method is having the setInterval() act as your for loop, and once per loop it will check to see if clearInterval() has been called on it. You will have a global counter to keep track of the position.

Related

issues with Raphaƫl and removing objects within svg

if you open the code pen there is a fire button. it will launch a bunch of ellipses and then when it hits it will cause a burst. if you look the ellipses ,which there are two sets of, they are still there. I have tried using the below
d3.selectAll("ellipse").remove()
$("ellipse").remove()
$("ellipse").each(function(){this.remove()})
http://codepen.io/daniel667/pen/QwMWrm
the code pen above will help show what im talking about the second fire button to the far right is what ive been trying to use to kill the ellipses so I don't wait for the animation the functions at the very bottom.
I would create a Raphael set, or an array and store the elemets in that, so you can reference them later to remove. If they will be used repeatedly, it may be worth not removing them, but just hiding them rather than recreating each time.
var mySet;
...
mySet = paper.set();
mySet.push( circi );
....
function throwss() {
mySet.forEach( function( el ) { el.remove(); });
}
Example: codepen
For speed, you may also want to look into Velocity.js, also be aware for animation filters can be quite resource heavy.

Executing a function while listening to a changing value

I'm using iosSlider to display artwork here : http://artiris.clients.twi.tl/galeries/galerie-bleue
I wish to add a blur filter to works that are outside the center. Although the plugin does not have an 'active' class setting, I could easily add one with a simple function to do this.
Here's the tricky part. I want the blur to transition in and out. Not with a time value, but rather I wish for the transition to be linked to the slider movement. For example, as an artwork approaches the center, the blur value will be connected to the movement and will be 0 when the artwork is in the center. I want this because the slider supports touch.
The slider object does provide it's real time position so I can figure out what blur value to set. However, write a do/while loop for this, the browser just crashes. Also there are onSlideStart and onSlideComplete events but I can't get my head around how to execute a function on one event and stop it on an other.
All in all, I just need someone to steer me in the right direction as to how I can do this cleanly and effectively.
Thanks
Unless you have some kind of "onDrag" event going off constantly, there are only two ways I can think of handling this.
First: a setTimeout that goes every millisecond or so, which adjusts the blur. This is almost certainly not a good option, but it is technically an option. This could cause performance issues, particularly on low-speed devices. It would also mean that the blur could be inconstant, as the timeout would probably not actually get run every millisecond.
You can't use a loop for it and enable/disable the loop according to events, as you suggested in the comments, because javascript is single-threaded: once the loop started, no other javascript will ever be run, and you'll always lock up your browser.
Second: A CSS only solution. If the movement is CSS only, then with any luck the blur can be done in the same way. Sadly I'm not a CSS expert, so I'm not sure of the best way of doing this.
Sorry, this isn't a very good answer to your question, but I wanted to explain the javascript option for you, and the reason for why you probably shouldn't do it.
iosSlider dev reporting in with some insight.
You could add your own function inside the touchmove event within the iosSlider plugin. This function would then fire alongside the iosSlider dragging. I recommend placing it somewhere after line 1806. If I was to code it, that's how I would do it.
Well here it is. http://artiris.clients.twi.tl/galeries/galerie-bleue
Not sure if it's the best way of doing it but it seems to work!
When the slider starts moving, I start a timeout which runs a function every 100ms. The timeout clears when the slider stops moving.
Here is my function :
function adjustFilter() {
var nodes = $gallerySlider.data('iosslider').slideNodes,
stage = $gallerySlider.data('iosslider').stageWidth,
matrix = $slider.css("-webkit-transform") ||
$slider.css("-moz-transform") ||
$slider.css("-ms-transform") ||
$slider.css("-o-transform") ||
$slider.css("transform"),
matrixArray = matrixToArray(matrix),
position = Math.abs(matrixArray[4]);
for(var i = 0; i < nodes.length; i++) {
var $node = $(nodes[i]),
nodeMatrix = $node.css("-webkit-transform") ||
$node.css("-moz-transform") ||
$node.css("-ms-transform") ||
$node.css("-o-transform") ||
$node.css("transform"),
nodeMatrixArray = matrixToArray(nodeMatrix),
nodePosition = Math.abs(nodeMatrixArray[4]),
distance = Math.abs(Math.min(Math.max(parseInt(nodePosition-position), stage*(-1)), stage)),
tx = distance/stage;
$node.css({ '-webkit-filter' : 'blur('+tx*10/2+'px) grayscale('+tx+')' })
}
}
Basically it gets the position of the slider. Then for each node I get it's current position and calculates the distance from the center. This distance is than normalised so that it's never greater than the width of a slide. I then use that number to set the blur and grayscale for every node in real time. This way the effect is continuous.
So far, performance seems to be good. In any case, I'm going to run the function only when the filter property is supported by the browser.
If anyone can suggest on ways I can improve this code, I'm all ears.

How to harness control of my JQuery coded sliding divs?

Essentially I have 4 divs that take turns sliding in and sliding out with delays and then it recalls the function. Like so:
$(document).ready (function bradslide(){
$("#slide1").delay('1000').slideDown('1000').delay('6000').slideUp('1000');
$("#slide2").delay('9000').slideDown('1000').delay('6000').slideUp('1000');
$("#slide3").delay('17000').slideDown('1000').delay('6000').slideUp('1000');
$("#slide4").delay('25000').slideDown('1000').delay('6000').slideUp('1000', 'swing', bradslide);
}
);
Let me say that this works fine, but that I am open to cleaning it up or making it easier or more up to standard if suggestions are made.
However my question is this: How can I arrange this so that the end user can manipulate the animation. This slides through the divs on its own, but ideally I would like to have a couple buttons to click to go backward or forwards (I think you get the idea).
Any suggestions of how or where to begin would be greatly appreciated. I imagine I might have to scrap this little piece of code as it stands. Thanks in advance guys.
Despite my own comment, I do have some general advice:
Look into using classes instead of IDs, and then use jQuery's DOM-traversal methods to identify what the next slider candidate is. Tracking the "currentSlide" and then targeting the "nextSlide" (identified with a .next() perhaps?) means that you can add any number of slider divs (with a class instead of ID, remember?) and still have it work.
The user controls (next, prev, or selecting a specific slide) simply interrupt the timer (probably a setTimeout instead of .delay()) and then invoke the exact same function that brings the next slide into place.
To make code more reusable and flexible, you should use some variables. For example, if your slide duration is going to be 1000, you would have var duration = 1000 scoped to an appropriate place (the document ready function is fine... or the sliding function) and then in your function call (whatever it ends up looking like), you would use .slideDown(duration). Then you can set that value to whatever you want and update it easily later.
Extending on the above, you could even build an API allowing you to pass values into your custom slider function:
var bradslide = function(container, delay, duration) {
// do stuff with a parent container, some delay value, and a duration value
};
bradslide('sliderParent', 6000, 1000);

Auto pagination of set number of items (with auto scroll)

I am trying to find a jQuery script that will take list items and virtually paginate them into 9 items per page. I have seen similar scripts on Dynamic drive, but they do not auto-play.
For example: http://www.dynamicdrive.com/dynamicindex17/virtualpagination.htm
Demo #1 here is almost perfect if it auto-played with a slide or fade effect. Is there a script out there that does this? Or is it easy to modify this script?
Any help is appreciated!
Thanks.
"autoplay" as you described can be achieved with a setInterval. Now I dont know the internals of that script, but something sort of like this should work.
// New image every 3 seconds
setInterval(function() {
slideShowObj.next();
}, 3000);
Where "slideShowObject" is some object that has a next function that shows the next item. Filling in that middle line is up to you.

Increase left margin in MooTools

I want to increase the left margin by -190px with each click a maximum of 6 times. I currently have
$$('#goright').addEvent('click', function(){
$$('#buttons').tween('marginLeft', -190);
})
But this only fires once. I need to run on every click (jQuery would use something like ++) and then only to a maximum of 6 times (I assume this would also use something like < 6).
Any help???
This is one way to do it. Basically create a global var count and increment it every time by 1. On click even basically check to see if click is less than 6 and if it is grab all the buttons and do an each loop on them and then tween them individually. The trick is to get the current el's margin-left style and then convert it to int in order to drop the px and then add or subtract depends on where you want the element's margin-left to go. Here is the JSFIDDLE demoing it in action, but instead of going -190 i went with +10 so you can see the effect. Please let me know if this is what you are looking for. By the way this is using Mootools core 1.3 fully compatible:
var count = 0;
$('goright').addEvent('click', function(){
if(count < 6){
$$('.btn').each(function(el){
el.tween('margin-left', el.getStyle('margin-left').toInt()-190);
});
}
count++;
});
HTML i used:
<button class='btn'>1</button>
<button class='btn'>2</button>
<button class='btn'>3</button>
<button class='btn'>4</button>
<div id='goright'>Click To Go Right</div>
This is a funny thing to do, actually! If you can use MooTools More, there's the possibility to define pseudo events. Events, that "do something" with themselves after executing. So insted of myEl.addEvent('click', fn) you would use myEl.addEvent('click:once', fn). In MooTools, :once is defined, it fires once, then deattaces, that means, after a second click on myEl, nothing will happen (the EventListener has deatached).
I've created a :times(n) pseudo event, no big deal, but it makes clear how to use these so-called pseudos. Here is a link to it.
Maybe this can help you or someone else.
Cheers and happy coding!

Categories