2013-03-03 21:22:44 8 Comments
I'm working on creating a cross-browser compatible rotation (ie9+) and I have the following code in a jsfiddle
$(document).ready(function () {
DoRotate(30);
AnimateRotate(30);
});
function DoRotate(d) {
$("#MyDiv1").css({
'-moz-transform':'rotate('+d+'deg)',
'-webkit-transform':'rotate('+d+'deg)',
'-o-transform':'rotate('+d+'deg)',
'-ms-transform':'rotate('+d+'deg)',
'transform': 'rotate('+d+'deg)'
});
}
function AnimateRotate(d) {
$("#MyDiv2").animate({
'-moz-transform':'rotate('+d+'deg)',
'-webkit-transform':'rotate('+d+'deg)',
'-o-transform':'rotate('+d+'deg)',
'-ms-transform':'rotate('+d+'deg)',
'transform':'rotate('+d+'deg)'
}, 1000);
}
The CSS and HTML are really simple and just for demo:
.SomeDiv{
width:50px;
height:50px;
margin:50px 50px;
background-color: red;}
<div id="MyDiv1" class="SomeDiv">test</div>
<div id="MyDiv2" class="SomeDiv">test</div>
The rotation works when using .css()
but not when using .animate()
; why is that and is there a way to fix it?
Thanks.
Related Questions
Sponsored Content
32 Answered Questions
27 Answered Questions
[SOLVED] Set cellpadding and cellspacing in CSS?
- 2008-12-04 08:45:47
- kokos
- 2246350 View
- 3217 Score
- 27 Answer
- Tags: html css html-table alignment
38 Answered Questions
[SOLVED] How to align checkboxes and their labels consistently cross-browsers
- 2008-11-20 18:02:01
- One Crayon
- 951305 View
- 1673 Score
- 38 Answer
- Tags: html css cross-browser alignment forms
18 Answered Questions
[SOLVED] How do CSS triangles work?
- 2011-08-16 03:54:51
- Stanislav Shabalin
- 151825 View
- 1793 Score
- 18 Answer
- Tags: css css3 geometry polygon css-shapes
28 Answered Questions
35 Answered Questions
[SOLVED] Change an HTML5 input's placeholder color with CSS
- 2010-04-09 19:54:53
- David Murdoch
- 1710514 View
- 3882 Score
- 35 Answer
- Tags: html css html5 placeholder html-input
19 Answered Questions
[SOLVED] Is it possible to apply CSS to half of a character?
- 2014-05-09 16:16:57
- Mathew MacLean
- 235941 View
- 2720 Score
- 19 Answer
- Tags: javascript html css css3
31 Answered Questions
[SOLVED] Is there a CSS parent selector?
- 2009-06-18 19:59:36
- jcuenod
- 1858440 View
- 2994 Score
- 31 Answer
- Tags: css css-selectors
31 Answered Questions
[SOLVED] Activity restart on rotation Android
- 2009-01-19 00:28:29
- Isaac Waller
- 374818 View
- 1344 Score
- 31 Answer
- Tags: android rotation android-activity
7 comments
@yckart 2013-03-03 21:29:14
CSS-Transforms are not possible to animate with jQuery, yet. You can do something like this:
You can read more about the step-callback here: http://api.jquery.com/animate/#step
http://jsfiddle.net/UB2XR/23/
And, btw: you don't need to prefix css3 transforms with jQuery 1.7+
Update
You can wrap this in a jQuery-plugin to make your life a bit easier:
http://jsbin.com/ofagog/2/edit
Update2
I optimized it a bit to make the order of
easing
,duration
andcomplete
insignificant.Update 2.1
Thanks to matteo who noted an issue with the
this
-context in the complete-callback
. If fixed it by binding the callback withjQuery.proxy
on each node.I've added the edition to the code before from Update 2.
Update 2.2
This is a possible modification if you want to do something like toggle the rotation back and forth. I simply added a start parameter to the function and replaced this line:
If anyone knows how to make this more generic for all use cases, whether or not they want to set a start degree, please make the appropriate edit.
The Usage...is quite simple!
Mainly you've two ways to reach the desired result. But at the first, let's take a look on the arguments:
jQuery.fn.animateRotate(angle, duration, easing, complete)
Except of "angle" are all of them optional and fallback to the default
jQuery.fn.animate
-properties:1st
This way is the short one, but looks a bit unclear the more arguments we pass in.
2nd
I prefer to use objects if there are more than three arguments, so this syntax is my favorit:
@John Dvorak 2013-03-03 21:30:47
(+ prefixes, ofc ;-) )
@frenchie 2013-03-03 21:32:11
Can you put this in a fiddle?
@yckart 2013-03-03 21:33:52
@frenchie I'm on iPhone, no chance since jsFiddle updated their editor ;) however, I'll prepare a bin for you...
@yckart 2013-03-03 21:39:24
@frenchie I forgot something! Updated my answer now... Here's an working example: jsbin.com/ofagog/2/edit
@frenchie 2013-03-04 11:54:52
Ok, very cool: that is THE plugin for cross-browser (IE9+) CSS3 rotation!! You can claim that: you built that. Nice work!
@Yeti 2013-10-17 11:30:42
I made this plugin work for IE7+ using transform matrix, also I improved the parameters. You really don't want to pass just and exactly those parameters.
@Codebeat 2014-02-24 06:56:09
Why not a css class solution?
@matteo 2014-06-29 20:16:52
Hey there's something wrong at least with the "update 2" version. When the complete function is executed, "this" inside it is supposed to be the dom element, but it is some other object. Any idea how to fix this?
@Trevin Avery 2014-10-30 15:08:54
What are
$.speed()
and$.style()
? I can't find any documentation on these two functions.@yckart 2014-10-30 17:04:29
@TrevinAvery
jQuery.speed
handles the arguments you pass intojQuery.fn.animate
, it makes the order insignificant. (So, you can pass induration, easing, complete
oreasing, duration, complete
or whatever).jQuery.style
is primarily the same as the already knownjQuery.fn.css
, however it works directly on the node instead of an jQuery-object. (jQuery.style
is not an alias forjQuery.fn.css
but is called in it.)@yckart 2014-10-30 18:15:51
@matteo Sorry for the late response and thanks for your test. I needed a little time fiddle the issue out, but I got it! fiddle.jshell.net/P5J4V/43 By the way, I mentioned your investigation in my anwer :)
@Trevin Avery 2014-10-30 20:02:38
@matteo The reason
this
does not refer to a DOM object is because the context is set to the objectanimate()
was called on, in this case{deg: 0}
is set to the context. You can fix this by changing the context of each callback function withapply()
/call()
or$.proxy()
(as @yckart has shown). Here is my solution to fix ALL callbacks and allow 3d rotation: jsfiddle.net/TrevinAvery/P5J4V/44@matteo 2014-10-30 22:34:32
Cool! Oh, I have to enter at least 15 characters. That's really cool!
@yckart 2014-12-15 01:09:42
@TrevinAvery Great work, I like the way you handle the promise-callbacks. However, I recognized a logic problem. Currently the styles are applied with CSS3-properties only, they are not supported by older browsers, so nothing will move around. Making another "type of string/object"-test and applying the styles, depending on this check, should fix it.
@Asbjørn Ulsberg 2015-01-21 13:17:20
If you want to animate the same element over and over, starting on
0
degrees every time will not lead to the expected behavior, so you need to initialize with the current rotation value. How to do that is explained here: stackoverflow.com/a/11840120/61818@user308553 2016-02-08 06:34:34
Can someone explain the
$({deg: 0}).animate({deg: angle}
part to me. I don't understand how it would do 0 to angle. It works even angle is negative. 1) How does it know it should do deg++ or deg-- 2) how does $({deg:0}) not return an error, I thought $() is a selector that would look for an element that fit the criteria, and the criteria has to be a certain syntax. This is like magic to me@raveren 2016-03-29 18:32:05
wow this is terrible, how about rotating back to zero? Oh, instant?
@yckart 2016-03-29 19:31:59
@Raveren This is an example and nothing to copy & paste, thoughtless... Just copy and code, modify and change. If you need help at some point, create a new question.
@Tires 2017-03-22 19:01:52
The binding with proxy inside of the loop is very expensive, so better use bind outside or call/apply.
@yckart 2017-03-23 06:02:02
@Tires Good finding. Passing the actual iterated element as argument to the
complete
callback, that can not be done outside of the loop. One could easily drop it, if not required. Note, this not a full solution, use it as startingpoint for another.@Seano 2017-06-15 10:14:03
For me, this method resets the start position to 0deg. So if I want to rotate an element which has a non-zero starting angle it doesn't work. Is anyone else having the same issue?
@yckart 2017-06-15 10:27:55
@Seano That's because of the
deg: 0
part in those functions. You could easily adopt my code and change that0
value to any other number.@Tires 2017-03-22 18:57:35
Another answer, because jQuery.transit is not compatible with jQuery.easing. This solution comes as an jQuery extension. Is more generic, rotation is a specific case:
The usage is as simple as:
@Alexey Alexeenka 2016-03-15 10:13:08
Without plugin cross browser with setInterval:
@AntiCampeR 2015-05-09 17:54:05
this is my solution:
then you can use it in the default animate fkt:
@Theo.T 2013-03-03 21:38:16
jQuery transit will probably make your life easier if you are dealing with CSS3 animations through jQuery.
EDIT March 2014 (because my advice has constantly been up and down voted since I posted it)
Let me explain why I was initially hinting towards the plugin above:
Updating the
DOM
on each step (i.e.$.animate
) is not ideal in terms of performance. It works, but will most probably be slower than pure CSS3 transitions or CSS3 animations.This is mainly because the browser gets a chance to think ahead if you indicate what the transition is going to look like from start to end.
To do so, you can for example create a CSS class for each state of the transition and only use jQuery to toggle the animation state.
This is generally quite neat as you can tweak you animations alongside the rest of your CSS instead of mixing it up with your business logic:
If any of the transform parameters is dynamic you can of course use the style attribute instead:
A lot more detailed information on CSS3 transitions on MDN.
HOWEVER There are a few other things to keep in mind and all this can get a bit tricky if you have complex animations, chaining etc. and jQuery Transit just does all the tricky bits under the hood:
@Yeti 2013-10-17 11:27:52
To do this cross browser including IE7+, you will need to expand the plugin with a transformation matrix. Since vendor prefix is done in jQuery from jquery-1.8+ I will leave that out for the
transform
property.Note: The parameters
options
andstartAngle
are optional, if you only need to setstartAngle
use{}
ornull
foroptions
.Example usage:
See also this jsfiddle for a demo.
Update: You can now also pass
extra: {}
in the options. This will make you able to execute other animations simultaneously. For example:This will rotate the element 90 degrees, and move it to the right with 100px and make it semi-transparent all at the same time during the animation.
@Liam - Reinstate Monica 2013-10-18 10:16:18
That fiddle doesn't work in Chrome, at all.
@Liam - Reinstate Monica 2013-10-18 10:17:51
Or IE9, does in Firefox, but only firefox.
@Yeti 2014-02-10 11:25:24
Okay so it works now in Chrome, Firefox and IE10. Can you test IE9, Liam? The problem was that the transform property was undefined for Chrome and IE, therefore the script thought that the transform property was unavailable. Hence, I changed the script to include all the prefixes:
ms
,o
,webkit
,moz
to ensure detection correctly. The fiddle is updated as well to v12.@drabname 2013-07-10 19:23:44
Thanks yckart! Great contribution. I fleshed out your plugin a bit more. Added startAngle for full control and cross-browser css.
@yckart 2013-07-23 13:43:15
jQuery adds the needed vendor prefix automatically, so no need for this!
@Pax Maximinus 2013-08-27 09:54:33
+1 for the cross platform. Great. @yckart : the auto prefix doesn't work for me in this case.
@yckart 2013-08-27 10:25:40
@PaxMaximinus What jQuery-version do you use? blog.jquery.com/2012/08/09/jquery-1-8-released
@Pax Maximinus 2013-08-28 08:33:07
@yckart : the 1.7.1 version.
@yckart 2013-08-28 09:01:35
@PaxMaximinus As you can see in the article from jquery-blog, the auto-prefixing is just since
jquery-1.8+
!@whyAto8 2013-09-11 06:57:23
Hey, does this solution works for IE8 as well? If not, what solution can be used for IE8, I just saw one of the options as jquery rotate plugin
@Amit Kumar Gupta 2018-01-28 03:57:11
This solution doesn't work when you set some data to the element after the animation. So that you can continue the animation after some time. So I have took your solution and combined with @yckart solution to make it cross browser compatible.