continuous scolling ticker - avoiding jumping? - javascript

I'm trying to get an infinite scrolling ticker type of thing working smoothly.
To make it continuous I am removing the first element and replacing it at the back once it is out of view, but this makes the container element jump a little in the amount of time it takes to reposition the element.
see here: http://jsfiddle.net/rFwfN/
is there anyway around this? is there a better way of making this scrolling element continuous?
I thought of cloning the set of elements so there are two, so making the dom switch less frequent.

http://jsfiddle.net/rFwfN/6/
You need to reset position before injecting:
var scrollone = function() {
$('carousel').tween('left',[0, (60 *-1)]);
$('carousel').setStyle('left', '0px').getFirst().inject($('carousel'));
}

$('carousel').getFirst().inject($('carousel'));
$('carousel').tween('left',[0, (60 *-1)]);
Not sure how to do with mootools. Tween must stop before element injection and begin once injection is done.

Related

How to trigger an SVG animation on scroll?

So I've finally cracked SVG animations (totally through cheating) and like most sites that use them if they're halfway down the page they begin automatically and you miss it, so how is it possible to trigger the animation on scroll to that div container?
Any help would be great,
Thanks!
You can use
beginElement() function to starts animations manually.
for this to work, you have to set the begin attribute of animate element to indefinite
a simple example would be something like
window.onscroll = function(){
var anime= document.getElementsByTagName('animate')[0];
// check for the amount of scroll
anime.beginElement();
}
You could also make use of beginElementAt()
read more about svg Animation Timing Control
side note: Can't be more accurate since you haven't shared much info or code samples, and not sure what you meant by 'cheating'

JS and Animate.css interval Issue

I am using animate.css for a feed. I have a div named feed that uses uses the slideInLeft class, remains for 3 seconds, then uses the fadeOut class. At this point, I need to change the content of the div and start again. Here's what I've got:
HTML:
<div id="feed"></div>
JS:
var myCars=new Array("Saab","Volvo","BMW");
var wIndex = 0;
$('#feed').text(myCars[wIndex]);
setInterval(function () {
++wIndex;
if (wIndex >= myCars.length) {
wIndex = 0;
}
$('#feed').removeClass('animated slideInLeft');
$('#feed').addClass('animated fadeOut').addClass('hidden');
$('#feed').text(myCars[wIndex]);
$('#feed').removeClass('animated fadeOut').removeClass('hidden');
$('#feed').addClass('animated slideInLeft');
}, 3000);
http://jsfiddle.net/tjfo/5a3SL/
The initial change from the first element in the array to the second works properly, fade out, slide in. All the following transitions just change the text in the div with no fade out, slide in. Animate.css is the preferred method for completing this task. Can anyone help figure out how to make it work properly?
Thanks!
I think you're looking to remove the animated and slideInLeft classes prior to applying subsequent classes. Maybe remove those classes right off, then in a timeout of say, 25ms, do the rest of the logic.
Here's a demo: http://jsfiddle.net/5a3SL/3.
When animating with CSS this is a fairly common thing since you need to give the browser time to calculate the new layout without those classes before applying new classes, otherwise the correct state won't exist in the layout for the new class to properly animate.
Also, that honestly seems like too much CSS for a simple animation... the trickiest thing about animations is having to re-write your CSS declarations for 4 different vendor prefixes as well as the standard declaration.
Another way to handle this would be to set a timeout at the end of the loop that is at least as long as the animation (the slide-in) and remove the unnecessary classes then.

Controlling the animation

I am creating a whack-a-mole style game where a sum is given and numbers animate from the bottom of the container to the top. The aim of the game is to click the correct answer to the sum and collect as many correct answers as possible.
I have also added a couple of extra icons to make the game more fun. One of the icons is a flame which speeds up the animation for 5 seconds.
At the moment it makes all the icons move really fast all at once. Instead of this happening I want the flow to continue as usual, but at a faster pace.
This is what I have so far..
$(".character").click(clickThrottled(function () {
if ($(this).hasClass("heat")) {
$(this).effect("explode", 400);
$("#container").children().css('top', '400px').fadeIn(1000).animate({
'top': '-100px'
}, 3000).fadeOut(1000);
}
}));
Can someone show me where I am going wrong? Look at the demo and click the flame icon to get a better understanding of the problem.
Fiddle: http://jsfiddle.net/pUwKb/52/
Easing will make all the elements ease to the top at the same time, but in a stylish way (like they slow down at the end.)
What you actually need to do is keep a flag called 'isFlameOn' or 'speedModifier' would be better. When a flame icon is clicked, set 'speedModifier' to equal like 2 or 3, which will make the speed twice or three times as fast as normal.
Remove this:
$("#container").children().css('top', '400px').fadeIn(1000).animate({
'top': '-100px'
}, 3000).fadeOut(1000);
Because you will be changing the speed of objects individually.
Now go down to wherever you manage each icon (move them) and instead of saying: item[i].y -= item[i].speed;
Do item[i].y -= item[i].speed * speedModifier;
If you make them animate to get to the top, then you will need to keep track of each of those animate intervals and reset them. So if you create an item and then .animate it, you will need to remove that .animate effect and create a new one with the compensated speedModifier percent. You will have an easy day if you did it frame by frame instead :).
When you want the flame effect to run out, just set speedModifier back to 1. If you animated each item, you'll need to again remove the current .animate and replace it with a normal speed. Be sure to keep track of each item's random speed so that you can reset its speed back to the original speed after the effect wears off.
Look at the different easings provided by jQuery UI, they should solve your problem. To use them just set property easing of animate (if you need more advanced ones you should also include jQuery UI).
For further customization you can use the step callback of animate.

