clipbucket/upload/styles/cbv2.7/theme/js/uslider_js/QTransform.js
2014-05-09 14:38:00 +00:00

455 lines
No EOL
16 KiB
JavaScript

/*
* based off of Louis-Rémi Babé rotate plugin (https://github.com/lrbabe/jquery.rotate.js)
*
* cssTransforms: jQuery cssHooks adding a cross browser, animatible transforms
*
* Author Bobby Schultz
*/
//
(function($) {
var div = document.createElement('div'),
divStyle = div.style;
//give props to those who dont have them
$.cssProps.transform =
divStyle.MozTransform === '' ? 'MozTransform' :
(divStyle.msTransform === '' ? 'msTransform' :
(divStyle.WebkitTransform === '' ? 'WebkitTransform' :
(divStyle.OTransform === '' ? 'OTransform' :
(divStyle.Transform === '' ? 'Transform' :
false))));
$.cssProps.transformOrigin =
divStyle.MozTransformOrigin === '' ? 'MozTransformOrigin' :
(divStyle.msTransformOrigin === '' ? 'msTransformOrigin' :
(divStyle.WebkitTransformOrigin === '' ? 'WebkitTransformOrigin' :
(divStyle.OTransformOrigin === '' ? 'OTransformOrigin' :
(divStyle.TransformOrigin === '' ? 'TransformOrigin' :
false))));
//define supported or not
$.support.transform = $.cssProps.transform !== false || divStyle.filter === '' ? true : false;
$.support.transformOrigin = $.cssProps.transformOrigin !== false ? true : false;
//if ONLY IE matrixes are supported (IE9 beta6 will use css3)
$.support.matrixFilter = (divStyle.filter === '' && $.cssProps.transform === false) ?
true : false;
div = null;
//stop if no form of transforms are supported
if($.support.transform === false)
return;
//opt out of letting jquery handle the units for custom setters/getters
$.cssNumber.skew =
$.cssNumber.skewX =
$.cssNumber.skewY =
$.cssNumber.scale =
$.cssNumber.scaleX =
$.cssNumber.scaleY =
$.cssNumber.rotate =
$.cssNumber.matrix = true;
$.cssNumber.transformOrigin =
$.cssNumber.transformOriginX =
$.cssNumber.transformOriginY = true;
if($.support.matrixFilter) {
$.cssNumber.transformOrigin =
$.cssNumber.transformOriginX =
$.cssNumber.transformOriginY = true;
$.cssProps.transformOrigin = 'matrixFilter';
}
$.cssHooks.transform = {
set: function(elem, val, unit) {
if($.support.matrixFilter) {
elem.style.filter = [val].join('');
} else {
elem.style[$.cssProps.transform] = val+'%';
}
},
get: function(elem, computed) {
if($.support.matrixFilter) {
return elem.style.filter;
} else {
return elem.style[$.cssProps.transform];
}
}
};
$.cssHooks.transformOrigin = {
set: function(elem, val, unit) {
if(!$.support.matrixFilter) {
val = (typeof val === 'string') ? val : val+(unit || '%');
elem.style[$.cssProps.transformOrigin] = val;
} else {
val = val.split(",");
$.cssHooks.transformOriginX.set( elem, val[0] );
if(val.length > 1) {
$.cssHooks.transformOriginY.set( elem, val[1] );
}
}
},
get: function(elem, computed) {
if(!$.support.matrixFilter) {
return elem.style[$.cssProps.transformOrigin];
} else {
var originX = $.data( elem, 'transformOriginX' );
var originY = $.data( elem, 'transformOriginY' );
return originX && originY && originX === originY ? originX : '50%';
}
}
};
$.fx.step.transformOrigin = function( fx ) {
$.cssHooks.transformOrigin.set( fx.elem, fx.now, fx.unit);
};
$.cssHooks.transformOriginX = {
set: function(elem, val, unit) {
if(!$.support.matrixFilter) {
val = (typeof val === 'string') ? val : val+(unit || '%');
elem.style[$.cssProps.transformOrigin+'X'] = val;
} else {
$.data( elem, 'transformOriginX', unit ? val+unit : val );
setIEMatrix(elem);
}
},
get: function(elem, computed) {
if(!$.support.matrixFilter) {
return elem.style[$.cssProps.transformOrigin+'X'];
} else {
var originX = $.data( elem, 'transformOriginX' );
switch(originX) {
case 'left': return '0%';
case 'center': return '50%';
case 'right': return '100%';
}
return originX ? originX : '50%';
}
}
};
$.fx.step.transformOriginX = function( fx ) {
$.cssHooks.transformOriginX.set( fx.elem, fx.now, fx.unit);
};
$.cssHooks.transformOriginY = {
set: function(elem, val, unit) {
if(!$.support.matrixFilter) {
val = (typeof val === 'string') ? val : val+(unit || '%');
elem.style[$.cssProps.transformOrigin+'Y'] = val;
} else {
$.data( elem, 'transformOriginY', unit ? val+unit : val );
setIEMatrix(elem);
}
},
get: function(elem, computed) {
if(!$.support.matrixFilter) {
return elem.style[$.cssProps.transformOrigin+'Y'];
} else {
var originY = $.data( elem, 'transformOriginY' );
switch(originY) {
case 'top': return '0%';
case 'center': return '50%';
case 'bottom': return '100%';
}
return originY ? originY : '50%';
}
}
};
$.fx.step.transformOriginY = function( fx ) {
$.cssHooks.transformOriginY.set( fx.elem, fx.now, fx.unit);
};
//create hooks for css transforms
var rtn = function(v){return v;};
var xy = [['X','Y'],'X','Y'];
var abcdxy = [['A','B','C','D','X','Y'],'A','B','C','D','X','Y']
var props = [
{prop: 'rotate',
matrix: [function(v){ return Math.cos(v); },
function(v){ return -Math.sin(v); },
function(v){ return Math.sin(v); },
function(v){ return Math.cos(v); } ],
unit: 'rad',
subProps: [''],
fnc: toRadian},
{prop: 'scale',
matrix: [[rtn,0,0,rtn],
[rtn,0,0,1],
[1,0,0,rtn]],
unit: '',
subProps: xy,
fnc: parseFloat,
_default:1},
{prop: 'skew',
matrix: [[1,rtn,rtn,1],
[1,rtn,0,1],
[1,0,rtn,1]],
unit: 'rad',
subProps: xy,
fnc: toRadian},
{prop: 'translate',
matrix: [[1,0,0,1,rtn,rtn],
[1,0,0,1,rtn,0],
[1,0,0,1,0,rtn]],
standardUnit: 'px',
subProps: xy,
fnc: parseFloat},
{prop: 'matrix',
matrix: [[rtn,rtn,rtn,rtn,rtn,rtn],
[rtn,0,0,1,0,0],
[1,rtn,0,1,0,0],
[1,0,rtn,1,0,0],
[1,0,0,rtn,0,0],
[1,0,0,1,0,rtn]],
subProps: abcdxy,
fnc: parseFloat}
];
jQuery.each(props, function(n,prop){
jQuery.each(prop.subProps, function(num, sub){
var _cssProp, _prop = prop;
if( $.isArray(sub) ) {
//composite transform
_cssProp = _prop.prop;
var _sub = sub;
$.cssHooks[_cssProp] = {
set: function( elem, val, unit ) {
jQuery.each(_sub, function(num, x){
$.cssHooks[_cssProp+x].set(elem, val, unit);
});
},
get: function( elem, computed ) {
var val = [];
jQuery.each(_sub, function(num, x){
val.push( $.cssHooks[_cssProp+x].get(elem, val) );
});
//hack until jQuery supports animating multiple properties
return val[0] || val[1];
}
}
} else {
//independent transfrom
_cssProp = _prop.prop+sub;
//alert(_cssProp); //********
$.cssHooks[_cssProp] = {
set: function( elem, val, unit ) {
$.data( elem, _cssProp, unit ? val+unit : val);
setCSSTransform( elem, _prop.fnc(unit ? val+unit : val), _cssProp,
_prop.unit || unit || _prop.standardUnit);
},
get: function( elem, computed ) {
var p = $.data( elem, _cssProp );
//console.log(_cssProp+'get:'+p);
return p && p !== undefined ? p : _prop._default || 0;
}
};
}
$.fx.step[_cssProp] = function( fx ) {
fx.unit = fx.unit === 'px' && $.cssNumber[_cssProp] ? _prop.standardUnit : fx.unit;
var unit = ($.cssNumber[_cssProp] ? '' : fx.unit);
$.cssHooks[_cssProp].set( fx.elem, fx.now, fx.unit);
};
})
});
function setCSSTransform( elem, val, prop, unit ){
if($.support.matrixFilter) {
return setIEMatrix(elem, val);
}
//parse css string
var allProps = parseCSSTransform(elem);
//check for value to be set
var a = /[X|Y]/.exec(prop);
a = (a === null ? '' : a[0] ? a[0] : a);
prop = /.*[^XY]/.exec(prop)[0];
unit = unit === undefined ? '' : unit;
//create return string
var result = '';
var wasUpdated = false;
var arr;
if(allProps !== null) {
for(var item in allProps) {
arr = allProps[item];
if(prop === item) {
//update parsed data with new value
if(prop !== 'matrix') {
result += prop+'(';
result += a === 'X' || a === '' ? val+unit :
(arr[0] !== '' ? arr[0] : $.cssHooks[prop+'X'].get(elem)+unit);
result += a === 'Y' ? ', '+val+unit :
(arr[1] !== '' ? ', '+arr[1] :
(prop+'Y' in $.cssHooks ?
', '+$.cssHooks[prop+'Y'].get(elem)+unit : ''));
result += ') ';
} else {
result += val+' ';
}
wasUpdated = true;
} else {
//dump parsed data to string
result += item + '(';
for(var i=0; i<arr.length; i++) {
result += arr[i];
if(i < arr.length-1 && arr[i+1] !== '')
result += ', '
else
break;
}
result += ') ';
}
}
}
//if prop was not found to be updated, then dump data
if(!wasUpdated)
result += prop+a+'('+val+unit+ ') ';
//set all transform properties
elem.style[$.cssProps.transform] = result;
}
function parseCSSTransform( elem ) {
var props, prop, name, transform;
//break up into single transform calls
$(elem.style[$.cssProps.transform].replace(/(?:\,\s|\)|\()/g,"|").split(" "))
//read each data point for the transform call
.each(function(i, item){
if(item !== '') {
if(props === undefined) props = {}
prop = item.split("|");
name = prop.shift();
transform = /.*[^XY]/.exec(name)[0];
if(!props[transform]) props[transform] = ['','','','','',''];
if(!/Y/.test(name)) props[transform][0] = prop[0];
if(!/X/.test(name)) props[transform][1] = prop[1];
if(prop.length == 6) {
props[transform][2] = prop[2];
props[transform][3] = prop[3];
props[transform][4] = prop[4];
props[transform][5] = prop[5];
}
}
});
return props !== undefined ? props : null ;
}
function ieOrigin(o, n, percent) {
return percent * (o - n);
}
function toRadian(value) {
if(typeof value === 'number') {
return parseFloat(value);
}
if(value.indexOf("deg") != -1) {
return parseInt(value,10) * (Math.PI * 2 / 360);
} else if (value.indexOf("grad") != -1) {
return parseInt(value,10) * (Math.PI/200);
}
}
$.rotate = {
radToDeg: function radToDeg( rad ) {
return rad * 180 / Math.PI;
}
};
//special case for IE matrix
function setIEMatrix( elem, mat ) {
var inverse, current, ang, org, originX, originY,
runTransform = $.cssProps.transformOrigin === 'matrixFilter' ? true : false;
current = [$.cssHooks.scaleX.get(elem),
toRadian($.cssHooks.skewY.get(elem)),
toRadian($.cssHooks.skewX.get(elem)),
$.cssHooks.scaleY.get(elem),
$.cssHooks.translateX.get(elem),
$.cssHooks.translateY.get(elem)];
//start by multiply inverse of transform origin by matrix
if(runTransform) {
elem.style.filter = [
"progid:DXImageTransform.Microsoft.Matrix"
+"(M11=1,M12=0,M21=0,M22=1,SizingMethod='auto expand')"
].join('');
var Wp = $.cssHooks.transformOriginX.get(elem);
var Hp = $.cssHooks.transformOriginY.get(elem);
Wp = Wp.indexOf('%') > 0 ?
(/[\d]*/.exec(Wp) / 100) : Wp;
Hp = Hp.indexOf('%') > 0 ?
(/[\d]*/.exec(Hp) / 100) : Hp;
var Wb = elem.offsetWidth;
var Hb = elem.offsetHeight;
}
//multiply old matrix to new matrix
if( typeof mat !== 'array' || mat.length !== 6 ) {
mat = current;
} else {
mat = [ ( (current[0]*mat[0]) + (current[1]*mat[2]) ),
( (current[0]*mat[1]) + (current[1]*mat[3]) ),
( (current[2]*mat[0]) + (current[3]*mat[2]) ),
( (current[2]*mat[1]) + (current[3]*mat[3]) ),
mat[4],
mat[5]
];
}
//multiply the transform and rotation matrixes
ang = $.data(elem, 'rotate');
if(ang) {
ang = toRadian(ang);
var cos = Math.cos(ang);
var sin = Math.sin(ang);
ang = [cos, -sin, sin, cos];
mat = [ ( (mat[0]*ang[0]) + (mat[1]*ang[2]) ),
( (mat[0]*ang[1]) + (mat[1]*ang[3]) ),
( (mat[2]*ang[0]) + (mat[3]*ang[2]) ),
( (mat[2]*ang[1]) + (mat[3]*ang[3]) ),
mat[4],
mat[5]
];
}
//apply the matrix as a IE filter
elem.style.filter = [
"progid:DXImageTransform.Microsoft.Matrix(",
"M11="+mat[0]+", ",
"M12="+mat[1]+", ",
"M21="+mat[2]+", ",
"M22="+mat[3]+", ",
"SizingMethod='auto expand'",
")"
].join('');
if (runTransform) {
var Wo = elem.offsetWidth;
var Ho = elem.offsetHeight;
elem.style.position = 'relative';
elem.style.left = Wp * (Wb - Wo) + (parseInt(mat[4]) || 0);
elem.style.top = Hp * (Hb - Ho) + (parseInt(mat[5]) || 0);
}
//$('#console').append('<div> trans:'+Wp+":"+Wb+":"+Wo+":"+mat[4]+":"+elem.style.left+'</div>');
}
})(jQuery);