Order CSS Styles with Transitions and JavaScript - javascript

if i apply a style to an element and immdiatily afterwards add css transition styles, the transition is applied to the style preceeding. this might not always be the intention.
i found a solution by using settimeout (0), is there any cleaner/more correct approach known ?
http://jsfiddle.net/nicib83/XP9E7/
$("div").css("opacity", 1);
$("div").css("-webkit-transition", "all 0.35s");
/* Works
window.setTimeout(function () {
$("div").css("-webkit-transition", "all 0.35s");
}, 0);
*/
best regards
Edit:
i didn't mean how best to set css styling but how to sequentially set styles when the first style should be applied without the second being active at that time but only afterwards, i wan to add transition afterwards. settimeout fixes it, best solution ?

It's much better to pre-define a class that contains both of the properties you want to apply, and add that class programmatically to the element. Both of the properties will be applied together.
.myClass {
opacity: 1;
-webkit-transition: all 0.35s;
}
$("div").addClass("myClass");

You could take a page from the book of Twitter Bootstrap:
fade {
opacity: 0;
-webkit-transition: opacity 0.15s linear;
-moz-transition:opacity 0.15s linear;
-o-transition:opacity 0.15s linear;
transition:opacity 0.15s linear;
}
.fade.in{
opacity:1;
}
then programatically add the .in class when you want it to fade in:
$("div").addClass("in");
with your original div looking something like:
<div class="fade">Box</div>

I've been running up against this myself and also found the setTimeout solution. After some research the issue is how the browser handles scheduling. The JavaScript runs in its own thread separate from the threads dealing with the UI and the DOM (which is why issues like UI blocking happen).
In cases like this both JavaScript statements run before the document registers the first change and it ends up applying both classes at the same time. setTimeout(fn,0) effectively makes the function asynchronous and shunts the functions to run at the next available opportunity. This allows the UI thread to catch up before the next class is added.

Related

How can I animate an element programmaticaly using JavaScript?

I am looking at this code http://codepen.io/optyler/pen/FgDyr and if you hover to the triangle element, you will see the animation. However instead of hovering it, I want to do it programmaticaly using JavaScript. This is what I have done so far:
document.querySelector('.triangle').classList.add('animateSpeak');
and added a new css class
.animateSpeak {
animation: vibrate .5s infinite ease-out;
}
The animation is working though as you can see here http://imgur.com/a/V9JyO the left part is only animating. Am I doing something wrong here?
Since you're using a CSS 3 animation, you would probably need some sort of active class.
Just change the :hover selectors (line 54) to, say, .active instead. i.e.:
.triangle.active,
.triangle.active:before,
.triangle.active:after {
animation: vibrate .5s infinite ease-out;
}
You can start the animation programmatically by adding the .active class or stop it be removing the class.
To answer your second question, it looks like the :before and :after elements need the animation too.
In your CSS add
.animateSpeak,
.animateSpeak:before,
.animateSpeak:after {
animation: vibrate .5s infinite ease-out;
}
Just a quick thought, you can avoid the intersection of the three becoming darker than their constituents by changing the color from rgba to rgb or a solid color,
$font_color: rgb(231,236,241);

Parallax scroll with easing

I have an element that move relative to scroll. I use jQuery for this:
$('#object').css('transform','translateY('+($(window).scrollTop()*.4)+'px)');
CSS
#object {
width:200px;
top:100%;
left:50%;
position:absolute;
}
This works well, but moves my element directly without any easing (delay).
By setting a transition using css I get some of the effect that I'm looking for, but doesn't look good if I scroll at the same time:
transition: 400ms ease;
Is it possible to do this smooth, but in a more elegant way?
I figured it out by myself. The problem was the css "ease". Ease means that it will start slow and end slow, which will result in at the time scrolling is active it will always be on the slow start. However if you use css "ease-out" it will always start fast and slow down in the end. So use this:
transition: 400ms ease-out;
Or cubic-bezier if you want to customize the easing-curve yourself:
transition: 400ms cubic-bezier(0.235, 0.615, 0.185, 0.995);
When doing a parallax effect you will set a new translateY() on every scroll event that triggers. The event triggers really often and normally there should be no need for a transition. If you still experience bad rendering it is probably because the browser does not render on every event. You can force the browser to do so by using requestAnimationFrame.
var translate = function() {
$('#object').css('transform','translateY('+($(window).scrollTop()*.4)+'px)');
}
$(window).on('scroll', function() {
window.requestAnimationFrame(translate);
});

