Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for a “swing”-like easing expressible both with jQuery and CSS3

I have to perform two animations on an object simultaneously.
For a number of reasons, I want to use jQuery for the vertical animation and CSS3 for the horizontal one.

On jQuery side, swing easing works great:

jquery swing

swing: function (a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}

I'm looking for a way to express this easing function in CSS3 transition.

If it is impossible, I'm looking for an easing function (e.g. a Bézier curve) that is most similar to swing
and can be used both in jQuery and CSS3. Please include link to any required plugins.

like image 693
Dan Abramov Avatar asked Feb 11 '12 23:02

Dan Abramov


3 Answers

TL;DR

I found that [.02, .01, .47, 1] Bézier curve provides a good enough approximation.

CSS3

-webkit-transition: all 1s cubic-bezier(.02, .01, .47, 1); 
-moz-transition: all 1s cubic-bezier(.02, .01, .47, 1); 
transition: all 1s cubic-bezier(.02, .01, .47, 1); 

jQuery

$(element).animate({ height: height }, 1000, $.easie(.02, .01, .47, 1));            

with jquery.easie (you might as well use bez).


The Quest

I used these graphs from Sparky672's answer to find out the exact function and its arguments:

enter image description here

It's the same as y = –x • (x – 2) where x is between 0 and 1.
So I created a graph with abettercalculator:

enter image description here

I cropped it and put it online.
Then used position: absolute to overlay cubic-bezier.com, suggested by Jim Jeffers.

enter image description here

The resulting approximation that I used was [.02, .01, .47, 1].

like image 189
Dan Abramov Avatar answered Oct 21 '22 20:10

Dan Abramov


As per the W3C, you're only allowed the following easing functions on the transition-timing-function property.

  • ease
  • linear
  • ease-in
  • ease-out
  • ease-in-out
  • cubic-bezier(<number>, <number>, <number>, <number>)

If you can translate "swing" into a cubic-bezier function, you can do it.

Also, looking at the graphical representations here, it seems like the ease-out built into transition-timing-function is very similar to the shape of swing.


EDIT based on comments:

If you'd rather just use jQuery for your easing, then you don't even need a plugin. You can just define your preferred function and use it...

jQuery easing functions without using a plugin

like image 40
Sparky Avatar answered Oct 21 '22 20:10

Sparky


You are limited to the presets or a simple cubic bezier curve. I got around this by creating an easing engine in javascript that generates CSS keyframe animations that are executed as transitions:

bounceDownTransition = new Sauce()
bounceDownTransition.recipe( (element) ->
   element.change("y").from(-200).using(Easie.bounceOut)
   element.change("scale").from(0).using(Easie.circOut)
)

bounceDownTransition.duration(2).delay(0.5).putOn("element_with_this_id")

You can checkout the project here: https://github.com/jimjeffers/Sauce

By using CSS keyframe animations we get the GPU enhanced performance of CSS transitions with the flexibility allotted to us by using our own custom easing equations in javascript.

My easing engine uses a port of Robbert Penner's equations. The one that matches jswing should be this:

@sineIn: (time,begin,change,duration) ->
    -change * Math.cos(time/duration * (Math.PI/2)) + change + begin

https://github.com/jimjeffers/Easie/blob/master/easie.coffee#L218

UPDATE:

Per comments -- if you want you can attempt to match the curve of a swing transition using a tool such as:

http://cubic-bezier.com/#.41,.66,.54,.91

like image 1
Jim Jeffers Avatar answered Oct 21 '22 21:10

Jim Jeffers