1 |
schoenebeck |
2732 |
/* |
2 |
|
|
* transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate() |
3 |
|
|
* |
4 |
|
|
* limitations: |
5 |
|
|
* - requires jQuery 1.4.3+ |
6 |
|
|
* - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**. |
7 |
|
|
* - transformOrigin is not accessible |
8 |
|
|
* |
9 |
|
|
* latest version and complete README available on Github: |
10 |
|
|
* https://github.com/louisremi/jquery.transform.js |
11 |
|
|
* |
12 |
|
|
* Copyright 2011 @louis_remi |
13 |
|
|
* Licensed under the MIT license. |
14 |
|
|
* |
15 |
|
|
* This saved you an hour of work? |
16 |
|
|
* Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON |
17 |
|
|
* |
18 |
|
|
*/ |
19 |
|
|
(function( $, window, document, Math, undefined ) { |
20 |
|
|
|
21 |
|
|
/* |
22 |
|
|
* Feature tests and global variables |
23 |
|
|
*/ |
24 |
|
|
var div = document.createElement("div"), |
25 |
|
|
divStyle = div.style, |
26 |
|
|
suffix = "Transform", |
27 |
|
|
testProperties = [ |
28 |
|
|
"O" + suffix, |
29 |
|
|
"ms" + suffix, |
30 |
|
|
"Webkit" + suffix, |
31 |
|
|
"Moz" + suffix |
32 |
|
|
], |
33 |
|
|
i = testProperties.length, |
34 |
|
|
supportProperty, |
35 |
|
|
supportMatrixFilter, |
36 |
|
|
supportFloat32Array = "Float32Array" in window, |
37 |
|
|
propertyHook, |
38 |
|
|
propertyGet, |
39 |
|
|
rMatrix = /Matrix([^)]*)/, |
40 |
|
|
rAffine = /^\s*matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*(?:,\s*0(?:px)?\s*){2}\)\s*$/, |
41 |
|
|
_transform = "transform", |
42 |
|
|
_transformOrigin = "transformOrigin", |
43 |
|
|
_translate = "translate", |
44 |
|
|
_rotate = "rotate", |
45 |
|
|
_scale = "scale", |
46 |
|
|
_skew = "skew", |
47 |
|
|
_matrix = "matrix"; |
48 |
|
|
|
49 |
|
|
// test different vendor prefixes of these properties |
50 |
|
|
while ( i-- ) { |
51 |
|
|
if ( testProperties[i] in divStyle ) { |
52 |
|
|
$.support[_transform] = supportProperty = testProperties[i]; |
53 |
|
|
$.support[_transformOrigin] = supportProperty + "Origin"; |
54 |
|
|
continue; |
55 |
|
|
} |
56 |
|
|
} |
57 |
|
|
// IE678 alternative |
58 |
|
|
if ( !supportProperty ) { |
59 |
|
|
$.support.matrixFilter = supportMatrixFilter = divStyle.filter === ""; |
60 |
|
|
} |
61 |
|
|
|
62 |
|
|
// px isn't the default unit of these properties |
63 |
|
|
$.cssNumber[_transform] = $.cssNumber[_transformOrigin] = true; |
64 |
|
|
|
65 |
|
|
/* |
66 |
|
|
* fn.css() hooks |
67 |
|
|
*/ |
68 |
|
|
if ( supportProperty && supportProperty != _transform ) { |
69 |
|
|
// Modern browsers can use jQuery.cssProps as a basic hook |
70 |
|
|
$.cssProps[_transform] = supportProperty; |
71 |
|
|
$.cssProps[_transformOrigin] = supportProperty + "Origin"; |
72 |
|
|
|
73 |
|
|
// Firefox needs a complete hook because it stuffs matrix with "px" |
74 |
|
|
if ( supportProperty == "Moz" + suffix ) { |
75 |
|
|
propertyHook = { |
76 |
|
|
get: function( elem, computed ) { |
77 |
|
|
return (computed ? |
78 |
|
|
// remove "px" from the computed matrix |
79 |
|
|
$.css( elem, supportProperty ).split("px").join(""): |
80 |
|
|
elem.style[supportProperty] |
81 |
|
|
); |
82 |
|
|
}, |
83 |
|
|
set: function( elem, value ) { |
84 |
|
|
// add "px" to matrices |
85 |
|
|
elem.style[supportProperty] = /matrix\([^)p]*\)/.test(value) ? |
86 |
|
|
value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, _matrix+"$1$2px,$3px"): |
87 |
|
|
value; |
88 |
|
|
} |
89 |
|
|
}; |
90 |
|
|
/* Fix two jQuery bugs still present in 1.5.1 |
91 |
|
|
* - rupper is incompatible with IE9, see http://jqbug.com/8346 |
92 |
|
|
* - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402 |
93 |
|
|
*/ |
94 |
|
|
} else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) { |
95 |
|
|
propertyHook = { |
96 |
|
|
get: function( elem, computed ) { |
97 |
|
|
return (computed ? |
98 |
|
|
$.css( elem, supportProperty.replace(/^ms/, "Ms") ): |
99 |
|
|
elem.style[supportProperty] |
100 |
|
|
); |
101 |
|
|
} |
102 |
|
|
}; |
103 |
|
|
} |
104 |
|
|
/* TODO: leverage hardware acceleration of 3d transform in Webkit only |
105 |
|
|
else if ( supportProperty == "Webkit" + suffix && support3dTransform ) { |
106 |
|
|
propertyHook = { |
107 |
|
|
set: function( elem, value ) { |
108 |
|
|
elem.style[supportProperty] = |
109 |
|
|
value.replace(); |
110 |
|
|
} |
111 |
|
|
} |
112 |
|
|
}*/ |
113 |
|
|
|
114 |
|
|
} else if ( supportMatrixFilter ) { |
115 |
|
|
propertyHook = { |
116 |
|
|
get: function( elem, computed, asArray ) { |
117 |
|
|
var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ), |
118 |
|
|
matrix, data; |
119 |
|
|
|
120 |
|
|
if ( elemStyle && rMatrix.test( elemStyle.filter ) ) { |
121 |
|
|
matrix = RegExp.$1.split(","); |
122 |
|
|
matrix = [ |
123 |
|
|
matrix[0].split("=")[1], |
124 |
|
|
matrix[2].split("=")[1], |
125 |
|
|
matrix[1].split("=")[1], |
126 |
|
|
matrix[3].split("=")[1] |
127 |
|
|
]; |
128 |
|
|
} else { |
129 |
|
|
matrix = [1,0,0,1]; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
if ( ! $.cssHooks[_transformOrigin] ) { |
133 |
|
|
matrix[4] = elemStyle ? parseInt(elemStyle.left, 10) || 0 : 0; |
134 |
|
|
matrix[5] = elemStyle ? parseInt(elemStyle.top, 10) || 0 : 0; |
135 |
|
|
|
136 |
|
|
} else { |
137 |
|
|
data = $._data( elem, "transformTranslate", undefined ); |
138 |
|
|
matrix[4] = data ? data[0] : 0; |
139 |
|
|
matrix[5] = data ? data[1] : 0; |
140 |
|
|
} |
141 |
|
|
|
142 |
|
|
return asArray ? matrix : _matrix+"(" + matrix + ")"; |
143 |
|
|
}, |
144 |
|
|
set: function( elem, value, animate ) { |
145 |
|
|
var elemStyle = elem.style, |
146 |
|
|
currentStyle, |
147 |
|
|
Matrix, |
148 |
|
|
filter, |
149 |
|
|
centerOrigin; |
150 |
|
|
|
151 |
|
|
if ( !animate ) { |
152 |
|
|
elemStyle.zoom = 1; |
153 |
|
|
} |
154 |
|
|
|
155 |
|
|
value = matrix(value); |
156 |
|
|
|
157 |
|
|
// rotate, scale and skew |
158 |
|
|
Matrix = [ |
159 |
|
|
"Matrix("+ |
160 |
|
|
"M11="+value[0], |
161 |
|
|
"M12="+value[2], |
162 |
|
|
"M21="+value[1], |
163 |
|
|
"M22="+value[3], |
164 |
|
|
"SizingMethod='auto expand'" |
165 |
|
|
].join(); |
166 |
|
|
filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || ""; |
167 |
|
|
|
168 |
|
|
elemStyle.filter = rMatrix.test(filter) ? |
169 |
|
|
filter.replace(rMatrix, Matrix) : |
170 |
|
|
filter + " progid:DXImageTransform.Microsoft." + Matrix + ")"; |
171 |
|
|
|
172 |
|
|
if ( ! $.cssHooks[_transformOrigin] ) { |
173 |
|
|
|
174 |
|
|
// center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie |
175 |
|
|
if ( (centerOrigin = $.transform.centerOrigin) ) { |
176 |
|
|
elemStyle[centerOrigin == "margin" ? "marginLeft" : "left"] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + "px"; |
177 |
|
|
elemStyle[centerOrigin == "margin" ? "marginTop" : "top"] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + "px"; |
178 |
|
|
} |
179 |
|
|
|
180 |
|
|
// translate |
181 |
|
|
// We assume that the elements are absolute positionned inside a relative positionned wrapper |
182 |
|
|
elemStyle.left = value[4] + "px"; |
183 |
|
|
elemStyle.top = value[5] + "px"; |
184 |
|
|
|
185 |
|
|
} else { |
186 |
|
|
$.cssHooks[_transformOrigin].set( elem, value ); |
187 |
|
|
} |
188 |
|
|
} |
189 |
|
|
}; |
190 |
|
|
} |
191 |
|
|
// populate jQuery.cssHooks with the appropriate hook if necessary |
192 |
|
|
if ( propertyHook ) { |
193 |
|
|
$.cssHooks[_transform] = propertyHook; |
194 |
|
|
} |
195 |
|
|
// we need a unique setter for the animation logic |
196 |
|
|
propertyGet = propertyHook && propertyHook.get || $.css; |
197 |
|
|
|
198 |
|
|
/* |
199 |
|
|
* fn.animate() hooks |
200 |
|
|
*/ |
201 |
|
|
$.fx.step.transform = function( fx ) { |
202 |
|
|
var elem = fx.elem, |
203 |
|
|
start = fx.start, |
204 |
|
|
end = fx.end, |
205 |
|
|
pos = fx.pos, |
206 |
|
|
transform = "", |
207 |
|
|
precision = 1E5, |
208 |
|
|
i, startVal, endVal, unit; |
209 |
|
|
|
210 |
|
|
// fx.end and fx.start need to be converted to interpolation lists |
211 |
|
|
if ( !start || typeof start === "string" ) { |
212 |
|
|
|
213 |
|
|
// the following block can be commented out with jQuery 1.5.1+, see #7912 |
214 |
|
|
if ( !start ) { |
215 |
|
|
start = propertyGet( elem, supportProperty ); |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
// force layout only once per animation |
219 |
|
|
if ( supportMatrixFilter ) { |
220 |
|
|
elem.style.zoom = 1; |
221 |
|
|
} |
222 |
|
|
|
223 |
|
|
// replace "+=" in relative animations (-= is meaningless with transforms) |
224 |
|
|
end = end.split("+=").join(start); |
225 |
|
|
|
226 |
|
|
// parse both transform to generate interpolation list of same length |
227 |
|
|
$.extend( fx, interpolationList( start, end ) ); |
228 |
|
|
start = fx.start; |
229 |
|
|
end = fx.end; |
230 |
|
|
} |
231 |
|
|
|
232 |
|
|
i = start.length; |
233 |
|
|
|
234 |
|
|
// interpolate functions of the list one by one |
235 |
|
|
while ( i-- ) { |
236 |
|
|
startVal = start[i]; |
237 |
|
|
endVal = end[i]; |
238 |
|
|
unit = +false; |
239 |
|
|
|
240 |
|
|
switch ( startVal[0] ) { |
241 |
|
|
|
242 |
|
|
case _translate: |
243 |
|
|
unit = "px"; |
244 |
|
|
case _scale: |
245 |
|
|
unit || ( unit = ""); |
246 |
|
|
|
247 |
|
|
transform = startVal[0] + "(" + |
248 |
|
|
Math.round( (startVal[1][0] + (endVal[1][0] - startVal[1][0]) * pos) * precision ) / precision + unit +","+ |
249 |
|
|
Math.round( (startVal[1][1] + (endVal[1][1] - startVal[1][1]) * pos) * precision ) / precision + unit + ")"+ |
250 |
|
|
transform; |
251 |
|
|
break; |
252 |
|
|
|
253 |
|
|
case _skew + "X": |
254 |
|
|
case _skew + "Y": |
255 |
|
|
case _rotate: |
256 |
|
|
transform = startVal[0] + "(" + |
257 |
|
|
Math.round( (startVal[1] + (endVal[1] - startVal[1]) * pos) * precision ) / precision +"rad)"+ |
258 |
|
|
transform; |
259 |
|
|
break; |
260 |
|
|
} |
261 |
|
|
} |
262 |
|
|
|
263 |
|
|
fx.origin && ( transform = fx.origin + transform ); |
264 |
|
|
|
265 |
|
|
propertyHook && propertyHook.set ? |
266 |
|
|
propertyHook.set( elem, transform, +true ): |
267 |
|
|
elem.style[supportProperty] = transform; |
268 |
|
|
}; |
269 |
|
|
|
270 |
|
|
/* |
271 |
|
|
* Utility functions |
272 |
|
|
*/ |
273 |
|
|
|
274 |
|
|
// turns a transform string into its "matrix(A,B,C,D,X,Y)" form (as an array, though) |
275 |
|
|
function matrix( transform ) { |
276 |
|
|
transform = transform.split(")"); |
277 |
|
|
var |
278 |
|
|
trim = $.trim |
279 |
|
|
, i = -1 |
280 |
|
|
// last element of the array is an empty string, get rid of it |
281 |
|
|
, l = transform.length -1 |
282 |
|
|
, split, prop, val |
283 |
|
|
, prev = supportFloat32Array ? new Float32Array(6) : [] |
284 |
|
|
, curr = supportFloat32Array ? new Float32Array(6) : [] |
285 |
|
|
, rslt = supportFloat32Array ? new Float32Array(6) : [1,0,0,1,0,0] |
286 |
|
|
; |
287 |
|
|
|
288 |
|
|
prev[0] = prev[3] = rslt[0] = rslt[3] = 1; |
289 |
|
|
prev[1] = prev[2] = prev[4] = prev[5] = 0; |
290 |
|
|
|
291 |
|
|
// Loop through the transform properties, parse and multiply them |
292 |
|
|
while ( ++i < l ) { |
293 |
|
|
split = transform[i].split("("); |
294 |
|
|
prop = trim(split[0]); |
295 |
|
|
val = split[1]; |
296 |
|
|
curr[0] = curr[3] = 1; |
297 |
|
|
curr[1] = curr[2] = curr[4] = curr[5] = 0; |
298 |
|
|
|
299 |
|
|
switch (prop) { |
300 |
|
|
case _translate+"X": |
301 |
|
|
curr[4] = parseInt(val, 10); |
302 |
|
|
break; |
303 |
|
|
|
304 |
|
|
case _translate+"Y": |
305 |
|
|
curr[5] = parseInt(val, 10); |
306 |
|
|
break; |
307 |
|
|
|
308 |
|
|
case _translate: |
309 |
|
|
val = val.split(","); |
310 |
|
|
curr[4] = parseInt(val[0], 10); |
311 |
|
|
curr[5] = parseInt(val[1] || 0, 10); |
312 |
|
|
break; |
313 |
|
|
|
314 |
|
|
case _rotate: |
315 |
|
|
val = toRadian(val); |
316 |
|
|
curr[0] = Math.cos(val); |
317 |
|
|
curr[1] = Math.sin(val); |
318 |
|
|
curr[2] = -Math.sin(val); |
319 |
|
|
curr[3] = Math.cos(val); |
320 |
|
|
break; |
321 |
|
|
|
322 |
|
|
case _scale+"X": |
323 |
|
|
curr[0] = +val; |
324 |
|
|
break; |
325 |
|
|
|
326 |
|
|
case _scale+"Y": |
327 |
|
|
curr[3] = val; |
328 |
|
|
break; |
329 |
|
|
|
330 |
|
|
case _scale: |
331 |
|
|
val = val.split(","); |
332 |
|
|
curr[0] = val[0]; |
333 |
|
|
curr[3] = val.length>1 ? val[1] : val[0]; |
334 |
|
|
break; |
335 |
|
|
|
336 |
|
|
case _skew+"X": |
337 |
|
|
curr[2] = Math.tan(toRadian(val)); |
338 |
|
|
break; |
339 |
|
|
|
340 |
|
|
case _skew+"Y": |
341 |
|
|
curr[1] = Math.tan(toRadian(val)); |
342 |
|
|
break; |
343 |
|
|
|
344 |
|
|
case _matrix: |
345 |
|
|
val = val.split(","); |
346 |
|
|
curr[0] = val[0]; |
347 |
|
|
curr[1] = val[1]; |
348 |
|
|
curr[2] = val[2]; |
349 |
|
|
curr[3] = val[3]; |
350 |
|
|
curr[4] = parseInt(val[4], 10); |
351 |
|
|
curr[5] = parseInt(val[5], 10); |
352 |
|
|
break; |
353 |
|
|
} |
354 |
|
|
|
355 |
|
|
// Matrix product (array in column-major order) |
356 |
|
|
rslt[0] = prev[0] * curr[0] + prev[2] * curr[1]; |
357 |
|
|
rslt[1] = prev[1] * curr[0] + prev[3] * curr[1]; |
358 |
|
|
rslt[2] = prev[0] * curr[2] + prev[2] * curr[3]; |
359 |
|
|
rslt[3] = prev[1] * curr[2] + prev[3] * curr[3]; |
360 |
|
|
rslt[4] = prev[0] * curr[4] + prev[2] * curr[5] + prev[4]; |
361 |
|
|
rslt[5] = prev[1] * curr[4] + prev[3] * curr[5] + prev[5]; |
362 |
|
|
|
363 |
|
|
prev = [rslt[0],rslt[1],rslt[2],rslt[3],rslt[4],rslt[5]]; |
364 |
|
|
} |
365 |
|
|
return rslt; |
366 |
|
|
} |
367 |
|
|
|
368 |
|
|
// turns a matrix into its rotate, scale and skew components |
369 |
|
|
// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp |
370 |
|
|
function unmatrix(matrix) { |
371 |
|
|
var |
372 |
|
|
scaleX |
373 |
|
|
, scaleY |
374 |
|
|
, skew |
375 |
|
|
, A = matrix[0] |
376 |
|
|
, B = matrix[1] |
377 |
|
|
, C = matrix[2] |
378 |
|
|
, D = matrix[3] |
379 |
|
|
; |
380 |
|
|
|
381 |
|
|
// Make sure matrix is not singular |
382 |
|
|
if ( A * D - B * C ) { |
383 |
|
|
// step (3) |
384 |
|
|
scaleX = Math.sqrt( A * A + B * B ); |
385 |
|
|
A /= scaleX; |
386 |
|
|
B /= scaleX; |
387 |
|
|
// step (4) |
388 |
|
|
skew = A * C + B * D; |
389 |
|
|
C -= A * skew; |
390 |
|
|
D -= B * skew; |
391 |
|
|
// step (5) |
392 |
|
|
scaleY = Math.sqrt( C * C + D * D ); |
393 |
|
|
C /= scaleY; |
394 |
|
|
D /= scaleY; |
395 |
|
|
skew /= scaleY; |
396 |
|
|
// step (6) |
397 |
|
|
if ( A * D < B * C ) { |
398 |
|
|
A = -A; |
399 |
|
|
B = -B; |
400 |
|
|
skew = -skew; |
401 |
|
|
scaleX = -scaleX; |
402 |
|
|
} |
403 |
|
|
|
404 |
|
|
// matrix is singular and cannot be interpolated |
405 |
|
|
} else { |
406 |
|
|
// In this case the elem shouldn't be rendered, hence scale == 0 |
407 |
|
|
scaleX = scaleY = skew = 0; |
408 |
|
|
} |
409 |
|
|
|
410 |
|
|
// The recomposition order is very important |
411 |
|
|
// see http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp#l971 |
412 |
|
|
return [ |
413 |
|
|
[_translate, [+matrix[4], +matrix[5]]], |
414 |
|
|
[_rotate, Math.atan2(B, A)], |
415 |
|
|
[_skew + "X", Math.atan(skew)], |
416 |
|
|
[_scale, [scaleX, scaleY]] |
417 |
|
|
]; |
418 |
|
|
} |
419 |
|
|
|
420 |
|
|
// build the list of transform functions to interpolate |
421 |
|
|
// use the algorithm described at http://dev.w3.org/csswg/css3-2d-transforms/#animation |
422 |
|
|
function interpolationList( start, end ) { |
423 |
|
|
var list = { |
424 |
|
|
start: [], |
425 |
|
|
end: [] |
426 |
|
|
}, |
427 |
|
|
i = -1, l, |
428 |
|
|
currStart, currEnd, currType; |
429 |
|
|
|
430 |
|
|
// get rid of affine transform matrix |
431 |
|
|
( start == "none" || isAffine( start ) ) && ( start = "" ); |
432 |
|
|
( end == "none" || isAffine( end ) ) && ( end = "" ); |
433 |
|
|
|
434 |
|
|
// if end starts with the current computed style, this is a relative animation |
435 |
|
|
// store computed style as the origin, remove it from start and end |
436 |
|
|
if ( start && end && !end.indexOf("matrix") && toArray( start ).join() == toArray( end.split(")")[0] ).join() ) { |
437 |
|
|
list.origin = start; |
438 |
|
|
start = ""; |
439 |
|
|
end = end.slice( end.indexOf(")") +1 ); |
440 |
|
|
} |
441 |
|
|
|
442 |
|
|
if ( !start && !end ) { return; } |
443 |
|
|
|
444 |
|
|
// start or end are affine, or list of transform functions are identical |
445 |
|
|
// => functions will be interpolated individually |
446 |
|
|
if ( !start || !end || functionList(start) == functionList(end) ) { |
447 |
|
|
|
448 |
|
|
start && ( start = start.split(")") ) && ( l = start.length ); |
449 |
|
|
end && ( end = end.split(")") ) && ( l = end.length ); |
450 |
|
|
|
451 |
|
|
while ( ++i < l-1 ) { |
452 |
|
|
start[i] && ( currStart = start[i].split("(") ); |
453 |
|
|
end[i] && ( currEnd = end[i].split("(") ); |
454 |
|
|
currType = $.trim( ( currStart || currEnd )[0] ); |
455 |
|
|
|
456 |
|
|
append( list.start, parseFunction( currType, currStart ? currStart[1] : 0 ) ); |
457 |
|
|
append( list.end, parseFunction( currType, currEnd ? currEnd[1] : 0 ) ); |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
// otherwise, functions will be composed to a single matrix |
461 |
|
|
} else { |
462 |
|
|
list.start = unmatrix(matrix(start)); |
463 |
|
|
list.end = unmatrix(matrix(end)) |
464 |
|
|
} |
465 |
|
|
|
466 |
|
|
return list; |
467 |
|
|
} |
468 |
|
|
|
469 |
|
|
function parseFunction( type, value ) { |
470 |
|
|
var |
471 |
|
|
// default value is 1 for scale, 0 otherwise |
472 |
|
|
defaultValue = +(!type.indexOf(_scale)), |
473 |
|
|
scaleX, |
474 |
|
|
// remove X/Y from scaleX/Y & translateX/Y, not from skew |
475 |
|
|
cat = type.replace( /e[XY]/, "e" ); |
476 |
|
|
|
477 |
|
|
switch ( type ) { |
478 |
|
|
case _translate+"Y": |
479 |
|
|
case _scale+"Y": |
480 |
|
|
|
481 |
|
|
value = [ |
482 |
|
|
defaultValue, |
483 |
|
|
value ? |
484 |
|
|
parseFloat( value ): |
485 |
|
|
defaultValue |
486 |
|
|
]; |
487 |
|
|
break; |
488 |
|
|
|
489 |
|
|
case _translate+"X": |
490 |
|
|
case _translate: |
491 |
|
|
case _scale+"X": |
492 |
|
|
scaleX = 1; |
493 |
|
|
case _scale: |
494 |
|
|
|
495 |
|
|
value = value ? |
496 |
|
|
( value = value.split(",") ) && [ |
497 |
|
|
parseFloat( value[0] ), |
498 |
|
|
parseFloat( value.length>1 ? value[1] : type == _scale ? scaleX || value[0] : defaultValue+"" ) |
499 |
|
|
]: |
500 |
|
|
[defaultValue, defaultValue]; |
501 |
|
|
break; |
502 |
|
|
|
503 |
|
|
case _skew+"X": |
504 |
|
|
case _skew+"Y": |
505 |
|
|
case _rotate: |
506 |
|
|
value = value ? toRadian( value ) : 0; |
507 |
|
|
break; |
508 |
|
|
|
509 |
|
|
case _matrix: |
510 |
|
|
return unmatrix( value ? toArray(value) : [1,0,0,1,0,0] ); |
511 |
|
|
break; |
512 |
|
|
} |
513 |
|
|
|
514 |
|
|
return [[ cat, value ]]; |
515 |
|
|
} |
516 |
|
|
|
517 |
|
|
function isAffine( matrix ) { |
518 |
|
|
return rAffine.test(matrix); |
519 |
|
|
} |
520 |
|
|
|
521 |
|
|
function functionList( transform ) { |
522 |
|
|
return transform.replace(/(?:\([^)]*\))|\s/g, ""); |
523 |
|
|
} |
524 |
|
|
|
525 |
|
|
function append( arr1, arr2, value ) { |
526 |
|
|
while ( value = arr2.shift() ) { |
527 |
|
|
arr1.push( value ); |
528 |
|
|
} |
529 |
|
|
} |
530 |
|
|
|
531 |
|
|
// converts an angle string in any unit to a radian Float |
532 |
|
|
function toRadian(value) { |
533 |
|
|
return ~value.indexOf("deg") ? |
534 |
|
|
parseInt(value,10) * (Math.PI * 2 / 360): |
535 |
|
|
~value.indexOf("grad") ? |
536 |
|
|
parseInt(value,10) * (Math.PI/200): |
537 |
|
|
parseFloat(value); |
538 |
|
|
} |
539 |
|
|
|
540 |
|
|
// Converts "matrix(A,B,C,D,X,Y)" to [A,B,C,D,X,Y] |
541 |
|
|
function toArray(matrix) { |
542 |
|
|
// remove the unit of X and Y for Firefox |
543 |
|
|
matrix = /([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix); |
544 |
|
|
return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]]; |
545 |
|
|
} |
546 |
|
|
|
547 |
|
|
$.transform = { |
548 |
|
|
centerOrigin: "margin" |
549 |
|
|
}; |
550 |
|
|
|
551 |
|
|
})( jQuery, window, document, Math ); |