In angular ui-router is it possible to animate specific view?

To animate state changes in angular.js ui-router there are classes for enter and on leave. It means that when I make an animation it will always the same for every view.
This example is not mine, but notice that when I go back to a previous state the animation is the same, it goes left. http://embed.plnkr.co/M03tYgtfqNH09U4x5pHC/preview
Is there a way to add animation per state or on other events?
As the animations are applied through CSS it seems your only option is to determine what CSS should be applied based on the new state and previous state. It is easy to apply a class to the outgoing view on view change events, but much more difficult for the incoming view.
This should work but involves hacking angular-ui-router.js. I think it should be relatively straight forward to write this functionality into an extension script of some kind.
Create different CSS classes for the different animations that will be performed. E.g. slide-left and slide-right as shown below.
In the forms controller add a scope variable that indicates which animation should take place e.g. $scope.animationType.
In the forms controller add a listener to the view change event that will change the value of $scope.animationType depending on the current and future states. The value should match the CSS class with the animation you want to perform.
In angular-ui-router.js find the cleanupLastView function and add the parameter and the first first two lines:
.
function cleanupLastView(clonedElement) {
if(clonedElement) clonedElement.attr("class", scope.animationType);
if(currentEl) currentEl.attr("class", scope.animationType);
...
Then you have to change the call to cleanupLastView so the cloned element is included: cleanupLastView(clone)
Abbreviated CSS with #keyframes not included.
.form-view-slide-left.ng-enter {
animation:slideInRight 0.5s both ease;
}
.form-view-slide-left.ng-leave {
animation:slideOutLeft 0.5s both ease;
}
.form-view-slide-right.ng-enter {
animation:slideInLeft 0.5s both ease;
}
.form-view-slide-right.ng-leave {
animation:slideOutRight 0.5s both ease;
}

Activate css animation/translation with javascript

I am trying to get off javascript animations and use CSS animations instead. I am currently using jQuery's animation functionality.
I came across this website with a bunch of wonderful css animations. Such as:
.demo1 {
-webkit-transition:all .5s ease-out;
-moz-transition:all .5s ease-out;
-ms-transition:all .5s ease-out;
-o-transition:all .5s ease-out;
transition:all .5s ease-out;
}
.demo1:hover {
-webkit-transform:translate(0px,10px);
-moz-transform:translate(0px,-10px);
-ms-transform:translate(0px,-10px);
-o-transform:translate(0px,10px);
transform:translate(0px,-10px);
}
What I can't figure out is how to activate these animations programmatically. So for example, instead of on a hover, how can I translate the element by calling elem.translate()?
I may be misinterpreting what you're asking, but I think you may be under a mistaken impression of what "translate" is on an element. A DOM element has an attribute called "translate", as well as a css property "translate". However, the element attribute "translate" is just a boolean flag specifying whether the text in the element should be translated in the linguistic sense, it is not a callable function and has nothing to do with the css property.
That aside, there are still plenty of ways to translate an element programmatically. Some other people already gave a pretty good idea of how to do this with jQuery. If you don't wish to use jQuery, you can still add and remove classes manually (same goes for styles).
Here's an example I cooked up for class addition/removal. It's pretty straightforward, but here's the relevant code for class modification:
.translator {
-webkit-transform:translate(0px,100px);
-moz-transform:translate(0px,-100px);
-ms-transform:translate(0px,-100px);
-o-transform:translate(0px,100px);
transform:translate(0px,-100px);
}
...
function move_box() {
var the_box = document.getElementById("the-box");
if (the_box.classList.contains("translator")) {
the_box.classList.remove("translator");
} else {
the_box.classList.add("translator");
}
}
By applying the class, the animation will begin (and removing it will reverse it). This can happen as many times as you'd like.
One important note: for this example, I still have the style "transition:all .5s ease-out;" applied to the div before anything happens. This is just a universal default that governs how animation effects are applied to the element. There are a couple of different approaches to this, but for simplicities sake I'm going to just leave it like this.
Otherwise, you can add the styles directly, like so:
function move_box() {
var the_box = document.getElementById("the-box");
set_translate(the_box, 100);
}
function set_translate(e, pix) {
e.style["-webkit-transform"] = "translate(0px, "+ pix +"px)";
e.style["-moz-transform"] = "translate(0px, -" + pix +"px)";
e.style["-ms-transform"] = "translate(0px, -" + pix + "px)";
e.style["-o-transform"] = "translate(0px, " + pix + "px)";
e.style["transform"] = "translate(0px, -" + pix + "px)";
}
Nothing too complex here - it sets each relevant element directly by manipulating the styles on the element. As before, it relies on a separate class to specify the transition style.
Personally, I think the class addition/removal is far superior. Technically speaking, direct modification of styles is more flexible, but if that's what you're aiming for you probably should use a good library like jQuery transit (as mentioned in the comments). However, if you just want to be able to programmatically apply a few canned effects, modifying classes on the fly is a fine solution.
If you already have the CSS in place, you can trigger it in jquery by doing $('.demo1').trigger('hover'); to simulate a hover event, or change your css selector from .demo:hover to .class-name and just add that class using $('.demo').addClass('class-name');
You can use jQuery.css.fn to apply the css rules.
$('.demo1').click(function(){
$(this).css({
transform: 'translate(0px,-10px)'
});
});
Or add a class to the element:
$('.demo1').click(function(){
$(this).toggleClass('translate');
});
.translate {
-webkit-transform:translate(0px,10px);
-moz-transform:translate(0px,-10px);
-ms-transform:translate(0px,-10px);
-o-transform:translate(0px,10px);
transform:translate(0px,-10px);
}

jQuery Domino Like Slider Plugin

I am looking a jQuery-based content slider plugin. I don't mean one like this (of which there are far too many) nor the jQueryUI slider. What I am looking for can best be described in a picture.
Is there a jQuery plugin which allows me to slide (or transition) certain elements off the viewport and slide new elements in its place? Ideally, I would like to be able to ease several elements off and back onto the page in (sort of a) series, rather than one after another. The ability to ease these elements, rather than slide them with a linear speed, would be awesome.
This picture is the best visual I could come up with:
I know I could develop a plugin, as I have done several before, but I would like to avoid reinventing the wheel, if possible. Can anyone suggest a plugin?
Thank you for your time.
If you're supporting CSS3, you could try doing something like this, albiet it may be better to build an animation class.
.item:nth-child(1)
{
transition-timing-function : ease-in-out;
transition-property : left;
transition-duration : 0.1s;
transition-delay : 0.35s;
}
item:nth-child(2)
{
transition-timing-function : ease-in-out;
transition-property : left;
transition-duration : 0.1s;
transition-delay : 0.55s;
}
.item:nth-child(3)
{
transition-timing-function : ease-in-out;
transition-property : left;
transition-duration : 0.1s;
transition-delay : 0.65s;
}
.item:nth-child(4)
{
transition-timing-function : ease-in-out;
transition-property : left;
transition-duration : 0.1s;
transition-delay : 0.75s;
}​
If you want to use jQuery, I've had some success with http://api.jquery.com/queue/ which would allow you to craft a more complex chained animation. For an unknown number of children you could use the slice() method.
I've changed this snippet of self-executing code found on http://paulirish.com/2008/sequentially-chain-your-callbacks-in-jquery-two-ways/
(function hidenext(jq){
jq.eq(0).fadeOut("fast", function(){
(jq=jq.slice(1)).length && hidenext(jq);
});
})($('div'))
You don't have to use fadeOut and it doesn't need to be self-executing, but it's neat and tidy way to apply a 'transition' to an unknown number of elements.
Here's a fiddle using fadeOut http://jsfiddle.net/NpBfJ/ ... this is probably more work than you want...:-)
In regards to sliders, this is one of the best free ones out there http://caroufredsel.dev7studios.com/ it has many customizable features.

Categories

Resources