Skip to content

Commit 893d953

Browse files
committed
Firefox 16 transform style returns a matrix rather than a string of transform functions. This broke the features of this jQuery patch in Firefox 16. It should be possible to parse the matrix for both scale and rotate (especially when scale is the same for both the X and Y axis), however the matrix does have disadvantages such as using its own units and also 45deg being indistinguishable from 45+360deg. To get around these issues, this patch tracks internally the scale, rotation, and rotation units for any elements that are .scale()'ed, .rotate()'ed, or animated. The major consequences of this are that 1. the scaled/rotated element will blow away any other transform rules applied to the same element (such as skew or scale), and 2. the scaled/rotated element is unaware of any preset scale or rotation initally set by page CSS rules. You will have to explicitly set the starting scale/rotation value.
1 parent 3e4bdaf commit 893d953

File tree

1 file changed

+68
-75
lines changed

1 file changed

+68
-75
lines changed

jquery-animate-css-rotate-scale.js

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,92 @@
1+
/*!
2+
/**
3+
* Monkey patch jQuery 1.3.1+ to add support for setting or animating CSS
4+
* scale and rotation independently.
5+
* https://github.com/zachstronaut/jquery-animate-css-rotate-scale
6+
* Released under dual MIT/GPL license just like jQuery.
7+
* 2009-2012 Zachary Johnson www.zachstronaut.com
8+
*/
19
(function ($) {
2-
// Monkey patch jQuery 1.3.1+ to add support for setting or animating CSS
3-
// scale and rotation independently.
4-
// 2009-2010 Zachary Johnson www.zachstronaut.com
510
// Updated 2010.11.06
6-
var rotateUnits = 'deg';
11+
// Updated 2012.10.13 - Firefox 16 transform style returns a matrix rather than a string of transform functions. This broke the features of this jQuery patch in Firefox 16. It should be possible to parse the matrix for both scale and rotate (especially when scale is the same for both the X and Y axis), however the matrix does have disadvantages such as using its own units and also 45deg being indistinguishable from 45+360deg. To get around these issues, this patch tracks internally the scale, rotation, and rotation units for any elements that are .scale()'ed, .rotate()'ed, or animated. The major consequences of this are that 1. the scaled/rotated element will blow away any other transform rules applied to the same element (such as skew or scale), and 2. the scaled/rotated element is unaware of any preset scale or rotation initally set by page CSS rules. You will have to explicitly set the starting scale/rotation value.
712

8-
$.fn.rotate = function (val)
9-
{
10-
var style = $(this).css('transform') || 'none';
11-
12-
if (typeof val == 'undefined')
13-
{
14-
if (style)
15-
{
16-
var m = style.match(/rotate\(([^)]+)\)/);
17-
if (m && m[1])
18-
{
19-
return m[1];
20-
}
21-
}
13+
function initData($el) {
14+
var _ARS_data = $el.data('_ARS_data');
15+
if (!_ARS_data) {
16+
_ARS_data = {
17+
rotateUnits: 'deg',
18+
scale: 1,
19+
rotate: 0
20+
};
2221

23-
return 0;
22+
$el.data('_ARS_data', _ARS_data);
23+
}
24+
25+
return _ARS_data;
26+
}
27+
28+
function setTransform($el, data) {
29+
$el.css('transform', 'rotate(' + data.rotate + data.rotateUnits + ') scale(' + data.scale + ',' + data.scale + ')');
30+
}
31+
32+
$.fn.rotate = function (val) {
33+
var $self = $(this), m, data = initData($self);
34+
35+
if (typeof val == 'undefined') {
36+
return data.rotate + data.rotateUnits;
2437
}
2538

26-
var m = val.toString().match(/^(-?\d+(\.\d+)?)(.+)?$/);
27-
if (m)
28-
{
29-
if (m[3])
30-
{
31-
rotateUnits = m[3];
39+
m = val.toString().match(/^(-?\d+(\.\d+)?)(.+)?$/);
40+
if (m) {
41+
if (m[3]) {
42+
data.rotateUnits = m[3];
3243
}
3344

34-
$(this).css(
35-
'transform',
36-
style.replace(/none|rotate\([^)]*\)/, '') + 'rotate(' + m[1] + rotateUnits + ')'
37-
);
45+
data.rotate = m[1];
46+
47+
setTransform($self, data);
3848
}
3949

4050
return this;
41-
}
51+
};
4252

4353
// Note that scale is unitless.
44-
$.fn.scale = function (val, duration, options)
45-
{
46-
var style = $(this).css('transform');
54+
$.fn.scale = function (val) {
55+
var $self = $(this), data = initData($self);
4756

48-
if (typeof val == 'undefined')
49-
{
50-
if (style)
51-
{
52-
var m = style.match(/scale\(([^)]+)\)/);
53-
if (m && m[1])
54-
{
55-
return m[1];
56-
}
57-
}
58-
59-
return 1;
57+
if (typeof val == 'undefined') {
58+
return data.scale;
6059
}
6160

62-
$(this).css(
63-
'transform',
64-
style.replace(/none|scale\([^)]*\)/, '') + 'scale(' + val + ')'
65-
);
61+
data.scale = val;
62+
63+
setTransform($self, data);
6664

6765
return this;
68-
}
66+
};
6967

7068
// fx.cur() must be monkey patched because otherwise it would always
7169
// return 0 for current rotate and scale values
7270
var curProxied = $.fx.prototype.cur;
73-
$.fx.prototype.cur = function ()
74-
{
75-
if (this.prop == 'rotate')
76-
{
71+
$.fx.prototype.cur = function () {
72+
if (this.prop == 'rotate') {
7773
return parseFloat($(this.elem).rotate());
78-
}
79-
else if (this.prop == 'scale')
80-
{
74+
75+
} else if (this.prop == 'scale') {
8176
return parseFloat($(this.elem).scale());
8277
}
8378

8479
return curProxied.apply(this, arguments);
85-
}
80+
};
8681

87-
$.fx.step.rotate = function (fx)
88-
{
89-
$(fx.elem).rotate(fx.now + rotateUnits);
90-
}
82+
$.fx.step.rotate = function (fx) {
83+
var data = initData($(fx.elem));
84+
$(fx.elem).rotate(fx.now + data.rotateUnits);
85+
};
9186

92-
$.fx.step.scale = function (fx)
93-
{
87+
$.fx.step.scale = function (fx) {
9488
$(fx.elem).scale(fx.now);
95-
}
89+
};
9690

9791
/*
9892
@@ -117,19 +111,18 @@
117111
*/
118112

119113
var animateProxied = $.fn.animate;
120-
$.fn.animate = function (prop)
121-
{
122-
if (typeof prop['rotate'] != 'undefined')
123-
{
124-
var m = prop['rotate'].toString().match(/^(([+-]=)?(-?\d+(\.\d+)?))(.+)?$/);
125-
if (m && m[5])
126-
{
127-
rotateUnits = m[5];
114+
$.fn.animate = function (prop) {
115+
if (typeof prop['rotate'] != 'undefined') {
116+
var $self, data, m = prop['rotate'].toString().match(/^(([+-]=)?(-?\d+(\.\d+)?))(.+)?$/);
117+
if (m && m[5]) {
118+
$self = $(this);
119+
data = initData($self);
120+
data.rotateUnits = m[5];
128121
}
129122

130123
prop['rotate'] = m[1];
131124
}
132125

133126
return animateProxied.apply(this, arguments);
134-
}
135-
})(jQuery);
127+
};
128+
})(jQuery);

0 commit comments

Comments
 (0)