9

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.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • 1
    Just found I can go the opposite way and [use bezier format (also used by CSS3) for jQuery easing](https://github.com/rdallasgray/bez) to have consistent easings. – Dan Abramov Feb 11 '12 at 23:50
  • 1
    Even better—[jquery.easie](https://github.com/jaukia/easie) provides exact CSS3 easings for jQuery. – Dan Abramov Feb 11 '12 at 23:54
  • 1
    Personally I'd recommend [this plugin](http://gsgd.co.uk/sandbox/jquery/easing/) because it doesn't prefix all it's easing functions with `easie`, but that's just personal preference. You might want to try `ease-in-out` in your CSS3 for a swing-ish animation. – Bojangles Feb 11 '12 at 23:57
  • You asked how to do `swing` with CSS3. How does using a jQuery plugin to _"simulate"_ CSS easing help you, when you could just use the original jQuery `swing` in the first place? – Sparky Feb 12 '12 at 00:01
  • @Sparky: I'm looking for a way to keep my horizontal (CSS3) and vertical (jQuery) animations consistent. But this question is specifically about any approximation to `swing` in CSS3 so that's the reason I wrote about these plugins in comments. – Dan Abramov Feb 12 '12 at 00:04
  • 1
    Then the closest way to do a `swing` in CSS3 would be the `ease-out` built into the CSS3 `transition-timing-function` property. – Sparky Feb 12 '12 at 00:06
  • @Sparky @Jam Hey folks, sorry about the confusion. I will accept the answer that contains a function most similar to `swing` that can be used *both* with jQuery and CSS3, with links to any relevant plugins. – Dan Abramov Feb 12 '12 at 00:32
  • you'd be searching for ´ease-in-out´ – japrescott Feb 12 '12 at 00:01

3 Answers3

32

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].

jpaugh
  • 6,634
  • 4
  • 38
  • 90
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
3

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

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • I have just tried `ease-out` but unfortunately it doesn't work well for me (the difference is noticeable). I included a clarification: it's much easier right now to use jQuery for one animation and CSS3 for the other one. Getting the easing right is the only problem. Otherwise, thanks for the info! – Dan Abramov Feb 12 '12 at 00:18
  • 1
    @DanAbramov, if `ease-out` is not close enough, then trying to duplicate it with a `cubic-bezier` is the only other option for a CSS3-only solution. – Sparky Feb 12 '12 at 00:31
  • Thanks, I'll try and let you know the results. – Dan Abramov Feb 12 '12 at 00:40
1

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

Jim Jeffers
  • 17,572
  • 4
  • 41
  • 49