59

Trying to rotate a div element...This might be DOM blasphemy, could it work possibly with a canvas element? I'm not sure - if anybody has any ideas of how this could work or why it doesn't, I'd love to know. Thanks.

user43889
  • 601
  • 1
  • 7
  • 3
  • 1
    There's a JQuery plugin, [jQuery Transform](https://github.com/louisremi/jquery.transform.js), that rotates elements (among other things). If you need to support non-latest IE this is a better approach than using `filter` workarounds because it uses the same rotation origin - whereas `filter` rotations rotate around a different point to regular CSS. [More info and live demos at this question](http://stackoverflow.com/questions/17490216/). – user56reinstatemonica8 Jul 05 '13 at 16:19

7 Answers7

24

To rotate a DIV Make use of WebkitTransform / -moz-transform: rotate(Xdeg).

This will not work in IE. The Raphael library does work with IE and it does rotation. I believe it uses canvases

If you want to animate the rotation, you can use a recursive setTimeout()

You could probably even do part of a spin with jQuery's .animate()

Make sure that you consider the width of your element. If rotate an that has a larger width than its visible content, you'll get funny results. However you can narrow the widths of elements, and then rotate them.

Here is a simply jQuery snippet that rotates the elements in a jQuery object. Rotatation can be started and stopped:

$(function() {
    var $elie = $(selectorForElementsToRotate);
    rotate(0);
    function rotate(degree) {

          // For webkit browsers: e.g. Chrome
        $elie.css({ WebkitTransform: 'rotate(' + degree + 'deg)'});
          // For Mozilla browser: e.g. Firefox
        $elie.css({ '-moz-transform': 'rotate(' + degree + 'deg)'});

          // Animate rotation with a recursive call
        setTimeout(function() { rotate(++degree); },5);
    }
});

jsFiddle example

Note:
Taking the degree and increasing it, will rotate the image clockwise. Decreasing the degree of rotation will rotate the image counter clockwise.

Nope
  • 22,147
  • 7
  • 47
  • 72
Peter Ajtai
  • 56,972
  • 13
  • 121
  • 140
  • 1
    Can we also mention the rotate direction (clockwise/anti-clockwise) ? – Adil Malik Jun 12 '12 at 13:26
  • Raphael.js uses SVG and (in old IE) VML, not HTML5 canvas. – user56reinstatemonica8 Jul 05 '13 at 16:22
  • @PeterAjtai: I know this is an old post but it is still showing up in google search at the top, so I found it relevant to mention here. when using script to set the degree on the rotation and using incremental degree values i.e: `rotate(++degree)` the issue is that you are never endingly increasing the degree value. i.e: `rotate(70531deg)` etc.. Eventually I'm assuming a max value is reached. The script should build in a mechanism whereby if the degree reaches 360 is starts back at 0. therefore it will never go higher than 360 and only go 0-360. – Nope Oct 09 '13 at 14:51
  • @PeterAjtai: I added a very simple example to your existing fiddle on how to re-set the degree value so it never ends up to high. See [**this forked fiddle**](http://jsfiddle.net/fdFm2/) If you watch the DOM now during the rotation you can see it re-setting every 360 degree to 0. – Nope Oct 09 '13 at 14:56
  • @Nope: Well, the max integer value in javascript is about 9 quadrillion, and the function runs every 5 milliseconds. So you will reach the max value in 1.4 million years. I think its fine. – rocketsarefast Apr 11 '18 at 16:33
  • @rocketsarefast That's a very "We cross that bridge when we get there" attitude, which in most cases is the main reason for huge issues down the road (maybe not in this specific case but in general it is). While I don't pre-optimize before it's needed in most cases I don't promote wasting resources ever if a small change can prevent that waste. Each to their own :) – Nope Apr 12 '18 at 08:06
7

Cross-browser rotate for any element. Works in IE7 and IE8. In IE7 it looks like not working in JSFiddle but in my project worked also in IE7

http://jsfiddle.net/RgX86/24/

var elementToRotate = $('#rotateMe');
var degreeOfRotation = 33;

var deg = degreeOfRotation;
var deg2radians = Math.PI * 2 / 360;
var rad = deg * deg2radians ;
var costheta = Math.cos(rad);
var sintheta = Math.sin(rad);

var m11 = costheta;
var m12 = -sintheta;
var m21 = sintheta;
var m22 = costheta;
var matrixValues = 'M11=' + m11 + ', M12='+ m12 +', M21='+ m21 +', M22='+ m22;

elementToRotate.css('-webkit-transform','rotate('+deg+'deg)')
    .css('-moz-transform','rotate('+deg+'deg)')
    .css('-ms-transform','rotate('+deg+'deg)')
    .css('transform','rotate('+deg+'deg)')
    .css('filter', 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\','+matrixValues+')')
    .css('-ms-filter', 'progid:DXImageTransform.Microsoft.Matrix(SizingMethod=\'auto expand\','+matrixValues+')');

Edit 13/09/13 15:00 Wrapped in a nice and easy, chainable, jquery plugin.

Example of use

$.fn.rotateElement = function(angle) {
    var elementToRotate = this,
        deg = angle,
        deg2radians = Math.PI * 2 / 360,
        rad = deg * deg2radians ,
        costheta = Math.cos(rad),
        sintheta = Math.sin(rad),

        m11 = costheta,
        m12 = -sintheta,
        m21 = sintheta,
        m22 = costheta,
        matrixValues = 'M11=' + m11 + ', M12='+ m12 +', M21='+ m21 +', M22='+ m22;

    elementToRotate.css('-webkit-transform','rotate('+deg+'deg)')
        .css('-moz-transform','rotate('+deg+'deg)')
        .css('-ms-transform','rotate('+deg+'deg)')
        .css('transform','rotate('+deg+'deg)')
        .css('filter', 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\','+matrixValues+')')
        .css('-ms-filter', 'progid:DXImageTransform.Microsoft.Matrix(SizingMethod=\'auto expand\','+matrixValues+')');
    return elementToRotate;
}

