CSS rotation кросс-браузер с jquery.animate ()

Я работаю над созданием кросс-браузера совместимого вращения (ie9 +), и у меня есть следующий код в 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); } 

CSS и HTML действительно простые и просто для демонстрации:

 .SomeDiv{ width:50px; height:50px; margin:50px 50px; background-color: red;} 
test
test

Вращение работает при использовании .css() но не при использовании .animate() ; почему это так и есть способ исправить это?

Благодарю.

CSS-Transforms невозможно анимировать с помощью jQuery. Вы можете сделать что-то вроде этого:

 function AnimateRotate(angle) { // caching the object for performance reasons var $elem = $('#MyDiv2'); // we use a pseudo object for the animation // (starts from `0` to `angle`), you can name it as you want $({deg: 0}).animate({deg: angle}, { duration: 2000, step: function(now) { // in the step-callback (that is fired each step of the animation), // you can use the `now` paramter which contains the current // animation-position (`0` up to `angle`) $elem.css({ transform: 'rotate(' + now + 'deg)' }); } }); } 

Подробнее о шаге-обратном вызове можно узнать здесь: http://api.jquery.com/animate/#step

http://jsfiddle.net/UB2XR/23/

И, кстати, вам не нужно префиксные преобразования css3 с помощью jQuery 1.7+

Обновить

Вы можете обернуть это в jQuery-плагин, чтобы сделать вашу жизнь немного легче:

 $.fn.animateRotate = function(angle, duration, easing, complete) { return this.each(function() { var $elem = $(this); $({deg: 0}).animate({deg: angle}, { duration: duration, easing: easing, step: function(now) { $elem.css({ transform: 'rotate(' + now + 'deg)' }); }, complete: complete || $.noop }); }); }; $('#MyDiv2').animateRotate(90); 

http://jsbin.com/ofagog/2/edit

Update2

Я немного его оптимизировал, чтобы сделать порядок easing , duration и незначительности.

 $.fn.animateRotate = function(angle, duration, easing, complete) { var args = $.speed(duration, easing, complete); var step = args.step; return this.each(function(i, e) { args.complete = $.proxy(args.complete, e); args.step = function(now) { $.style(e, 'transform', 'rotate(' + now + 'deg)'); if (step) return step.apply(e, arguments); }; $({deg: 0}).animate({deg: angle}, args); }); }; 

Обновление 2.1

Спасибо matteo, который отметил проблему с this -context в full- callback . Если исправлено это, связывая обратный вызов с jQuery.proxy на каждом узле.

Я добавил версию в код до версии 2 .

Обновление 2.2

Это возможная модификация, если вы хотите сделать что-то вроде переключения назад и вперед. Я просто добавил параметр запуска к функции и заменил эту строку:

 $({deg: start}).animate({deg: angle}, args); 

Если кто-то знает, как сделать это более общим для всех случаев использования, независимо от того, хотите ли они установить начальную степень, сделайте соответствующее редактирование.


Использование … довольно просто!

В основном у вас есть два способа достичь желаемого результата. Но, во-первых, давайте рассмотрим аргументы:

jQuery.fn.animateRotate(angle, duration, easing, complete)

За исключением «угла», все они являются необязательными и возвращаются к умолчанию jQuery.fn.animate :

 duration: 400 easing: "swing" complete: function () {} 

первый

Этот путь является коротким, но выглядит несколько неясным, чем больше аргументов мы передаем.

 $(node).animateRotate(90); $(node).animateRotate(90, function () {}); $(node).animateRotate(90, 1337, 'linear', function () {}); 

второй

Я предпочитаю использовать объекты, если есть более трех аргументов, поэтому этот синтаксис – это мой favorit:

 $(node).animateRotate(90, { duration: 1337, easing: 'linear', complete: function () {}, step: function () {} }); 

Благодарю yckart! Большой вклад. Я немного добавил ваш плагин. Добавлен startAngle для полного управления и кросс-браузера css.

 $.fn.animateRotate = function(startAngle, endAngle, duration, easing, complete){ return this.each(function(){ var elem = $(this); $({deg: startAngle}).animate({deg: endAngle}, { duration: duration, easing: easing, step: function(now){ elem.css({ '-moz-transform':'rotate('+now+'deg)', '-webkit-transform':'rotate('+now+'deg)', '-o-transform':'rotate('+now+'deg)', '-ms-transform':'rotate('+now+'deg)', 'transform':'rotate('+now+'deg)' }); }, complete: complete || $.noop }); }); }; 

jQuery-транзит , вероятно, упростит вашу жизнь, если вы будете заниматься анимацией CSS3 через jQuery.

EDIT March 2014 (потому что мой совет постоянно поднимался и опускался, поскольку я опубликовал его)

Позвольте мне объяснить, почему я изначально намекал на плагин выше:

Обновление DOM на каждом шаге (т.е. $.animate ) не является идеальным с точки зрения производительности. Он работает, но, скорее всего, будет медленнее, чем чистые переходы CSS3 или анимации CSS3 .

Это связано главным образом с тем, что браузер получает возможность задуматься, если вы укажете, как будет выглядеть переход от начала и до конца.

Для этого вы можете, например, создать class CSS для каждого состояния перехода и использовать jQuery для переключения состояния анимации.

Это, как правило, довольно аккуратно, так как вы можете настроить анимацию наряду с остальной частью вашего CSS вместо того, чтобы смешивать ее с вашей бизнес-логикой:

 // initial state .eye { -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); // etc. // transition settings -webkit-transition: -webkit-transform 1s linear 0.2s; -moz-transition: -moz-transform 1s linear 0.2s; transition: transform 1s linear 0.2s; // etc. } // open state .eye.open { transform: rotate(90deg); } // Javascript $('.eye').on('click', function () { $(this).addClass('open'); }); 

Если какой-либо из параметров преобразования является динамическим, вы можете, конечно, использовать атрибут стиля:

 $('.eye').on('click', function () { $(this).css({ -webkit-transition: '-webkit-transform 1s ease-in', -moz-transition: '-moz-transform 1s ease-in', // ... // note that jQuery will vendor prefix the transform property automatically transform: 'rotate(' + (Math.random()*45+45).toFixed(3) + 'deg)' }); }); 

Более подробная информация о переходах CSS3 на MDN .

ОДНАКО Есть еще несколько вещей, о которых нужно помнить, и все это может немного запутаться, если у вас сложная анимация, цепочка и т. Д., А jQuery Transit просто выполняет все сложные биты под капотом:

 $('.eye').transit({ rotate: '90deg'}); // easy huh ? 

Чтобы сделать этот кросс-браузер, включая IE7 +, вам нужно будет расширить плагин с помощью матрицы преобразования. Поскольку префикс поставщика выполняется в jQuery из jquery-1.8 +, я оставлю это для свойства transform .

 $.fn.animateRotate = function(endAngle, options, startAngle) { return this.each(function() { var elem = $(this), rad, costheta, sintheta, matrixValues, noTransform = !('transform' in this.style || 'webkitTransform' in this.style || 'msTransform' in this.style || 'mozTransform' in this.style || 'oTransform' in this.style), anims = {}, animsEnd = {}; if(typeof options !== 'object') { options = {}; } else if(typeof options.extra === 'object') { anims = options.extra; animsEnd = options.extra; } anims.deg = startAngle; animsEnd.deg = endAngle; options.step = function(now, fx) { if(fx.prop === 'deg') { if(noTransform) { rad = now * (Math.PI * 2 / 360); costheta = Math.cos(rad); sintheta = Math.sin(rad); matrixValues = 'M11=' + costheta + ', M12=-'+ sintheta +', M21='+ sintheta +', M22='+ costheta; $('body').append('Test ' + matrixValues + '
'); elem.css({ 'filter': 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\','+matrixValues+')', '-ms-filter': 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\','+matrixValues+')' }); } else { elem.css({ //webkitTransform: 'rotate('+now+'deg)', //mozTransform: 'rotate('+now+'deg)', //msTransform: 'rotate('+now+'deg)', //oTransform: 'rotate('+now+'deg)', transform: 'rotate('+now+'deg)' }); } } }; if(startAngle) { $(anims).animate(animsEnd, options); } else { elem.animate(animsEnd, options); } }); };

Примечание. Параметры options и startAngle являются необязательными, если вам нужно только установить startAngle использования {} или null для options .

Пример использования:

 var obj = $(document.createElement('div')); obj.on("click", function(){ obj.stop().animateRotate(180, { duration: 250, complete: function() { obj.animateRotate(0, { duration: 250 }); } }); }); obj.text('Click me!'); obj.css({cursor: 'pointer', position: 'absolute'}); $('body').append(obj); 

См. Также этот jsfiddle для демонстрации.

Обновление : теперь вы можете передать extra: {} в параметрах. Это позволит вам одновременно выполнять другие анимации. Например:

 obj.animateRotate(90, {extra: {marginLeft: '100px', opacity: 0.5}}); 

Это повернет элемент на 90 gradleусов и сдвинет его вправо с помощью 100 пикселей и сделает его полупрозрачным одновременно во время анимации.

это мое решение:

 var matrixRegex = /(?:matrix\(|\s*,\s*)([-+]?[0-9]*\.?[0-9]+(?:[e][-+]?[0-9]+)?)/gi; var getMatches = function(string, regex) { regex || (regex = matrixRegex); var matches = []; var match; while (match = regex.exec(string)) { matches.push(match[1]); } return matches; }; $.cssHooks['rotation'] = { get: function(elem) { var $elem = $(elem); var matrix = getMatches($elem.css('transform')); if (matrix.length != 6) { return 0; } return Math.atan2(parseFloat(matrix[1]), parseFloat(matrix[0])) * (180/Math.PI); }, set: function(elem, val){ var $elem = $(elem); var deg = parseFloat(val); if (!isNaN(deg)) { $elem.css({ transform: 'rotate(' + deg + 'deg)' }); } } }; $.cssNumber.rotation = true; $.fx.step.rotation = function(fx) { $.cssHooks.rotation.set(fx.elem, fx.now + fx.unit); }; 

то вы можете использовать его в диалоговом окне fimate:

 //rotate to 90 deg cw $('selector').animate({ rotation: 90 }); //rotate to -90 deg ccw $('selector').animate({ rotation: -90 }); //rotate 90 deg cw from current rotation $('selector').animate({ rotation: '+=90' }); //rotate 90 deg ccw from current rotation $('selector').animate({ rotation: '-=90' }); 

Другой ответ, поскольку jQuery.transit несовместим с jQuery.easing. Это решение поставляется как расширение jQuery. Более общий, поворот – это конкретный случай:

 $.fn.extend({ animateStep: function(options) { return this.each(function() { var elementOptions = $.extend({}, options, {step: options.step.bind($(this))}); $({x: options.from}).animate({x: options.to}, elementOptions); }); }, rotate: function(value) { return this.css("transform", "rotate(" + value + "deg)"); } }); 

Использование так же просто, как:

 $(element).animateStep({from: 0, to: 90, step: $.fn.rotate}); 

Без перекрестного браузера с параметром setInterval:

  function rotatePic() { jQuery({deg: 0}).animate( {deg: 360}, {duration: 3000, easing : 'linear', step: function(now, fx){ jQuery("#id").css({ '-moz-transform':'rotate('+now+'deg)', '-webkit-transform':'rotate('+now+'deg)', '-o-transform':'rotate('+now+'deg)', '-ms-transform':'rotate('+now+'deg)', 'transform':'rotate('+now+'deg)' }); } }); } var sec = 3; rotatePic(); var timerInterval = setInterval(function() { rotatePic(); sec+=3; if (sec > 30) { clearInterval(timerInterval); } }, 3000); 
  • Вращение экземпляров BufferedImage
  • Почему изображение, захваченное с использованием намерения камеры, вращается на некоторых устройствах на Android?
  • Повернуть прямоугольник Java Graphics2D?
  • Вращающееся изображение. Анимационный список или анимированный поворот? (Android)
  • Повернуть BufferedImage внутри JPanel
  • Поворот изображения в java на указанный угол
  • Есть ли способ, которым я могу вращать эти 90 gradleусов?
  • Поверните JLabel или ImageIcon на Java Swing
  • Вращение Java 2d в направлении мыши
  • threejs, как вращаться вокруг собственного центра объекта, а не центра мира
  • Java - Вращающийся массив
  • Interesting Posts
    Давайте будем гением компьютера.