weird jQuery UI Slider behavior

I'm developing a simple one page website and I'm integrating the jQuery UI Slider. The website I'm integrating it in is : Website.
It seems like I'm having a little problem with the slider. If you look closely at the slider when navigating with the left and right arrow ( or the left and right keyboard keys ) you will notice that when going backward, before the last step, the min range jumps ahead the handle with a few pixels ( the background image ).
And also the animate property attached to the handle it doesn't work when using the mouse cursor to move the handle, per say the handle is in position 0 and you click on the last position, normally it should animate to the last position but it jumps there.
Could someone tell me how to fix these bugs ? I tried working on the CSS for the first problem but it doesn't seem to be because of that.
"min range jumps ahead the handle" - I've reduced the bug here: http://jsfiddle.net/jefferyto/Gd5dn/
This is a bug in jQuery.animate() when animating non-pixel values; Slider uses percentages. Before animating, jQuery converts the element's starting value (in pixels) into the end value's units, and assigns this non-px starting value to the element (lines 8601-8605 in jQuery 1.7.2 (unminified)).
The calculation is flawed for small end values (like 0%), and so the range's starting width is larger than what it should be.
I've opened a pull request with a fix; the same fix can be applied to the current stable version of jQuery.
Update: You can find a plugin that fixes this bug (for jQuery 1.7.2) here: http://jsfiddle.net/jefferyto/zbkQX/
Copy from (at the top)
// Start jQuery.animate() fix
to (before the test code)
// End jQuery.animate() fix
It should work if you paste this code into your plugins.js.
"it should animate to the last position but it jumps there" - this is because the Slider and jPages plugins are connected with circular callbacks.
When the user clicks on the slider, Slider triggers a slide event then animates the handle and range. The slide event handler calls jPages to change to the new page. jPages calls its assigned callback function, which passes the current page number back to Slider. Slider sets its value and starts to animate the handle/range.
After the slide event, Slider goes back to animating the handle and range (which is actually the second time it is animating). Slider calls .stop(1, 1) on the elements before animating, which causes the first animation to stop and jump immediately to its end value. (The second .animate() does nothing since the elements are already in the correct position.)
(I hope that made sense :-) )
I suggest adding logic in the jPages callback to call Slider with the new page number only if the trigger isn't originally from Slider.
Update: I think you'll need to update both callbacks:
For Slider:
slide: function(event, ui) {
if (!self.paging) {
self.paging = true;
$(self.shop_navigation_class).jPages(ui.value);
self.paging = false;
}
}
For jPages:
callback: function(pages) {
var data = {
current_page: pages.current,
total_pages: pages.count
}
self.set_local_storage_data(self.data_key, JSON.stringify(data));
if (!self.paging) {
self.paging = true;
$(self.shop_slider_class).slider("value", pages.current);
self.paging = false;
}
}
Please let me know if this works for you.
The simplest answer is probably to just not use jQueryUI's slider.
Having looked at your code it looks like you're easily competent enough at JS and CSS to replicate its appearance and core behaviour yourself, and make it work exactly how you want it to.

Finding the first word that browsers will classify as overflow

I'm looking to build a page that has no scrolling, and will recognize where the main div's contents overflow. The code will remember that point and construct a separate page that starts at that word or element.
I've spent a few hours fiddling, and here's the approaches that past questions employ:
1. Clone the div, incrementally strip words out until the clone's height/width becomes less than the original's.
Too slow. I suppose I could speed it up by exponentially stripping words and then slowly filling it back up--running past the target then backtracking slowly till I hit it exactly--but the approach itself seems kind of brute force.
2. Do the math on the div's dimensions, calculate out how many ems will fit horizontally and vertically.
Would be good if all contents were uniform text, ala a book, but I'm expecting to deal with headlines and images and whatnot, which throws a monkey wrench in this one. Also complicated by browsers' different default font preferences (100%? 144%?)
3. Render items as tokens, stop when the element in question (i.e. one character) is no longer visible to the user onscreen.
This would be my preferred approach, since it'd just involve some sort of isVisible() check on rendered elements. I don't know if it's consistent with how browsers opt to render, though.
Any recommendations on how this might get done? Or are browsers designed to render the whole page length before deciding whether a scrollbar is needed?
Instead of cloning the div, you could just have an overflow:hidden div and set div.scrollTop += div.height each time you need to advance a 'page'. (Even though the browser will show no scrollbar, you can still programmatically cause the div to scroll.)
This way, you let the browser handle what it's designed to do (flow of content).
Here's a snippet that will automatically advance through the pages: (demo)
var div = $('#pages'), h = div.height(), len = div[0].scrollHeight, p = $('#p');
setInterval(function() {
var top = div[0].scrollTop += h;
if (top >= len) top = div[0].scrollTop = 0;
p.text(Math.floor(top/h)+1 + '/' + Math.ceil(len/h)); // Show 'page' number
}, 1000);
You could also do some fiddling to make sure that a 'page' does not start in the middle of a block-level element if you don't want (for example) headlines sliced in half. Unfortunately, it will be much harder (perhaps impossible) to ensure that a line of text isn't sliced in half.

Categories

Resources