$element.rotateElement(15);

JSFiddle: http://jsfiddle.net/RgX86/175/

Pawel
  • 16,093
  • 5
  • 70
  • 73
  • This isn't working for me in IE 7 or 8 when I emulate them in IE 10. – Curtis May 20 '13 at 21:49
  • 2
    @curtis that's [because of IE10's default security settings](http://stackoverflow.com/questions/16340945/why-isnt-this-element-rotation-working) – user56reinstatemonica8 Jul 05 '13 at 16:16
  • @curtis IE10 doesn't support filters anymore. Emulation mode doesn't support filters either. You'll have to test it in real IE7 and IE8 to see that it works. – Pawel Oct 17 '13 at 10:08
  • This kinda works but using dodgy IE matrix filter has a side-effect: element after rotation will have a origin that is different than before it's been rotated. See http://extremelysatisfactorytotalitarianism.com/blog/?p=1002. Having said that, I'm afraid it's a non-trivial task to achieve consistent rotation across browsers without using some 3rd jQuery plugin such as [link](https://github.com/louisremi/jquery.transform.js/), which I've verified myself to be working very well in IE8. – JZ_42 Feb 06 '18 at 01:08
7

yeah you're not going to have much luck i think. Typically across the 3 drawing methods the major browsers use (Canvas, SVG, VML), text support is poor, I believe. If you want to rotate an image, then it's all good, but if you've got mixed content with formatting and styles, probably not.

Check out RaphaelJS for a cross-browser drawing API.

nickf
  • 537,072
  • 198
  • 649
  • 721
1

Here are two jQuery patches to help out (maybe already included in jQuery by the time you are reading this):

Neeme Praks
  • 8,956
  • 5
  • 47
  • 47
David Herse
  • 471
  • 5
  • 8
1

EDIT: Updated for jQuery 1.8

jQuery 1.8 will add browser specific transformations. jsFiddle Demo

var rotation = 0;

jQuery.fn.rotate = function(degrees) {
    $(this).css({'transform' : 'rotate('+ degrees +'deg)'});
    return $(this);
};

$('.rotate').click(function() {
    rotation += 5;
    $(this).rotate(rotation);
});

EDIT: Added code to make it a jQuery function.

For those of you who don't want to read any further, here you go. For more details and examples, read on. jsFiddle Demo.

var rotation = 0;

jQuery.fn.rotate = function(degrees) {
    $(this).css({'-webkit-transform' : 'rotate('+ degrees +'deg)',
                 '-moz-transform' : 'rotate('+ degrees +'deg)',
                 '-ms-transform' : 'rotate('+ degrees +'deg)',
                 'transform' : 'rotate('+ degrees +'deg)'});
    return $(this);
};

$('.rotate').click(function() {
    rotation += 5;
    $(this).rotate(rotation);
});

EDIT: One of the comments on this post mentioned jQuery Multirotation. This plugin for jQuery essentially performs the above function with support for IE8. It may be worth using if you want maximum compatibility or more options. But for minimal overhead, I suggest the above function. It will work IE9+, Chrome, Firefox, Opera, and many others.


Bobby... This is for the people who actually want to do it in the javascript. This may be required for rotating on a javascript callback.

Here is a jsFiddle.

If you would like to rotate at custom intervals, you can use jQuery to manually set the css instead of adding a class. Like this! I have included both jQuery options at the bottom of the answer.

HTML

<div class="rotate">
    <h1>Rotatey text</h1>
</div>

CSS

/* Totally for style */
.rotate {
    background: #F02311;
    color: #FFF;
    width: 200px;
    height: 200px;
    text-align: center;
    font: normal 1em Arial;
    position: relative;
    top: 50px;
    left: 50px;
}

/* The real code */
.rotated {
    -webkit-transform: rotate(45deg);  /* Chrome, Safari 3.1+ */
    -moz-transform: rotate(45deg);  /* Firefox 3.5-15 */
    -ms-transform: rotate(45deg);  /* IE 9 */
    -o-transform: rotate(45deg);  /* Opera 10.50-12.00 */
    transform: rotate(45deg);  /* Firefox 16+, IE 10+, Opera 12.10+ */
}

jQuery

Make sure these are wrapped in $(document).ready

$('.rotate').click(function() {
    $(this).toggleClass('rotated');
});

Custom intervals

var rotation = 0;
$('.rotate').click(function() {
    rotation += 5;
    $(this).css({'-webkit-transform' : 'rotate('+ rotation +'deg)',
                 '-moz-transform' : 'rotate('+ rotation +'deg)',
                 '-ms-transform' : 'rotate('+ rotation +'deg)',
                 'transform' : 'rotate('+ rotation +'deg)'});
});
Dan Grahn
  • 9,044
  • 4
  • 37
  • 74
0

I doubt you can rotate an element using DOM/CSS. Your best bet would be to render to a canvas and rotate that (not sure on the specifics).

strager
  • 88,763
  • 26
  • 134
  • 176
-1

I put together an animated rotate code program.. you can get your code here ... (if not to late)

http://99mission.why3s.tw/rotatetest.html

Yuan Shen
  • 79
  • 1
  • 3