拐道交叉的css3动画,使用jquery.animate()的CSS旋转交叉浏览器

使用jquery.animate()的CSS旋转交叉浏览器

我正在创建一个跨浏览器兼容的旋转(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()时无效; 为什么这样,有没有办法解决它?

谢谢。

7个解决方案

207 votes

但是,使用jQuery无法使用CSS-Transforms进行动画制作。 你可以这样做:

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

而且,顺便说一句:你不需要使用jQuery 1.7+为css3转换添加前缀

更新

你可以将它包装在一个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

我优化了一下,使订单jQuery.fn.animate,callback和jQuery.proxy微不足道。

$.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在完整的callback中注意到jQuery.fn.animate上下文的问题。 如果通过在每个节点上将回调绑定到jQuery.proxy来修复它。

我在Update 2之前已将该版本添加到代码中。

更新2.2

如果您想要执行诸如来回切换旋转之类的操作,则可以进行此修改。 我只是在函数中添加了一个start参数并替换了这一行:

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

如果有人知道如何使所有用例更通用,无论他们是否想要设置起始度,请进行适当的编辑。

用法......很简单!

主要是你有两种方法可以达到预期的效果。 但首先,让我们来看看这些论点:

jQuery.fn.animate

除“angle”外,所有这些都是可选的,并且回退到默认值jQuery.fn.animate-properties:

duration: 400

easing: "swing"

complete: function () {}

1

这种方式很短,但看起来有点不清楚我们传递的参数越多。

$(node).animateRotate(90);

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

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

第2

如果有三个以上的参数,我更喜欢使用对象,所以这个语法是我的最爱:

$(node).animateRotate(90, {

duration: 1337,

easing: 'linear',

complete: function () {},

step: function () {}

});

yckart answered 2019-04-22T00:39:08Z

17 votes

谢谢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

});

});

};

drabname answered 2019-04-22T00:39:33Z

10 votes

如果你通过jQuery处理CSS3动画,jQuery传输可能会让你的生活更轻松。

编辑2014年3月(因为自从我发布以来,我的建议一直在上下投票)

让我解释为什么我最初暗示上面的插件:

在每个步骤(即$.animate)上更新DOM在性能方面并不理想。它可以工作,但很可能比纯CSS3过渡或CSS3动画慢。

这主要是因为如果您指出从开始到结束的过渡情况,浏览器就有机会提前考虑。

为此,您可以为转换的每个状态创建一个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'); });

如果任何变换参数是动态的,您当然可以使用style属性:

$('.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)'

});

});

关于MDN上CSS3过渡的更多详细信息。

但是还有一些其他的事情需要记住,如果你有复杂的动画,链接等等,所有这些都会变得有点棘手,jQuery Transit只是做了所有棘手的事情:

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

Theo.T answered 2019-04-22T00:41:07Z

3 votes

要通过浏览器(包括IE7 +)执行此操作,您需要使用转换矩阵扩展插件。 由于供应商前缀是在jQuery中从jquery-1.8 +完成的,我将把它留给extra: {}属性。

$.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);

}

});

};

注意:参数extra: {}和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度,并使用100px将其向右移动,并在动画期间同时使其半透明。

Yeti answered 2019-04-22T00:42:06Z

2 votes

这是我的解决方案:

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);

};

然后你可以在默认的动画fkt中使用它:

//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' });

AntiCampeR answered 2019-04-22T00:42:36Z

1 votes

另一个答案,因为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});

Tires answered 2019-04-22T00:43:10Z

0 votes

没有插件跨浏览器与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);

Alexey Alexeenka answered 2019-04-22T00:43:38Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值