I would like to learn how to do fade, and similar effects on JavaScript. I often get answers, like why not use jQuery, Mootools, etc ? Well, I want to learn how stuff works, then I won't mind using any of these frameworks.
I'm currently learning about making changes on the DOM, so, I've read a lot of stuff on this theme. Also, I've read about Reflow, still, I didn't find any cool stuff on Repaint, but, I'll keep searching.
From seeing source files etc, I see a few methods, that I don't know if they've created or are Core methods of JS.
My question is, is there any resource where I can learn all this neat stuff like smooth position change, fading elements trough opacity or whatever, etc?
Take a look at emile.js. It's brand-spanking new. Great way to learn how to do your own.
Introduced at the recent jsconf conference. Written by Thomas Fuchs (script.aculo.us).
http://github.com/madrobby/emile
Émile Stand-alone CSS animation
JavaScript mini-framework
Doesn't need
a JavaScript framework
Full set of CSS
properties for animation (length-based
and colors)
Easing and callbacks
Less
than 50 lines of code
Get updates on
Twitter: http://twitter.com/emilejs
here's an example that works in firefox and chrome. ie doesn't respect the opacity style.
var ELEMENT;
var STEPS;
var INTERVAL;
var COUNT;
var TIMERID;
// 5 * 200ms = 1 second
STEPS = 5;
INTERVAL = 200;
function Button1_onclick() {
ELEMENT = document.getElementById("foo");
COUNT = STEPS - 1;
TIMERID = setInterval(Fade, INTERVAL);
}
function Fade() {
ELEMENT.style.opacity = String(COUNT / STEPS);
COUNT--;
if (COUNT < 0) {
clearInterval(TIMERID);
TIMERID = 0;
}
}
setInterval and clearInterval are standard js functions. they will execute the given function every x milliseconds. in our case we kill it when we've hit 0 opacity.
sliding a window is a similar process. you'd set the left/right/top/bottom style instead of opacity.
Fading using javascript is basically modifying opacity of an element programmatically. The "smoothness" is done by using timers. Same for position/size changes. You need to read up on css to understand what style properties of an element you have to control using javascript for the effect you want.
If you are really curious, you can dive into the source of yui in github: http://github.com/yui
Related
I built a basic picture carousel a while back, and I'm finally getting around to transferring it from MooTools over to jQuery so I can drop MooTools. I've got the script completely functional, but for whatever reason when the carousel slides in one direction, you can see a "pop" where it resets itself.
I've tried playing around with the order it handles everything, but no matter what it seems to always desync for just a fraction of a section.
Here's a copy of my code: https://jsfiddle.net/Chaosxmk/pf6dzchm/
The offending section of code is this:
styles['position'] = 'absolute';
styles[self.params.axis] = -32768;
$(self.list[0]).css(styles).hide();
$(self.list[0]).appendTo(self.carousel);
$(self.list[conf.mi]).css(self.params.axis, (100-conf.pr)+'%');
styles = {};
styles['position'] = 'relative';
styles[self.params.axis] = 'auto';
$(self.list[conf.mi]).css(styles);
Issue is that $.fadeOut() sets display:none on the element, which causes some strange rendering issues in your setTimeout() callback. Works better if you use $.fadeTo() instead:
if (self.params.direction) {
// Go forward
self.carousel.css(self.params.axis, '-'+conf.pr+'%');
$(self.list[0]).fadeTo(400, 0);
$(self.list[conf.mi]).css(self.params.axis, '100%').fadeTo(400, 1);
} else {
// Go backward
self.carousel.css(self.params.axis, conf.pr+'%');
$(self.list[conf.mi-1]).fadeTo(400, 0);
self.list.last().css(self.params.axis, '-'+conf.pr+'%').fadeTo(400, 1);
}
For simplicity I used a 400ms duration, but you can set this to whatever you need.
JSFiddle
I had a nice idea, namely to use the 'stroke-dasharray' CSS-attribute that can be used on SVG objects, to stroke the paths on the page, giving it a nice artistic way for shapes to appear.
It works perfectly and is supported by most modern browsers as well as phones.
A nice jsfiddle of what I've made can be found here: http://jsfiddle.net/G6ECE/
The code that makes the whole thing tick right now:
num=0;
setInterval(function(){
updateStroke(num);
num+= 0.2;
}, 1);
function updateStroke(num){
// stroke-dasharray is a list of two or more numbers. In this example, percentage values are used to make all paths fully stroked at the end of the animation, irregardless of path length.
$('svg path').css({stroke:'#00FF00','stroke-dasharray':num+'% '+(100-num)+'%'});
}
Obviously this is a very basic, ugly way to animate something.
I want to customize the animation a little: I want to be able to add a custom animation length and also use different easings. Unfortunately, the jQuery $().animate() function that I'd normally use to animate CSS attributes, does not support non-numeric values.
As stroke-dasharray uses two or more numeric(pixel or percentage) values to work, I need an alternative for .animate()
What would be the cleanest way to do this? (with using as much existing jQuery functionality as possible, and as little as possible re-inventing an animation framework)
What about CSS transitions? They also have a better performance than jQuery animations.
http://www.w3schools.com/css/css3_transitions.asp
But be sure not to use both for the same property as jQuery animations interfere with CSS transitions.
Recently, I have been working with a nice robust cross-browser javascript animation object. Once you understand the way it is used, it becomes quite seamless for all or your SVG animations. It can be attached to any svg element and control associated values.
There are some examples that show the various choices of animation performance(linear, quadratic, ease,etc) at:
http://www.svgDiscovery.com/
Below is the object:
var AnimateJS=function(options){
this.options=options
var start = new Date
var iT = setInterval(
function(){
var timePassed = new Date - start
var progress = timePassed / options.duration
if (progress > 1) progress = 1
this.progress=progress
var delta = options.delta(progress)
options.output(delta)
if (progress == 1)clearInterval(iT);
},options.delay)
}
I was wondering if it was possible, using some javascript or jquery, to skip to the next, or go to the last part of a css animation. Lets say we have the following:
#keyframe effect{
0%{opacity:1;}
45%{opacity:1;}
50%{opacity:0;}
95%{opacity:0;}
100%{opacity:1;}
}
that will fade something out and then back in
so lets say I made some buttons. How would I do the following:
$('#next').click(function(){
//skip to the next animation part
});
$('#previous').click(function(){
//skip to the previous animation part
});
It's not really possible unless you break the CSS into different parts based on classes and then add/remove classes.
However, there is an absolutely fantastic javascript library called Greensock, that allows timeline-based animation - and in many cases is faster than CSS animations. It also has the benefit of being cross-browser compatible.
If you were, for example to create something similar using Greensock, it would look something like this:
var effect = new TimelineMax({paused:true});
effect.addLabel('start');
effect.to(
'#myItem',
1,
{css:{opacity:1}}
);
effect.addLabel('step1');
effect.to(
'#myItem',
1,
{css:{opacity:0}}
);
effect.addLabel('end');
effect.play();
$('#gotoEnd').on('click', function(e){
e.preventDefault();
effect.seek('end');
});
With the use of the animation-play-state Property, you can pause an animation and update the transform, then restart it.
element.style.webkitAnimationPlayState = "paused";
element.style.webkitAnimationPlayState = "running";
However you can't pause the animation, transform it, resume it, and expect it to run fluidly from the new transformed state.
At this time, there is no way to get the exact current "percentage completed" of a CSS keyframe animation. The best method to approximate it is using a setInterval or requestAnimationFrame.
This CSS tricks article explains this further, and gives an example of using setInterval. Another option is to use request animation frame
As mentioned GreenSock or Velocity are animation libraries which allow for extremely fast and smooth animations
I'm trying to do very basic, custom animation with JavaScript. I'm using a library called Modernizr to detect HTML5 support, and if a browser doesn't support CSS3 Transitions, I'd like to have my own custom (non jQuery) script that recreates the same effect of CSS3 Transitions.
My idea for this code is this:
JS:
function slide() {
var cur = 0;
while (cur <= 50) {
setInterval("document.getElementById('slider').style.marginLeft=cur + 'px'",100);
cur = cur++;
}
}
HTML (for hovering):
<div id="slider" onmouseover="slide()">
This should slide left.
</div>
This doesn't work (I know it doesn't loop, that's one of the issues that I can't figure out). I'm pretty new with JS so I don't know some pretty basic stuff.
The main reason that I don't want to use jQuery is for educational purposese. I want to know basic JS before I learn jQuery, just so I know how to do the things I want to do.
I'd like this to work for two different cases, one being automatically, one being only on hover (and the hover version doesn't have to loop). I had something kind of working on hover, but the more you hovered over it, the faster it would move.
Thanks!
function slide() {
var cur = 0;
while (cur >= 50) {
setInterval("document.getElementById('slider').style.marginLeft=cur + 'px'",100);
cur = cur++;
}
}
Your code sets cur to 0, and then the while condition is cur >= 50 (*while cur variable is larger or equal to 50) which will never be true because it is 0.
Also, animating with a loop is not a good idea, as the browser likely won't render the results in a manner that is pleasant to look at (or at all). Use setInterval() without the loop.
If I was tasked with writing this, it may look like...
function slide(element, newHeight) {
var currentHeight = element.offsetHeight;
var increaseHeight = function() {
currentHeight += 10;
element.style.height = currentHeight + 'px';
}
var interval = setInterval(function() {
if (currentHeight >= newHeight) {
clearInterval(interval);
}
increaseHeight();
}, 100);
}
jsFiddle.
There are many examples of doing sliding in javascript.
Here is one of them.
http://www.harrymaugans.com/2007/03/06/how-to-create-an-animated-sliding-collapsible-div-with-javascript-and-css/
In your example, if you use setInterval you will also want to call clearInterval. For a description of both you can look at: https://developer.mozilla.org/en/window.setInterval
Hopefully you aren't actually using the onmouseover function in the element, as shown, but are instead checking if you need this, then setting it after the page has loaded.
You may want to look at unobtrusive javascript to get an idea how this can be done well.
There are various articles on this, but you could start with:
http://labs.adobe.com/technologies/spry/articles/best_practices/separating_behavior.html
Is there easier way to make something to appear slowly on webpage? I tried to incrementally increase opacity of the CSS, but it (opacity) tag is different for each browser. Is there well know Javascript function that everyone uses? Or is there any css tag?
[edit] Thanks for Jquery suggestion. Is there other option? My page is very small and don't want to add Jquery. (I know about Google hosting it)
Aargh! Every JS developer here seems to have contracted the jqueryitis!
If you're not yet infected or still want to escape from it, here's a small function that do the job cross browser :)
function appear(elm, i, step, speed){
var t_o;
//initial opacity
i = i || 0;
//opacity increment
step = step || 5;
//time waited between two opacity increments in msec
speed = speed || 50;
t_o = setInterval(function(){
//get opacity in decimals
var opacity = i / 100;
//set the next opacity step
i = i + step;
if(opacity > 1 || opacity < 0){
clearInterval(t_o);
//if 1-opaque or 0-transparent, stop
return;
}
//modern browsers
elm.style.opacity = opacity;
//older IE
elm.style.filter = 'alpha(opacity=' + opacity*100 + ')';
}, speed);
}
To appear
appear(document.getElementsByTagName('DIV')[0], 0, 5, 40);
To disappear
appear(document.getElementsByTagName('DIV')[0], 100, -5, 40);
Easy with Jquery:
$("#myElementID").fadeIn("slow");
Dear Lord! Yes, I think most of us do know about jQuery, thanks.
Opacity isn't so complicated to set, today; it's now only IE that needs special help. See this answer for some simple plain-JavaScript time-independent fading code.
If you can use jQuery then animate() function will hep you.
$('your_selector').animate({opacity: 0.25}, 5000, function() {
// Animation complete.
});
See .animate()
or you can use fadeIn
$('your_selector').fadeIn('slow', function() {
// Animation complete
});
YUI Also has animate functionality and allows you to only include required modules which will reduce your load times.
YUI Animation
You fadein and fadeout of jQuery. For example, jQuery('#ID').fadeout() will make an element with 'ID' as its id to fade out (slowly disappear),
I recommend using jQuery. You will have to use the fadeIn() function. Detailed explanation here: http://api.jquery.com/fadeIn/. I rarely use pure Javascript after having started with the jQuery library.
You can use slideDown as well.
$("#YourID").slideDown("slow");