Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pulled in the rake build from jQuery

  • Loading branch information...
commit 013b56a910eac7455f89d9433353433e1e3e88d8 1 parent 9763970
@heygrady authored
View
81 Rakefile
@@ -0,0 +1,81 @@
+prefix = File.dirname( __FILE__ )
+
+# Directory variables
+src_dir = File.join( prefix, 'src' )
+build_dir = File.join( prefix, 'build' )
+test_dir = File.join( prefix, 'test' )
+
+# A different destination directory can be set by
+# setting DIST_DIR before calling rake
+dist_dir = ENV['DIST_DIR'] || File.join( prefix, 'dist' )
+
+base_files = %w{transform transform.attributes transform.animate angle matrix matrix.calculations matrix.functions}.map { |js| File.join( src_dir, "jquery.#{js}.js" ) }
+
+# General Variables
+date = `git log -1`[/^Date:\s+(.+)$/, 1]
+version = File.read( File.join( prefix, 'version.txt' ) ).strip
+
+# jQuery files/dirs
+jq = File.join( dist_dir, "jquery.transform-#{version}.js" )
+jq_min = File.join( dist_dir, "jquery.transform-#{version}.min.js" )
+
+
+# Build tools
+rhino = "java -jar \"#{build_dir}/js.jar\""
+minfier = "java -jar \"#{build_dir}/yuicompressor-2.4.2.jar\""
+
+# Turn off output other than needed from `sh` and file commands
+verbose(false)
+
+# Tasks
+task :default => "all"
+
+desc "Builds jQuery; Tests with JSLint; Minifies jQuery"
+task :all => [:jquery, :lint, :min] do
+ puts "jQuery build complete."
+end
+
+desc "Builds jQuery Transform: jquery.transform.js (Default task)"
+task :jquery => [jq]
+
+desc "Builds a minified version of jQuery Transform: jquery.transform.min.js"
+task :min => jq_min
+
+
+task :init => [] do
+end
+
+desc "Removes dist folder"
+task :clean do
+ puts "Removing Distribution directory: #{dist_dir}..."
+ rm_rf dist_dir
+end
+
+desc "Tests built jquery.transform.js against JSLint"
+task :lint => jq do
+ puts "Checking jQuery against JSLint..."
+ sh "#{rhino} \"" + File.join(build_dir, 'jslint-check.js') + "\""
+end
+
+
+# File and Directory Dependencies
+directory dist_dir
+
+file jq => [dist_dir, base_files].flatten do
+ puts "Building jquery.transform.js..."
+
+ File.open(jq, 'w') do |f|
+ f.write cat(base_files).gsub(/(Date:.)/, "\\1#{date}" ).gsub(/@VERSION/, version)
+ end
+end
+
+file jq_min => jq do
+ puts "Building jquery.transform.min.js..."
+ sh "#{minfier} -o \"#{jq_min}\" \"#{jq}\""
+end
+
+def cat( files )
+ files.map do |file|
+ File.read(file)
+ end.join('')
+end
View
BIN  build/js.jar
Binary file not shown
View
36 build/jslint-check.js
@@ -0,0 +1,36 @@
+load("build/jslint.js");
+
+var src = readFile("dist/jquery.js");
+
+JSLINT(src, { evil: true, forin: true, maxerr: 100 });
+
+// All of the following are known issues that we think are 'ok'
+// (in contradiction with JSLint) more information here:
+// http://docs.jquery.com/JQuery_Core_Style_Guidelines
+var ok = {
+ "Expected an identifier and instead saw 'undefined' (a reserved word).": true,
+ "Use '===' to compare with 'null'.": true,
+ "Use '!==' to compare with 'null'.": true,
+ "Expected an assignment or function call and instead saw an expression.": true,
+ "Expected a 'break' statement before 'case'.": true
+
+};
+
+var e = JSLINT.errors, found = 0, w;
+
+for ( var i = 0; i < e.length; i++ ) {
+ w = e[i];
+
+ if ( !ok[ w.reason ] ) {
+ found++;
+ print( "\n" + w.evidence + "\n" );
+ print( " Problem at line " + w.line + " character " + w.character + ": " + w.reason );
+ }
+}
+
+if ( found > 0 ) {
+ print( "\n" + found + " Error(s) found." );
+
+} else {
+ print( "JSLint check passed." );
+}
View
5,500 build/jslint.js
5,500 additions, 0 deletions not shown
View
BIN  build/yuicompressor-2.4.2.jar
Binary file not shown
View
1,772 dist/jquery.transform-0.9.0.js
@@ -0,0 +1,1772 @@
+/*!
+ * jQuery 2d Transform v0.9.0
+ * http://wiki.github.com/heygrady/transform/
+ *
+ * Copyright 2010, Grady Kuhnline
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Date: Wed Oct 6 00:34:26 2010 -0700
+ */
+///////////////////////////////////////////////////////
+// Transform
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ /**
+ * @var Regex identify the matrix filter in IE
+ */
+ var rmatrix = /progid:DXImageTransform\.Microsoft\.Matrix\(.*?\)/;
+
+ // Steal some code from Modernizr
+ var m = document.createElement( 'modernizr' ),
+ m_style = m.style;
+
+ function stripUnits(arg) {
+ return parseFloat(arg);
+ }
+
+ /**
+ * Find the prefix that this browser uses
+ */
+ function getVendorPrefix() {
+ var property = {
+ transformProperty : '',
+ MozTransform : '-moz-',
+ WebkitTransform : '-webkit-',
+ OTransform : '-o-',
+ msTransform : '-ms-'
+ };
+ for (var p in property) {
+ if (typeof m_style[p] != 'undefined') {
+ return property[p];
+ }
+ }
+ return null;
+ }
+
+ function supportCssTransforms() {
+ if (typeof(window.Modernizr) !== 'undefined') {
+ return Modernizr.csstransforms;
+ }
+
+ var props = [ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ];
+ for ( var i in props ) {
+ if ( m_style[ props[i] ] !== undefined ) {
+ return true;
+ }
+ }
+ }
+
+ // Capture some basic properties
+ var vendorPrefix = getVendorPrefix(),
+ transformProperty = vendorPrefix !== null ? vendorPrefix + 'transform' : false,
+ transformOriginProperty = vendorPrefix !== null ? vendorPrefix + 'transform-origin' : false;
+
+ // store support in the jQuery Support object
+ $.support.csstransforms = supportCssTransforms();
+
+ /**
+ * Class for creating cross-browser transformations
+ * @constructor
+ */
+ $.extend({
+ transform: function(elem) {
+ // Cache the transform object on the element itself
+ elem.transform = this;
+
+ /**
+ * The element we're working with
+ * @var jQueryCollection
+ */
+ this.$elem = $(elem);
+
+ /**
+ * Remember the matrix we're applying to help the safeOuterLength func
+ */
+ this.applyingMatrix = false;
+ this.matrix = null;
+
+ /**
+ * Remember the css height and width to save time
+ * This is only really used in IE
+ * @var Number
+ */
+ this.height = null;
+ this.width = null;
+ this.outerHeight = null;
+ this.outerWidth = null;
+
+ /**
+ * We need to know the box-sizing in IE for building the outerHeight and outerWidth
+ * @var string
+ */
+ this.boxSizingValue = null;
+ this.boxSizingProperty = null;
+
+ this.attr = null;
+ this.transformProperty = transformProperty;
+ this.transformOriginProperty = transformOriginProperty;
+ }
+ });
+
+ $.extend($.transform, {
+ /**
+ * @var Array list of all valid transform functions
+ */
+ funcs: ['matrix', 'origin', 'reflect', 'reflectX', 'reflectXY', 'reflectY', 'rotate', 'scale', 'scaleX', 'scaleY', 'skew', 'skewX', 'skewY', 'translate', 'translateX', 'translateY'],
+
+ rfunc: {
+ /**
+ * @var Regex identifies functions that require an angle unit
+ */
+ angle: /^rotate|skew[X|Y]?$/,
+
+ /**
+ * @var Regex identifies functions that require a length unit
+ */
+ length: /^origin|translate[X|Y]?$/,
+
+ /**
+ * @var Regex identifies functions that do not require a unit
+ */
+ scale: /^scale[X|Y]?$/,
+
+ /**
+ * @var Regex reflection functions
+ */
+ reflect: /^reflect(XY|X|Y)?$/
+ }
+ });
+
+ /**
+ * Create Transform as a jQuery plugin
+ * @param Object funcs
+ * @param Object options
+ */
+ $.fn.transform = function(funcs, options) {
+ return this.each(function() {
+ var t = this.transform || new $.transform(this);
+ if (funcs) {
+ t.exec(funcs, options);
+ }
+ });
+ };
+
+ $.transform.prototype = {
+ /**
+ * Applies all of the transformations
+ * @param Object funcs
+ * @param Object options
+ * forceMatrix - uses the matrix in all browsers
+ * preserve - tries to preserve the values from previous runs
+ */
+ exec: function(funcs, options) {
+ // extend options
+ options = $.extend(true, {
+ forceMatrix: false,
+ preserve: false
+ }, options);
+
+ // preserve the funcs from the previous run
+ this.attr = null;
+ if (options.preserve) {
+ funcs = $.extend(true, this.getAttrs(true, true), funcs);
+ } else {
+ funcs = $.extend(true, {}, funcs); // copy the object to prevent weirdness
+ }
+
+ // Record the custom attributes on the element itself (helps out
+ // the animator)
+ this.setAttrs(funcs);
+
+ // apply the funcs
+ if ($.support.csstransforms && !options.forceMatrix) {
+ // CSS3 is supported
+ return this.execFuncs(funcs);
+ } else if ($.browser.msie || ($.support.csstransforms && options.forceMatrix)) {
+ // Internet Explorer or Forced matrix
+ return this.execMatrix(funcs);
+ }
+ return false;
+ },
+
+ /**
+ * Applies all of the transformations as functions
+ * @param Object funcs
+ */
+ execFuncs: function(funcs) {
+ var values = [];
+
+ // construct a CSS string
+ for (var func in funcs) {
+ // handle origin separately
+ if (func == 'origin') {
+ this[func].apply(this, $.isArray(funcs[func]) ? funcs[func] : [funcs[func]]);
+ } else if ($.inArray(func, $.transform.funcs) != -1) {
+ values.push(this.createTransformFunc(func, funcs[func]));
+ }
+ }
+ this.$elem.css(transformProperty, values.join(' '));
+ return true;
+ },
+
+ /**
+ * Applies all of the transformations as a matrix
+ * @param Object funcs
+ */
+ execMatrix: function(funcs) {
+ var matrix,
+ tempMatrix,
+ args;
+
+ for (var func in funcs) {
+ if ($.matrix[func]) {
+ args = $.isArray(funcs[func]) ? funcs[func] : [funcs[func]];
+
+ // strip the units
+ // TODO: should probably convert the units properly instead of just stripping them
+ args = $.map(args, stripUnits);
+
+ // TODO: translation and origin should be applied last
+ // TODO: should hold translations until the extreme end
+ tempMatrix = $.matrix[func].apply(this, args);
+ matrix = matrix ? matrix.x(tempMatrix) : tempMatrix;
+ } else if (func == 'origin') {
+ //TODO: this is a dumb way to handle the origin for a matrix
+ args = $.isArray(funcs[func]) ? funcs[func] : [funcs[func]];
+ this[func].apply(this, args);
+ }
+ }
+
+ // check that we have a matrix
+ // TODO: This will result in a filter being needlessly set in IE
+ matrix = matrix || $.matrix.identity();
+
+ // pull out the relevant values
+ var a = parseFloat(matrix.e(1,1).toFixed(6)),
+ b = parseFloat(matrix.e(2,1).toFixed(6)),
+ c = parseFloat(matrix.e(1,2).toFixed(6)),
+ d = parseFloat(matrix.e(2,2).toFixed(6)),
+ tx = matrix.rows === 3 ? parseFloat(matrix.e(1,3).toFixed(6)) : 0,
+ ty = matrix.rows === 3 ? parseFloat(matrix.e(2,3).toFixed(6)) : 0;
+
+ //apply the transform to the element
+ if ($.support.csstransforms && vendorPrefix === '-moz-') {
+ // -moz-
+ this.$elem.css(transformProperty, 'matrix(' + a + ', ' + b + ', ' + c + ', ' + d + ', ' + tx + 'px, ' + ty + 'px)');
+ } else if ($.support.csstransforms) {
+ // -webkit, -o-, w3c
+ // NOTE: WebKit and Opera don't allow units on the translate variables
+ this.$elem.css(transformProperty, 'matrix(' + a + ', ' + b + ', ' + c + ', ' + d + ', ' + tx + ', ' + ty + ')');
+ } else if ($.browser.msie) {
+ // IE requires the special transform Filter
+
+ //TODO: Use Nearest Neighbor during animation FilterType=\'nearest neighbor\'
+ var filterType = ', FilterType=\'nearest neighbor\''; //bilinear
+ var style = this.$elem[0].style;
+ var matrixFilter = 'progid:DXImageTransform.Microsoft.Matrix(' +
+ 'M11=' + a + ', M12=' + c + ', M21=' + b + ', M22=' + d +
+ ', sizingMethod=\'auto expand\'' + filterType + ')';
+ var filter = style.filter || jQuery.curCSS( this.$elem[0], "filter" ) || "";
+ style.filter = rmatrix.test(filter) ? filter.replace(rmatrix, matrixFilter) : filter ? filter + ' ' + matrixFilter : matrixFilter;
+
+ // Let's know that we're applying post matrix fixes and the height/width will be static for a bit
+ this.applyingMatrix = true;
+ this.matrix = matrix;
+
+ // IE can't set the origin or translate directly
+ this.fixPosition(matrix, tx, ty);
+
+ this.applyingMatrix = false;
+ this.matrix = null;
+ }
+ return true;
+ },
+
+ /**
+ * Sets the transform-origin
+ * This really needs to be percentages
+ * @param Number x length
+ * @param Number y length
+ */
+ origin: function(x, y) {
+ // use CSS in supported browsers
+ if ($.support.csstransforms) {
+ if (typeof y === 'undefined') {
+ this.$elem.css(transformOriginProperty, x);
+ } else {
+ this.$elem.css(transformOriginProperty, x + ' ' + y);
+ }
+ return true;
+ }
+
+ // correct for keyword lengths
+ switch (x) {
+ case 'left': x = '0'; break;
+ case 'right': x = '100%'; break;
+ case 'center': // no break
+ case undefined: x = '50%';
+ }
+ switch (y) {
+ case 'top': y = '0'; break;
+ case 'bottom': y = '100%'; break;
+ case 'center': // no break
+ case undefined: y = '50%'; //TODO: does this work?
+ }
+
+ // store percentages directly
+ if (/%/.test(x) && /%/.test(y)) {
+ this.setAttr('origin', [x, y]);
+ return true;
+ }
+
+ // store mixed values with units, assumed pixels
+ this.setAttr('origin', [
+ /%/.test(x) ? x : parseFloat(x) + 'px',
+ /%/.test(y) ? y : parseFloat(y) + 'px'
+ ]);
+ return true;
+ },
+
+ /**
+ * Create a function suitable for a CSS value
+ * @param string func
+ * @param Mixed value
+ */
+ createTransformFunc: function(func, value) {
+ if ($.transform.rfunc.reflect.test(func)) {
+ // let's fake reflection
+ // TODO: why would value be false?
+ var matrix = value ? $.matrix[func]() : $.matrix.identity(),
+ a = matrix.e(1,1),
+ b = matrix.e(2,1),
+ c = matrix.e(1,2),
+ d = matrix.e(2,2);
+ return 'matrix(' + a + ', ' + b + ', ' + c + ', ' + d + ', 0, 0)';
+ }
+
+ value = _correctUnits(func, value);
+
+ if (!$.isArray(value)) {
+ return func + '(' + value + ')';
+ } else if (func == 'matrix') {
+ if (vendorPrefix === '-moz-' && value[4]) {
+ value[4] = value[4] +'px';
+ }
+ if (vendorPrefix === '-moz-' && value[5]) {
+ value[5] = value[5] +'px';
+ }
+ return 'matrix(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + value[3] + ', ' + (value[4] || 0) + ', ' + (value[5] || 0) + ')';
+ } else {
+ return func + '(' + value[0] + ', ' + value[1] + ')';
+ }
+ },
+
+ /**
+ * @param Matrix matrix
+ * @param Number tx
+ * @param Number ty
+ * @param Number height
+ * @param Number width
+ */
+ fixPosition: function(matrix, tx, ty, height, width) {
+ // now we need to fix it!
+ var calc = new $.matrix.calc(matrix, this.safeOuterHeight(), this.safeOuterWidth()),
+ origin = this.getAttr('origin'); // mixed percentages and px
+
+ // translate a 0, 0 origin to the current origin
+ var offset = calc.originOffset(new $.matrix.V2(
+ /%/.test(origin[0]) ? parseFloat(origin[0])/100*calc.outerWidth : parseFloat(origin[0]),
+ /%/.test(origin[1]) ? parseFloat(origin[1])/100*calc.outerHeight : parseFloat(origin[1])
+ ));
+
+ // IE glues the top-most and left-most pixels of the transformed object to top/left of the original object
+ //TODO: This seems wrong in the calculations
+ var sides = calc.sides();
+
+ // Protect against an item that is already positioned
+ var cssPosition = this.$elem.css('position');
+ if (cssPosition == 'static') {
+ cssPosition = 'relative';
+ }
+
+ //TODO: if the element is already positioned, we should attempt to respect it (somehow)
+ //NOTE: we could preserve our offset top and left in an attr on the elem
+ var pos = {top: 0, left: 0};
+
+ // Approximates transform-origin, tx, and ty
+ var css = {
+ 'position': cssPosition,
+ 'top': (offset.top + ty + sides.top + pos.top) + 'px',
+ 'left': (offset.left + tx + sides.left + pos.left) + 'px',
+ 'zoom': 1
+ };
+
+ this.$elem.css(css);
+ }
+ };
+
+ /**
+ * Ensure that values have the appropriate units on them
+ * @param string func
+ * @param Mixed value
+ */
+ var rfxnum = /^([\+\-]=)?([\d+.\-]+)(.*)$/;
+ function _correctUnits(func, value) {
+ var result = !$.isArray(value)? [value] : value,
+ rangle = $.transform.rfunc.angle,
+ rlength = $.transform.rfunc.length;
+
+ for (var i = 0, len = result.length; i < len; i++) {
+ var parts = rfxnum.exec(result[i]),
+ unit = '';
+
+ // Use an appropriate unit
+ if (rangle.test(func)) {
+ unit = 'deg';
+
+ // remove nonsense units
+ if (parts[3] && !$.angle.runit.test(parts[3])) {
+ parts[3] = null;
+ }
+ } else if (rlength.test(func)) {
+ unit = 'px';
+ }
+
+ // ensure a value and appropriate unit
+ if (!parts) {
+ result[i] = 0 + unit;
+ } else if(!parts[3]) {
+ result[i] += unit;
+ }
+
+ }
+ return len == 1 ? result[0] : result;
+ }
+})(jQuery, this, this.document);
+
+
+///////////////////////////////////////////////////////
+// Safe Outer Length
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ $.extend($.transform.prototype, {
+ /**
+ * @param void
+ * @return Number
+ */
+ safeOuterHeight: function() {
+ return this.safeOuterLength('height');
+ },
+
+ /**
+ * @param void
+ * @return Number
+ */
+ safeOuterWidth: function() {
+ return this.safeOuterLength('width');
+ },
+
+ /**
+ * Returns reliable outer dimensions for an object that may have been transformed.
+ * Only use this if the matrix isn't handy
+ * @param String dim height or width
+ * @return Number
+ */
+ safeOuterLength: function(dim) {
+ var funcName = 'outer' + (dim == 'width' ? 'Width' : 'Height');
+
+ if ($.browser.msie) {
+ // make the variables more generic
+ dim = dim == 'width' ? 'width' : 'height';
+
+ // if we're transforming and have a matrix; we can shortcut.
+ // the true outerHeight is the transformed outerHeight divided by the ratio.
+ // the ratio is equal to the height of a 1px by 1px box that has been transformed by the same matrix.
+ if (this.applyingMatrix && !this[funcName] && this.matrix) {
+ // calculate and return the correct size
+ var calc = new $.matrix.calc(this.matrix, 1, 1),
+ ratio = calc.offset(),
+ length = this.$elem[funcName]() / ratio[dim];
+ this[funcName] = length;
+
+ return length;
+ } else if (this.applyingMatrix && this[funcName]) {
+ // return the cached calculation
+ return this[funcName];
+ }
+
+ // map dimensions to box sides
+ var side = {
+ height: ['top', 'bottom'],
+ width: ['left', 'right']
+ };
+
+ // setup some variables
+ var elem = this.$elem[0],
+ outerLen = parseFloat($.curCSS(elem, dim, true)), //TODO: this can be cached on animations that do not animate height/width
+ boxSizingProp = this.boxSizingProperty,
+ boxSizingValue = this.boxSizingValue;
+
+ // IE6 && IE7 will never have a box-sizing property, so fake it
+ if (!this.boxSizingProperty) {
+ boxSizingProp = this.boxSizingProperty = _findBoxSizingProperty() || 'box-sizing';
+ boxSizingValue = this.boxSizingValue = this.$elem.css(boxSizingProp) || 'content-box';
+ }
+
+ // return it immediately if we already know it
+ if (this[funcName] && this[dim] == outerLen) {
+ return this[funcName];
+ } else {
+ this[dim] = outerLen;
+ }
+
+ // add in the padding and border
+ if (boxSizingProp && (boxSizingValue == 'padding-box' || boxSizingValue == 'content-box')) {
+ outerLen += parseFloat($.curCSS(elem, 'padding-' + side[dim][0], true)) || 0 +
+ parseFloat($.curCSS(elem, 'padding-' + side[dim][1], true)) || 0;
+ }
+ if (boxSizingProp && boxSizingValue == 'content-box') {
+ outerLen += parseFloat($.curCSS(elem, 'border-' + side[dim][0] + '-width', true)) || 0 +
+ parseFloat($.curCSS(elem, 'border-' + side[dim][1] + '-width', true)) || 0;
+ }
+
+ // remember and return the outerHeight
+ this[funcName] = outerLen;
+ return outerLen;
+ }
+ return this.$elem[funcName]();
+ }
+ });
+
+ /**
+ * Determine the correct property for checking the box-sizing property
+ * @param void
+ * @return string
+ */
+ var _boxSizingProperty = null;
+ function _findBoxSizingProperty () {
+ if (_boxSizingProperty) {
+ return _boxSizingProperty;
+ }
+
+ var property = {
+ boxSizing : 'box-sizing',
+ MozBoxSizing : '-moz-box-sizing',
+ WebkitBoxSizing : '-webkit-box-sizing',
+ OBoxSizing : '-o-box-sizing'
+ },
+ elem = document.body;
+
+ for (var p in property) {
+ if (typeof elem.style[p] != 'undefined') {
+ _boxSizingProperty = property[p];
+ return _boxSizingProperty;
+ }
+ }
+ return null;
+ }
+})(jQuery, this, this.document);
+
+
+///////////////////////////////////////////////////////
+// Attr
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ var rfuncvalue = /([\w\-]*?)\((.*?)\)/g, // with values
+ attr = 'data-transform',
+ rspace = /\s/,
+ rcspace = /,\s/;
+
+ $.extend($.transform.prototype, {
+ /**
+ * This overrides all of the attributes
+ * @param Object funcs a list of transform functions to store on this element
+ * @return void
+ */
+ setAttrs: function(funcs) {
+ var string = '',
+ value;
+ for (var func in funcs) {
+ value = funcs[func];
+ if ($.isArray(value)) {
+ value = value.join(', ');
+ }
+ string += ' ' + func + '(' + value + ')';
+ }
+ this.attr = $.trim(string);
+ this.$elem.attr(attr, this.attr);
+ },
+
+ /**
+ * This sets only a specific atribute
+ * @param string func name of a transform function
+ * @param mixed value with proper units
+ * @return void
+ */
+ setAttr: function(func, value) {
+ // stringify the value
+ if ($.isArray(value)) {
+ value = value.join(', ');
+ }
+ value = $.trim(value+'');
+
+ // pull from a local variable to look it up
+ var transform = this.attr || this.$elem.attr(attr);
+
+ if (!transform || transform.indexOf(func) > -1) {
+ // We don't have any existing values, save it
+ // we don't have this function yet, save it
+ this.attr = $.trim(transform + ' ' + func + '(' + value + ')');
+ this.$elem.attr(attr, this.attr);
+ } else {
+ // replace the existing value
+ var funcs = [], parts;
+
+ // regex split
+ rfuncvalue.lastIndex = 0; // reset the regex pointer
+ while ((result = rfuncvalue.exec(transform)) !== null) {
+ if (func == parts[1]) {
+ funcs.push(func + '(' + value + ')');
+ } else {
+ funcs.push(parts[0]);
+ }
+ }
+ this.attr = funcs.join(' ');
+ this.$elem.attr(attr, this.attr);
+ }
+ },
+
+ /**
+ * @return Object
+ */
+ getAttrs: function() {
+ var transform = this.attr || this.$elem.attr(attr);
+ if (!transform) {
+ // We don't have any existing values, return empty object
+ return {};
+ }
+
+ // replace the existing value
+ var attrs = {}, parts, value;
+
+ rfuncvalue.lastIndex = 0; // reset the regex pointer
+ while ((parts = rfuncvalue.exec(transform)) !== null) {
+ if (parts) {
+ value = parts[2].split(rcspace);
+ attrs[parts[1]] = value.length == 1 ? value[0] : value;
+ }
+ }
+ return attrs;
+ },
+
+ /**
+ * @param String func
+ * @return mixed
+ */
+ getAttr: function(func) {
+ var attrs = this.getAttrs();
+
+ if (typeof attrs[func] !== 'undefined') {
+ return attrs[func];
+ }
+
+ // animate needs sensible defaults for some props
+ switch (func) {
+ case 'scale': return [1, 1];
+ case 'scaleX': // no break;
+ case 'scaleY': return 1;
+ case 'matrix': return [1, 0, 0, 1, 0, 0];
+ case 'origin':
+ if ($.support.csstransforms) {
+ // supported browsers return percentages always
+ return this.$elem.css(this.transformOriginProperty).split(rspace);
+ } else {
+ // just force IE to also return a percentage
+ return ['50%', '50%'];
+ }
+ }
+ return null;
+ }
+ });
+})(jQuery, this, this.document);
+///////////////////////////////////////////////////////
+// Animation
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ // Extend the jQuery animation to handle transform functions
+ /**
+ * @var Regex looks for units on a string
+ */
+ var rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/;
+
+ /**
+ * @var Regex identify if additional values are hidden in the unit
+ */
+ var rfxmultinum = /^(.*?)\s+([+\-]=)?([\d+.\-]+)(.*)$/;
+
+ /**
+ * Doctors prop values in the event that they contain spaces
+ * @param Object prop
+ * @param String speed
+ * @param String easing
+ * @param Function callback
+ * @return bool
+ */
+ var _animate = $.fn.animate;
+ $.fn.animate = function( prop, speed, easing, callback ) {
+ //NOTE: The $.fn.animate() function is a big jerk and requires
+ // you to attempt to convert the values passed into pixels.
+ // So we have to doctor the values passed in here to make
+ // sure $.fn.animate() won't think there's units an ruin
+ // our fun.
+ if (prop && !jQuery.isEmptyObject(prop)) {
+ var $elem = this;
+ jQuery.each( prop, function( name, val ) {
+ // Clean up the numbers for space-sperated prop values
+ if ($.inArray(name, $.transform.funcs) != -1) {
+ // allow for reflection animation
+ if ($.transform.rfunc.reflect.test(name)) {
+ var m = val ? $.matrix[name]() : $.matrix.identity(),
+ e = m.elements;
+ val = [e[0], e[1], e[2], e[3]];
+ }
+
+ var parts = rfxnum.exec(val);
+
+ if ((parts && parts[3]) || $.isArray(val)) {
+ // Either a unit was found or an array was passed
+ var end, unit, values = [];
+
+ if ($.isArray(val)) {
+ // An array was passed
+ $.each(val, function(i) {
+ parts = rfxnum.exec(this);
+ end = parseFloat(parts[2]);
+ unit = parts[3] || "px";
+
+ // Remember value
+ values.push({
+ end: (parts[1] ? parts[1] : '') + end,
+ unit: unit
+ });
+ });
+ } else {
+ // A unit was found
+ end = parseFloat( parts[2] );
+ unit = parts[3] || "px";
+
+ // Remember the first value
+ values.push({
+ end: (parts[1] ? parts[1] : '') + end,
+ unit: unit
+ });
+
+ // Detect additional values hidden in the unit
+ var i = 0;
+ while (parts = rfxmultinum.exec(unit)) {
+ // Fix the previous unit
+ values[i].unit = parts[1];
+
+ // Remember this value
+ values.push({
+ end: (parts[2] ? parts[2] : '') + parseFloat(parts[3]),
+ unit: parts[4]
+ });
+ unit = parts[4];
+ i++;
+ }
+ }
+
+ // Save the values and truncate the value to make it safe to animate
+ $elem.data('data-animate-' + name, values);
+ prop[name] = values[0].end; // NOTE: this propegates into the arguments object
+ }
+ }
+ });
+ }
+ //NOTE: we edit prop above
+ return _animate.apply(this, arguments);
+ };
+
+ /**
+ * Returns appropriate start value for transform props
+ * @param Boolean force
+ * @return Number
+ */
+ var _cur = $.fx.prototype.cur;
+ $.fx.prototype.cur = function(force) {
+ //NOTE: The cur function tries to look things up on the element
+ // itself as a native property first instead of as a style
+ // property. However, the animate function is a big jerk
+ // and it's extremely easy to poison the element.style
+ // with a random property and ruin all of the fun. So, it's
+ // easier to just look it up ourselves.
+ if ($.inArray(this.prop, $.transform.funcs) != -1) {
+ this.transform = this.transform || this.elem.transform || new $.transform(this.elem);
+ var r = $.transform.rfunc;
+
+ // return a single unitless number and animation will play nice
+ var value = this.transform.getAttr(this.prop),
+ parts = rfxnum.exec($.isArray(value) ? value[0] : value);
+ if (value === null || parts === null) {
+ value = r.scale.test(this.prop) || r.reflect.test(this.prop) ? 1 : 0;
+ parts = [null, null, value];
+ }
+ return parseFloat(parts[2]);
+ }
+ return _cur.apply(this, arguments);
+ };
+
+ /**
+ * Detects the existence of a space separated value
+ * @param Object fx
+ * @return null
+ */
+ $.fx.multivalueInit = function(fx) {
+ var $elem = $(fx.elem),
+ values = fx.transform.getAttr(fx.prop), // existing values
+ initValues = $elem.data('data-animate-' + fx.prop); // new values passed into animate
+
+ if (initValues) {
+ $elem.removeData('data-animate-' + fx.prop); // unremember the saved property
+ }
+
+ if ($.transform.rfunc.reflect.test(fx.prop)) {
+ values = fx.transform.getAttr('matrix');
+ }
+
+ fx.values = [];
+
+ // If we found a previous array but we're only setting one value, we need to set both
+ if ($.isArray(values) && !$.isArray(initValues)) {
+ initValues = [
+ {
+ end: parseFloat(fx.end),
+ unit: fx.unit
+ },
+ {
+ end: $.transform.rfunc.scale.test(fx.prop) ? 1 : 0,
+ unit: fx.unit
+ }
+ ];
+ }
+
+ // If we altered the values before
+ // This happens in the doctored animate function when we pass a unit or multiple values
+ if (initValues) {
+ var start,
+ rscalefunc = $.transform.rfunc.scale,
+ parts;
+ $.each(initValues, function(i, val) {
+ // pull out the start value
+ if ($.isArray(values)) {
+ start = values[i];
+ } else if (i > 0) {
+ // scale duplicates the values for x and y
+ start = rscalefunc.test(fx.prop) ? values : null;
+ } else {
+ start = values;
+ }
+
+ // if we didn't find a start value
+ if (!start && start !== 0) {
+ start = rscalefunc.test(fx.prop) ? 1 : 0;
+ }
+
+ // ensure a number
+ start = parseFloat(start);
+
+ // handle the existence of += and -= prefixes
+ parts = rfxnum.exec(val.end);
+ if (parts && parts[1]) {
+ val.end = ((parts[1] === "-=" ? -1 : 1) * parseFloat(parts[2])) + start;
+ }
+
+ // Save the values
+ fx.values.push({
+ start: parseFloat(start),
+ end: parseFloat(val.end),
+ unit: val.unit
+ });
+ });
+ } else {
+ // Save the known value
+ fx.values.push({
+ start: parseFloat(fx.start),
+ end: parseFloat(fx.end), // force a Number
+ unit: fx.unit
+ });
+ }
+ };
+
+ /**
+ * Animates a multi value attribute
+ * @param Object fx
+ * @return null
+ */
+ $.fx.multivalueStep = {
+ _default: function(fx) {
+ $.each(fx.values, function(i, val) {
+ fx.values[i].now = val.start + ((val.end - val.start) * fx.pos);
+ });
+ }
+ };
+
+ /**
+ * Step for animating tranformations
+ */
+ $.each($.transform.funcs, function(i, func) {
+ $.fx.step[func] = function(fx) {
+ // Initialize the transformation
+ if (!fx.transformInit) {
+ fx.transform = fx.transform || fx.elem.transform || new $.transform(fx.elem);
+
+ // Handle multiple values
+ $.fx.multivalueInit(fx);
+ if (fx.values.length > 1) {
+ fx.multiple = true;
+ }
+
+ // Force degrees for angles, Remove units for unitless
+ var r = $.transform.rfunc;
+ if (r.angle.test(fx.prop)) {
+ //TODO: we should convert from other rational units
+ fx.unit = 'deg';
+ } else if (r.scale.test(fx.prop)) {
+ fx.unit = '';
+ } else if (r.reflect.test(fx.prop)) {
+ //TODO: for animation purposes, this is a matrix and can be animated (although it looks silly)
+ fx.unit = ''; //this is a boolean func
+ } else if (fx.prop == 'matrix') {
+ fx.unit = '';
+ }
+ //TODO: I guess we already foced length units earlier
+
+ // Force all units on multiple values to be the same
+ //TODO: we should convert from other rational units
+ $.each(fx.values, function(i) {fx.values[i].unit = fx.unit;});
+
+ fx.transformInit = true;
+ }
+
+
+ // Increment all of the values
+ if (fx.multiple) {
+ ($.fx.multivalueStep[fx.prop] || $.fx.multivalueStep._default)(fx);
+ } else {
+ fx.values[0].now = fx.now;
+ }
+
+ var values = [];
+
+ // Do some value correction and join the values
+ $.each(fx.values, function(i, value) {
+ // Keep angles below 360 in either direction.
+ if (value.unit == 'deg') {
+ while (value.now >= 360 ) {
+ value.now -= 360;
+ }
+ while (value.now <= -360 ) {
+ value.now += 360;
+ }
+ }
+ // TODO: handle reflection matrices here
+
+ //Pretty up the final value (use the double parseFloat
+ // to correct super small decimals)
+ values.push(parseFloat(parseFloat(value.now).toFixed(8)) + value.unit);
+ });
+
+ // Apply the transformation
+ var funcs = {},
+ prop = $.transform.rfunc.reflect.test(fx.prop) ? 'matrix' : fx.prop;
+
+ funcs[prop] = fx.multiple ? values : values[0];
+ fx.transform.exec(funcs, {preserve: true});
+ };
+ });
+})(jQuery, this, this.document);
+///////////////////////////////////////////////////////
+// Angle
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ /**
+ * Converting a radian to a degree
+ * @const
+ */
+ var RAD_DEG = 180/Math.PI;
+
+ /**
+ * Converting a radian to a grad
+ * @const
+ */
+ var RAD_GRAD = 200/Math.PI;
+
+ /**
+ * Converting a degree to a radian
+ * @const
+ */
+ var DEG_RAD = Math.PI/180;
+
+ /**
+ * Converting a degree to a grad
+ * @const
+ */
+ var DEG_GRAD = 2/1.8;
+
+ /**
+ * Converting a grad to a degree
+ * @const
+ */
+ var GRAD_DEG = 0.9;
+
+ /**
+ * Converting a grad to a radian
+ * @const
+ */
+ var GRAD_RAD = Math.PI/200;
+
+ /**
+ * Functions for converting angles
+ * @var Object
+ */
+ $.extend({
+ angle: {
+ /**
+ * available units for an angle
+ * @var Regex
+ */
+ runit: /(deg|g?rad)/,
+
+ /**
+ * Convert a radian into a degree
+ * @param Number rad
+ * @return Number
+ */
+ radianToDegree: function(rad) {
+ return rad * RAD_DEG;
+ },
+
+ /**
+ * Convert a radian into a degree
+ * @param Number rad
+ * @return Number
+ */
+ radianToGrad: function(rad) {
+ return rad * RAD_GRAD;
+ },
+
+ /**
+ * Convert a degree into a radian
+ * @param Number deg
+ * @return Number
+ */
+ degreeToRadian: function(deg) {
+ return deg * DEG_RAD;
+ },
+
+ /**
+ * Convert a degree into a radian
+ * @param Number deg
+ * @return Number
+ */
+ degreeToGrad: function(deg) {
+ return deg * DEG_GRAD;
+ },
+
+ /**
+ * Convert a grad into a degree
+ * @param Number grad
+ * @return Number
+ */
+ gradToDegree: function(grad) {
+ return grad * GRAD_DEG;
+ },
+
+ /**
+ * Convert a grad into a radian
+ * @param Number grad
+ * @return Number
+ */
+ gradToRadian: function(grad) {
+ return grad * GRAD_RAD;
+ }
+ }
+ });
+})(jQuery, this, this.document);
+///////////////////////////////////////////////////////
+// Matrix
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ /**
+ * Matrix object for creating matrices relevant for 2d Transformations
+ * @var Object
+ */
+ if (typeof($.matrix) == 'undefined') {
+ $.extend({
+ matrix: {}
+ });
+ }
+
+ $.extend( $.matrix, {
+ /**
+ * A 2-value vector
+ * @param Number x
+ * @param Number y
+ * @constructor
+ */
+ V2: function(x, y){
+ if ($.isArray(arguments[0])) {
+ this.elements = arguments[0].slice(0, 2);
+ } else {
+ this.elements = [x, y];
+ }
+ this.length = 2;
+ },
+
+ /**
+ * A 2-value vector
+ * @param Number x
+ * @param Number y
+ * @param Number z
+ * @constructor
+ */
+ V3: function(x, y, z){
+ if ($.isArray(arguments[0])) {
+ this.elements = arguments[0].slice(0, 3);
+ } else {
+ this.elements = [x, y, z];
+ }
+ this.length = 3;
+ },
+
+ /**
+ * A 2x2 Matrix, useful for 2D-transformations without translations
+ * @param Number mn
+ * @constructor
+ */
+ M2x2: function(m11, m12, m21, m22) {
+ if ($.isArray(arguments[0])) {
+ this.elements = arguments[0].slice(0, 4);
+ } else {
+ this.elements = Array.prototype.slice.call(arguments).slice(0, 4);
+ }
+ this.rows = 2;
+ this.cols = 2;
+ },
+
+ /**
+ * A 3x3 Matrix, useful for 3D-transformations without translations
+ * @param Number mn
+ * @constructor
+ */
+ M3x3: function(m11, m12, m13, m21, m22, m23, m31, m32, m33) {
+ if ($.isArray(arguments[0])) {
+ this.elements = arguments[0].slice(0, 9);
+ } else {
+ this.elements = Array.prototype.slice.call(arguments).slice(0, 9);
+ }
+ this.rows = 3;
+ this.cols = 3;
+ }
+ });
+
+ /** generic matrix prototype */
+ var Matrix = {
+ /**
+ * Return a specific element from the matrix
+ * @param Number row where 1 is the 0th row
+ * @param Number col where 1 is the 0th column
+ * @return Number
+ */
+ e: function(row, col) {
+ var rows = this.rows,
+ cols = this.cols;
+
+ // return 0 on nonsense rows and columns
+ if (row > rows || col > rows || row < 1 || col < 1) {
+ return 0;
+ }
+
+ return this.elements[(row - 1) * cols + col - 1];
+ }
+ };
+
+ /** Extend all of the matrix types with the same prototype */
+ $.extend($.matrix.M2x2.prototype, Matrix, {
+ toM3x3: function() {
+ var a = this.elements;
+ return new $.matrix.M3x3(
+ a[0], a[1], 0,
+ a[2], a[3], 0,
+ 0, 0, 1
+ );
+ },
+
+ /**
+ * Multiply a 2x2 matrix by a similar matrix or a vector
+ * @param M2x2 | V2 matrix
+ * @return M2x2 | V2
+ */
+ x: function(matrix) {
+ var isVector = typeof(matrix.rows) === 'undefined';
+
+ // Ensure the right-sized matrix
+ if (!isVector && matrix.rows == 3) {
+ return this.toM3x3().x(matrix);
+ }
+
+ var a = this.elements,
+ b = matrix.elements;
+
+ if (isVector && b.length == 2) {
+ // b is actually a vector
+ return new $.matrix.V2(
+ a[0] * b[0] + a[1] * b[1],
+ a[2] * b[0] + a[3] * b[1]
+ );
+ } else if (b.length == a.length) {
+ // b is a 2x2 matrix
+ return new $.matrix.M2x2(
+ a[0] * b[0] + a[1] * b[2],
+ a[0] * b[1] + a[1] * b[3],
+
+ a[2] * b[0] + a[3] * b[2],
+ a[2] * b[1] + a[3] * b[3]
+ );
+ }
+ return false; // fail
+ },
+
+ /**
+ * Generates an inverse of the current matrix
+ * @param void
+ * @return M2x2
+ * @link http://www.dr-lex.be/random/matrix_inv.html
+ */
+ inverse: function() {
+ var d = 1/this.determinant(),
+ a = this.elements;
+ return new $.matrix.M2x2(
+ d * a[3], d * -a[1],
+ d * -a[2], d * a[0]
+ );
+ },
+
+ /**
+ * Calculates the determinant of the current matrix
+ * @param void
+ * @return Number
+ * @link http://www.dr-lex.be/random/matrix_inv.html
+ */
+ determinant: function() {
+ var a = this.elements;
+ return a[0] * a[3] - a[1] * a[2];
+ }
+ });
+
+ $.extend($.matrix.M3x3.prototype, Matrix, {
+ /**
+ * Multiply a 3x3 matrix by a similar matrix or a vector
+ * @param M3x3 | V3 matrix
+ * @return M3x3 | V3
+ */
+ x: function(matrix) {
+ var isVector = typeof(matrix.rows) === 'undefined';
+
+ // Ensure the right-sized matrix
+ if (!isVector && matrix.rows < 3) {
+ matrix = matrix.toM3x3();
+ }
+
+ var a = this.elements,
+ b = matrix.elements;
+
+ if (isVector && b.length == 3) {
+ // b is actually a vector
+ return new $.matrix.V3(
+ a[0] * b[0] + a[1] * b[1] + a[2] * b[2],
+ a[3] * b[0] + a[4] * b[1] + a[5] * b[2],
+ a[6] * b[0] + a[7] * b[1] + a[8] * b[2]
+ );
+ } else if (b.length == a.length) {
+ // b is a 3x3 matrix
+ return new $.matrix.M3x3(
+ a[0] * b[0] + a[1] * b[3] + a[2] * b[6],
+ a[0] * b[1] + a[1] * b[4] + a[2] * b[7],
+ a[0] * b[2] + a[1] * b[5] + a[2] * b[8],
+
+ a[3] * b[0] + a[4] * b[3] + a[5] * b[6],
+ a[3] * b[1] + a[4] * b[4] + a[5] * b[7],
+ a[3] * b[2] + a[4] * b[5] + a[5] * b[8],
+
+ a[6] * b[0] + a[7] * b[3] + a[8] * b[6],
+ a[6] * b[1] + a[7] * b[4] + a[8] * b[7],
+ a[6] * b[2] + a[7] * b[5] + a[8] * b[8]
+ );
+ }
+ return false; // fail
+ },
+
+ /**
+ * Generates an inverse of the current matrix
+ * @param void
+ * @return M3x3
+ * @link http://www.dr-lex.be/random/matrix_inv.html
+ */
+ inverse: function() {
+ var d = 1/this.determinant(),
+ a = this.elements;
+ return new $.matrix.M3x3(
+ d * ( a[8] * a[4] - a[7] * a[5]),
+ d * (-(a[8] * a[1] - a[7] * a[2])),
+ d * ( a[5] * a[1] - a[4] * a[2]),
+
+ d * (-(a[8] * a[3] - a[6] * a[5])),
+ d * ( a[8] * a[0] - a[6] * a[2]),
+ d * (-(a[5] * a[0] - a[3] * a[2])),
+
+ d * ( a[7] * a[3] - a[6] * a[4]),
+ d * (-(a[7] * a[0] - a[6] * a[1])),
+ d * ( a[4] * a[0] - a[3] * a[1])
+ );
+ },
+
+ /**
+ * Calculates the determinant of the current matrix
+ * @param void
+ * @return Number
+ * @link http://www.dr-lex.be/random/matrix_inv.html
+ */
+ determinant: function() {
+ var a = this.elements;
+ return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]);
+ }
+ });
+
+ /** generic vector prototype */
+ var Vector = {
+ /**
+ * Return a specific element from the vector
+ * @param Number i where 1 is the 0th value
+ * @return Number
+ */
+ e: function(i) {
+ return this.elements[i - 1];
+ }
+ };
+
+ /** Extend all of the vector types with the same prototype */
+ $.extend($.matrix.V2.prototype, Vector);
+ $.extend($.matrix.V3.prototype, Vector);
+})(jQuery, this, this.document);
+///////////////////////////////////////////////////////
+// Matrix Calculations
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ /**
+ * Matrix object for creating matrices relevant for 2d Transformations
+ * @var Object
+ */
+ if (typeof($.matrix) == 'undefined') {
+ $.extend({
+ matrix: {}
+ });
+ }
+
+ $.extend( $.matrix, {
+ /**
+ * Class for calculating coordinates on a matrix
+ * @param Matrix matrix
+ * @param Number outerHeight
+ * @param Number outerWidth
+ * @constructor
+ */
+ calc: function(matrix, outerHeight, outerWidth) {
+ /**
+ * @var Matrix
+ */
+ this.matrix = matrix;
+
+ /**
+ * @var Number
+ */
+ this.outerHeight = outerHeight;
+
+ /**
+ * @var Number
+ */
+ this.outerWidth = outerWidth;
+ }
+ });
+
+ $.matrix.calc.prototype = {
+ /**
+ * Calculate a coord on the new object
+ * @return Object
+ */
+ coord: function(x, y, z) {
+ //default z and w
+ z = typeof(z) !== 'undefined' ? z : 0;
+
+ var matrix = this.matrix,
+ vector;
+
+ switch (matrix.rows) {
+ case 2:
+ vector = matrix.x(new $.matrix.V2(x, y));
+ break;
+ case 3:
+ vector = matrix.x(new $.matrix.V3(x, y, z));
+ break;
+ }
+
+ return vector;
+ },
+
+ /**
+ * Calculate the corners of the new object
+ * @return Object
+ */
+ corners: function(x, y) {
+ // Try to save the corners if this is called a lot
+ var save = !(typeof(x) !=='undefined' || typeof(y) !=='undefined'),
+ c;
+ if (!this.c || !save) {
+ y = y || this.outerHeight;
+ x = x || this.outerWidth;
+
+ c = {
+ tl: this.coord(0, 0),
+ bl: this.coord(0, y),
+ tr: this.coord(x, 0),
+ br: this.coord(x, y)
+ };
+ } else {
+ c = this.c;
+ }
+
+ if (save) {
+ this.c = c;
+ }
+ return c;
+ },
+
+ /**
+ * Calculate the sides of the new object
+ * @return Object
+ */
+ sides: function(corners) {
+ // The corners of the box
+ var c = corners || this.corners();
+
+ return {
+ top: Math.min(c.tl.e(2), c.tr.e(2), c.br.e(2), c.bl.e(2)),
+ bottom: Math.max(c.tl.e(2), c.tr.e(2), c.br.e(2), c.bl.e(2)),
+ left: Math.min(c.tl.e(1), c.tr.e(1), c.br.e(1), c.bl.e(1)),
+ right: Math.max(c.tl.e(1), c.tr.e(1), c.br.e(1), c.bl.e(1))
+ };
+ },
+
+ /**
+ * Calculate the offset of the new object
+ * @return Object
+ */
+ offset: function(corners) {
+ // The corners of the box
+ var s = this.sides(corners);
+
+ // return size
+ return {
+ height: Math.abs(s.bottom - s.top),
+ width: Math.abs(s.right - s.left)
+ };
+ },
+
+ /**
+ * Calculate the area of the new object
+ * @return Number
+ * @link http://en.wikipedia.org/wiki/Quadrilateral#Area_of_a_convex_quadrilateral
+ */
+ area: function(corners) {
+ // The corners of the box
+ var c = corners || this.corners();
+
+ // calculate the two diagonal vectors
+ var v1 = {
+ x: c.tr.e(1) - c.tl.e(1) + c.br.e(1) - c.bl.e(1),
+ y: c.tr.e(2) - c.tl.e(2) + c.br.e(2) - c.bl.e(2)
+ },
+ v2 = {
+ x: c.bl.e(1) - c.tl.e(1) + c.br.e(1) - c.tr.e(1),
+ y: c.bl.e(2) - c.tl.e(2) + c.br.e(2) - c.tr.e(2)
+ };
+
+ return 0.25 * Math.abs(v1.e(1) * v2.e(2) - v1.e(2) * v2.e(1));
+ },
+
+ /**
+ * Calculate the non-affinity of the new object
+ * @return Number
+ */
+ nonAffinity: function() {
+ // The corners of the box
+ var sides = this.sides(),
+ xDiff = sides.top - sides.bottom,
+ yDiff = sides.left - sides.right;
+
+ return parseFloat(parseFloat(Math.abs(
+ (Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) /
+ (sides.top * sides.bottom + sides.left * sides.right)
+ )).toFixed(8));
+ },
+
+ /**
+ * Calculate a proper top and left for IE
+ * @param Object toOrigin
+ * @param Object fromOrigin
+ * @return Object
+ */
+ originOffset: function(toOrigin, fromOrigin) {
+ // the origin to translate to
+ toOrigin = toOrigin ? toOrigin : new $.matrix.V2(
+ this.outerWidth * 0.5,
+ this.outerHeight * 0.5
+ );
+
+ // the origin to translate from (IE has a fixed origin of 0, 0)
+ fromOrigin = fromOrigin ? fromOrigin : new $.matrix.V2(
+ 0,
+ 0
+ );
+
+ // transform the origins
+ var toCenter = this.coord(toOrigin.e(1), toOrigin.e(2));
+ var fromCenter = this.coord(fromOrigin.e(1), fromOrigin.e(2));
+
+ // return the offset
+ return {
+ top: (fromCenter.e(2) - fromOrigin.e(2)) - (toCenter.e(2) - toOrigin.e(2)),
+ left: (fromCenter.e(1) - fromOrigin.e(1)) - (toCenter.e(1) - toOrigin.e(1))
+ };
+ }
+ };
+})(jQuery, this, this.document);
+///////////////////////////////////////////////////////
+// 2d Matrix Functions
+///////////////////////////////////////////////////////
+(function($, window, document, undefined) {
+ /**
+ * Matrix object for creating matrices relevant for 2d Transformations
+ * @var Object
+ */
+ if (typeof($.matrix) == 'undefined') {
+ $.extend({
+ matrix: {}
+ });
+ }
+
+ $.extend( $.matrix, {
+ /**
+ * Identity matrix
+ * @param Number size
+ * @return Matrix
+ */
+ identity: function(size) {
+ size = size || 2;
+ var length = size * size,
+ elements = new Array(length),
+ mod = size + 1;
+ for (var i = 0; i < length; i++) {
+ elements[i] = (i % mod) === 0 ? 1 : 0;
+ }
+ return new $.matrix['M'+size+'x'+size](elements);
+ },
+
+ /**
+ * Matrix
+ * @return Matrix
+ */
+ matrix: function() {
+ var args = Array.prototype.slice.call(arguments);
+ // arguments are in column-major order
+ switch (arguments.length) {
+ case 4:
+ return new $.matrix.M2x2(
+ args[0], args[2],
+ args[1], args[3]
+ );
+ case 6:
+ return new $.matrix.M3x3(
+ args[0], args[2], args[4],
+ args[1], args[3], args[5],
+ 0, 0, 1
+ );
+ }
+ },
+
+ /**
+ * Reflect (same as rotate(180))
+ * @return Matrix
+ */
+ reflect: function() {
+ return new $.matrix.M2x2(
+ -1, 0,
+ 0, -1
+ );
+ },
+
+ /**
+ * Reflect across the x-axis (mirrored upside down)
+ * @return Matrix
+ */
+ reflectX: function() {
+ return new $.matrix.M2x2(
+ 1, 0,
+ 0, -1
+ );
+ },
+
+ /**
+ * Reflect by swapping x an y (same as reflectX + rotate(-90))
+ * @return Matrix
+ */
+ reflectXY: function() {
+ return new $.matrix.M2x2(
+ 0, 1,
+ 1, 0
+ );
+ },
+
+ /**
+ * Reflect across the y-axis (mirrored)
+ * @return Matrix
+ */
+ reflectY: function() {
+ return new $.matrix.M2x2(
+ -1, 0,
+ 0, 1
+ );
+ },
+
+ /**
+ * Rotates around the origin
+ * @param Number deg
+ * @return Matrix
+ * @link http://www.w3.org/TR/SVG/coords.html#RotationDefined
+ */
+ rotate: function(deg) {
+ //TODO: detect units
+ var rad = $.angle.degreeToRadian(deg),
+ costheta = Math.cos(rad),
+ sintheta = Math.sin(rad);
+
+ var a = costheta,
+ b = sintheta,
+ c = -sintheta,
+ d = costheta;
+
+ return new $.matrix.M2x2(
+ a, c,
+ b, d
+ );
+
+ },
+
+ /**
+ * Scale
+ * @param Number sx
+ * @param Number sy
+ * @return Matrix
+ * @link http://www.w3.org/TR/SVG/coords.html#ScalingDefined
+ */
+ scale: function (sx, sy) {
+ sx = sx || sx === 0 ? sx : 1;
+ sy = sy || sy === 0 ? sy : sx;
+
+ return new $.matrix.M2x2(
+ sx, 0,
+ 0, sy
+ );
+ },
+
+ /**
+ * Scale on the X-axis
+ * @param Number sx
+ * @return Matrix
+ */
+ scaleX: function (sx) {
+ return $.matrix.scale(sx, 1);
+ },
+
+ /**
+ * Scale on the Y-axis
+ * @param Number sy
+ * @return Matrix
+ */
+ scaleY: function (sy) {
+ return $.matrix.scale(1, sy);
+ },
+
+ /**
+ * Skews on the X-axis and Y-axis
+ * @param Number degX
+ * @param Number degY
+ * @return Matrix
+ */
+ skew: function (degX, degY) {
+ degX = degX || 0;
+ degY = degY || 0;
+
+ //TODO: detect units
+ var radX = $.angle.degreeToRadian(degX),
+ radY = $.angle.degreeToRadian(degY),
+ x = Math.tan(radX),
+ y = Math.tan(radY);
+
+ return new $.matrix.M2x2(
+ 1, x,
+ y, 1
+ );
+ },
+
+ /**
+ * Skews on the X-axis
+ * @param Number degX
+ * @return Matrix
+ * @link http://www.w3.org/TR/SVG/coords.html#SkewXDefined
+ */
+ skewX: function (degX) {
+ return $.matrix.skew(degX);
+ },
+
+ /**
+ * Skews on the Y-axis
+ * @param Number degY
+ * @return Matrix
+ * @link http://www.w3.org/TR/SVG/coords.html#SkewYDefined
+ */
+ skewY: function (degY) {
+ return $.matrix.skew(0, degY);
+ },
+
+ /**
+ * Translate
+ * @param Number tx
+ * @param Number ty
+ * @return Matrix
+ * @link http://www.w3.org/TR/SVG/coords.html#TranslationDefined
+ */
+ translate: function (tx, ty) {
+ tx = tx || 0;
+ ty = ty || 0;
+
+ return new $.matrix.M3x3(
+ 1, 0, tx,
+ 0, 1, ty,
+ 0, 0, 1
+ );
+ }
+ });
+})(jQuery, this, this.document);
View
11 dist/jquery.transform-0.9.0.min.js
@@ -0,0 +1,11 @@
+/*
+ * jQuery 2d Transform v0.9.0
+ * http://wiki.github.com/heygrady/transform/
+ *
+ * Copyright 2010, Grady Kuhnline
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Date: Wed Oct 6 00:34:26 2010 -0700
+ */
+(function(g,h,k,c){var i=/progid:DXImageTransform\.Microsoft\.Matrix\(.*?\)/;var d=k.createElement("modernizr"),e=d.style;function o(m){return parseFloat(m)}function n(){var m={transformProperty:"",MozTransform:"-moz-",WebkitTransform:"-webkit-",OTransform:"-o-",msTransform:"-ms-"};for(var q in m){if(typeof e[q]!="undefined"){return m[q]}}return null}function p(){if(typeof(h.Modernizr)!=="undefined"){return Modernizr.csstransforms}var q=["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"];for(var m in q){if(e[q[m]]!==c){return true}}}var a=n(),j=a!==null?a+"transform":false,l=a!==null?a+"transform-origin":false;g.support.csstransforms=p();g.extend({transform:function(m){m.transform=this;this.$elem=g(m);this.applyingMatrix=false;this.matrix=null;this.height=null;this.width=null;this.outerHeight=null;this.outerWidth=null;this.boxSizingValue=null;this.boxSizingProperty=null;this.attr=null;this.transformProperty=j;this.transformOriginProperty=l}});g.extend(g.transform,{funcs:["matrix","origin","reflect","reflectX","reflectXY","reflectY","rotate","scale","scaleX","scaleY","skew","skewX","skewY","translate","translateX","translateY"],rfunc:{angle:/^rotate|skew[X|Y]?$/,length:/^origin|translate[X|Y]?$/,scale:/^scale[X|Y]?$/,reflect:/^reflect(XY|X|Y)?$/}});g.fn.transform=function(m,q){return this.each(function(){var r=this.transform||new g.transform(this);if(m){r.exec(m,q)}})};g.transform.prototype={exec:function(m,q){q=g.extend(true,{forceMatrix:false,preserve:false},q);this.attr=null;if(q.preserve){m=g.extend(true,this.getAttrs(true,true),m)}else{m=g.extend(true,{},m)}this.setAttrs(m);if(g.support.csstransforms&&!q.forceMatrix){return this.execFuncs(m)}else{if(g.browser.msie||(g.support.csstransforms&&q.forceMatrix)){return this.execMatrix(m)}}return false},execFuncs:function(q){var m=[];for(var r in q){if(r=="origin"){this[r].apply(this,g.isArray(q[r])?q[r]:[q[r]])}else{if(g.inArray(r,g.transform.funcs)!=-1){m.push(this.createTransformFunc(r,q[r]))}}}this.$elem.css(j,m.join(" "));return true},execMatrix:function(r){var C,x,z;for(var t in r){if(g.matrix[t]){z=g.isArray(r[t])?r[t]:[r[t]];z=g.map(z,o);x=g.matrix[t].apply(this,z);C=C?C.x(x):x}else{if(t=="origin"){z=g.isArray(r[t])?r[t]:[r[t]];this[t].apply(this,z)}}}C=C||g.matrix.identity();var D=parseFloat(C.e(1,1).toFixed(6)),B=parseFloat(C.e(2,1).toFixed(6)),A=parseFloat(C.e(1,2).toFixed(6)),y=parseFloat(C.e(2,2).toFixed(6)),v=C.rows===3?parseFloat(C.e(1,3).toFixed(6)):0,u=C.rows===3?parseFloat(C.e(2,3).toFixed(6)):0;if(g.support.csstransforms&&a==="-moz-"){this.$elem.css(j,"matrix("+D+", "+B+", "+A+", "+y+", "+v+"px, "+u+"px)")}else{if(g.support.csstransforms){this.$elem.css(j,"matrix("+D+", "+B+", "+A+", "+y+", "+v+", "+u+")")}else{if(g.browser.msie){var m=", FilterType='nearest neighbor'";var q=this.$elem[0].style;var w="progid:DXImageTransform.Microsoft.Matrix(M11="+D+", M12="+A+", M21="+B+", M22="+y+", sizingMethod='auto expand'"+m+")";var s=q.filter||jQuery.curCSS(this.$elem[0],"filter")||"";q.filter=i.test(s)?s.replace(i,w):s?s+" "+w:w;this.applyingMatrix=true;this.matrix=C;this.fixPosition(C,v,u);this.applyingMatrix=false;this.matrix=null}}}return true},origin:function(m,q){if(g.support.csstransforms){if(typeof q==="undefined"){this.$elem.css(l,m)}else{this.$elem.css(l,m+" "+q)}return true}switch(m){case"left":m="0";break;case"right":m="100%";break;case"center":case c:m="50%"}switch(q){case"top":q="0";break;case"bottom":q="100%";break;case"center":case c:q="50%"}if(/%/.test(m)&&/%/.test(q)){this.setAttr("origin",[m,q]);return true}this.setAttr("origin",[/%/.test(m)?m:parseFloat(m)+"px",/%/.test(q)?q:parseFloat(q)+"px"]);return true},createTransformFunc:function(s,t){if(g.transform.rfunc.reflect.test(s)){var r=t?g.matrix[s]():g.matrix.identity(),q=r.e(1,1),m=r.e(2,1),v=r.e(1,2),u=r.e(2,2);return"matrix("+q+", "+m+", "+v+", "+u+", 0, 0)"}t=f(s,t);if(!g.isArray(t)){return s+"("+t+")"}else{if(s=="matrix"){if(a==="-moz-"&&t[4]){t[4]=t[4]+"px"}if(a==="-moz-"&&t[5]){t[5]=t[5]+"px"}return"matrix("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+(t[4]||0)+", "+(t[5]||0)+")"}else{return s+"("+t[0]+", "+t[1]+")"}}},fixPosition:function(y,v,u,A,m){var t=new g.matrix.calc(y,this.safeOuterHeight(),this.safeOuterWidth()),z=this.getAttr("origin");var s=t.originOffset(new g.matrix.V2(/%/.test(z[0])?parseFloat(z[0])/100*t.outerWidth:parseFloat(z[0]),/%/.test(z[1])?parseFloat(z[1])/100*t.outerHeight:parseFloat(z[1])));var q=t.sides();var r=this.$elem.css("position");if(r=="static"){r="relative"}var x={top:0,left:0};var w={position:r,top:(s.top+u+q.top+x.top)+"px",left:(s.left+v+q.left+x.left)+"px",zoom:1};this.$elem.css(w)}};var b=/^([\+\-]=)?([\d+.\-]+)(.*)$/;function f(q,v){var x=!g.isArray(v)?[v]:v,m=g.transform.rfunc.angle,w=g.transform.rfunc.length;for(var s=0,t=x.length;s<t;s++){var r=b.exec(x[s]),u="";if(m.test(q)){u="deg";if(r[3]&&!g.angle.runit.test(r[3])){r[3]=null}}else{if(w.test(q)){u="px"}}if(!r){x[s]=0+u}else{if(!r[3]){x[s]+=u}}}return t==1?x[0]:x}})(jQuery,this,this.document);(function(d,c,a,f){d.extend(d.transform.prototype,{safeOuterHeight:function(){return this.safeOuterLength("height")},safeOuterWidth:function(){return this.safeOuterLength("width")},safeOuterLength:function(l){var o="outer"+(l=="width"?"Width":"Height");if(d.browser.msie){l=l=="width"?"width":"height";if(this.applyingMatrix&&!this[o]&&this.matrix){var k=new d.matrix.calc(this.matrix,1,1),m=k.offset(),g=this.$elem[o]()/m[l];this[o]=g;return g}else{if(this.applyingMatrix&&this[o]){return this[o]}}var n={height:["top","bottom"],width:["left","right"]};var h=this.$elem[0],j=parseFloat(d.curCSS(h,l,true)),p=this.boxSizingProperty,i=this.boxSizingValue;if(!this.boxSizingProperty){p=this.boxSizingProperty=e()||"box-sizing";i=this.boxSizingValue=this.$elem.css(p)||"content-box"}if(this[o]&&this[l]==j){return this[o]}else{this[l]=j}if(p&&(i=="padding-box"||i=="content-box")){j+=parseFloat(d.curCSS(h,"padding-"+n[l][0],true))||0+parseFloat(d.curCSS(h,"padding-"+n[l][1],true))||0}if(p&&i=="content-box"){j+=parseFloat(d.curCSS(h,"border-"+n[l][0]+"-width",true))||0+parseFloat(d.curCSS(h,"border-"+n[l][1]+"-width",true))||0}this[o]=j;return j}return this.$elem[o]()}});var b=null;function e(){if(b){return b}var h={boxSizing:"box-sizing",MozBoxSizing:"-moz-box-sizing",WebkitBoxSizing:"-webkit-box-sizing",OBoxSizing:"-o-box-sizing"},g=a.body;for(var i in h){if(typeof g.style[i]!="undefined"){b=h[i];return b}}return null}})(jQuery,this,this.document);(function(g,f,b,h){var d=/([\w\-]*?)\((.*?)\)/g,a="data-transform",e=/\s/,c=/,\s/;g.extend(g.transform.prototype,{setAttrs:function(i){var j="",l;for(var k in i){l=i[k];if(g.isArray(l)){l=l.join(", ")}j+=" "+k+"("+l+")"}this.attr=g.trim(j);this.$elem.attr(a,this.attr)},setAttr:function(k,l){if(g.isArray(l)){l=l.join(", ")}l=g.trim(l+"");var j=this.attr||this.$elem.attr(a);if(!j||j.indexOf(k)>-1){this.attr=g.trim(j+" "+k+"("+l+")");this.$elem.attr(a,this.attr)}else{var i=[],m;d.lastIndex=0;while((result=d.exec(j))!==null){if(k==m[1]){i.push(k+"("+l+")")}else{i.push(m[0])}}this.attr=i.join(" ");this.$elem.attr(a,this.attr)}},getAttrs:function(){var j=this.attr||this.$elem.attr(a);if(!j){return{}}var i={},l,k;d.lastIndex=0;while((l=d.exec(j))!==null){if(l){k=l[2].split(c);i[l[1]]=k.length==1?k[0]:k}}return i},getAttr:function(j){var i=this.getAttrs();if(typeof i[j]!=="undefined"){return i[j]}switch(j){case"scale":return[1,1];case"scaleX":case"scaleY":return 1;case"matrix":return[1,0,0,1,0,0];case"origin":if(g.support.csstransforms){return this.$elem.css(this.transformOriginProperty).split(e)}else{return["50%","50%"]}}return null}})})(jQuery,this,this.document);(function(e,d,b,f){var a=/^([+\-]=)?([\d+.\-]+)(.*)$/;var c=/^(.*?)\s+([+\-]=)?([\d+.\-]+)(.*)$/;var h=e.fn.animate;e.fn.animate=function(m,j,l,k){if(m&&!jQuery.isEmptyObject(m)){var i=this;jQuery.each(m,function(n,o){if(e.inArray(n,e.transform.funcs)!=-1){if(e.transform.rfunc.reflect.test(n)){var p=o?e.matrix[n]():e.matrix.identity(),t=p.elements;o=[t[0],t[1],t[2],t[3]]}var r=a.exec(o);if((r&&r[3])||e.isArray(o)){var q,u,v=[];if(e.isArray(o)){e.each(o,function(w){r=a.exec(this);q=parseFloat(r[2]);u=r[3]||"px";v.push({end:(r[1]?r[1]:"")+q,unit:u})})}else{q=parseFloat(r[2]);u=r[3]||"px";v.push({end:(r[1]?r[1]:"")+q,unit:u});var s=0;while(r=c.exec(u)){v[s].unit=r[1];v.push({end:(r[2]?r[2]:"")+parseFloat(r[3]),unit:r[4]});u=r[4];s++}}i.data("data-animate-"+n,v);m[n]=v[0].end}}})}return h.apply(this,arguments)};var g=e.fx.prototype.cur;e.fx.prototype.cur=function(k){if(e.inArray(this.prop,e.transform.funcs)!=-1){this.transform=this.transform||this.elem.transform||new e.transform(this.elem);var i=e.transform.rfunc;var j=this.transform.getAttr(this.prop),l=a.exec(e.isArray(j)?j[0]:j);if(j===null||l===null){j=i.scale.test(this.prop)||i.reflect.test(this.prop)?1:0;l=[null,null,j]}return parseFloat(l[2])}return g.apply(this,arguments)};e.fx.multivalueInit=function(l){var j=e(l.elem),i=l.transform.getAttr(l.prop),k=j.data("data-animate-"+l.prop);if(k){j.removeData("data-animate-"+l.prop)}if(e.transform.rfunc.reflect.test(l.prop)){i=l.transform.getAttr("matrix")}l.values=[];if(e.isArray(i)&&!e.isArray(k)){k=[{end:parseFloat(l.end),unit:l.unit},{end:e.transform.rfunc.scale.test(l.prop)?1:0,unit:l.unit}]}if(k){var o,n=e.transform.rfunc.scale,m;e.each(k,function(p,q){if(e.isArray(i)){o=i[p]}else{if(p>0){o=n.test(l.prop)?i:null}else{o=i}}if(!o&&o!==0){o=n.test(l.prop)?1:0}o=parseFloat(o);m=a.exec(q.end);if(m&&m[1]){q.end=((m[1]==="-="?-1:1)*parseFloat(m[2]))+o}l.values.push({start:parseFloat(o),end:parseFloat(q.end),unit:q.unit})})}else{l.values.push({start:parseFloat(l.start),end:parseFloat(l.end),unit:l.unit})}};e.fx.multivalueStep={_default:function(i){e.each(i.values,function(j,k){i.values[j].now=k.start+((k.end-k.start)*i.pos)})}};e.each(e.transform.funcs,function(j,k){e.fx.step[k]=function(n){if(!n.transformInit){n.transform=n.transform||n.elem.transform||new e.transform(n.elem);e.fx.multivalueInit(n);if(n.values.length>1){n.multiple=true}var m=e.transform.rfunc;if(m.angle.test(n.prop)){n.unit="deg"}else{if(m.scale.test(n.prop)){n.unit=""}else{if(m.reflect.test(n.prop)){n.unit=""}else{if(n.prop=="matrix"){n.unit=""}}}}e.each(n.values,function(p){n.values[p].unit=n.unit});n.transformInit=true}if(n.multiple){(e.fx.multivalueStep[n.prop]||e.fx.multivalueStep._default)(n)}else{n.values[0].now=n.now}var l=[];e.each(n.values,function(p,q){if(q.unit=="deg"){while(q.now>=360){q.now-=360}while(q.now<=-360){q.now+=360}}l.push(parseFloat(parseFloat(q.now).toFixed(8))+q.unit)});var i={},o=e.transform.rfunc.reflect.test(n.prop)?"matrix":n.prop;i[o]=n.multiple?l:l[0];n.transform.exec(i,{preserve:true})}})})(jQuery,this,this.document);(function(f,g,i,b){var c=180/Math.PI;var j=200/Math.PI;var e=Math.PI/180;var d=2/1.8;var h=0.9;var a=Math.PI/200;f.extend({angle:{runit:/(deg|g?rad)/,radianToDegree:function(k){return k*c},radianToGrad:function(k){return k*j},degreeToRadian:function(k){return k*e},degreeToGrad:function(k){return k*d},gradToDegree:function(k){return k*h},gradToRadian:function(k){return k*a}}})})(jQuery,this,this.document);(function(e,d,b,f){if(typeof(e.matrix)=="undefined"){e.extend({matrix:{}})}e.extend(e.matrix,{V2:function(g,h){if(e.isArray(arguments[0])){this.elements=arguments[0].slice(0,2)}else{this.elements=[g,h]}this.length=2},V3:function(g,i,h){if(e.isArray(arguments[0])){this.elements=arguments[0].slice(0,3)}else{this.elements=[g,i,h]}this.length=3},M2x2:function(h,g,j,i){if(e.isArray(arguments[0])){this.elements=arguments[0].slice(0,4)}else{this.elements=Array.prototype.slice.call(arguments).slice(0,4)}this.rows=2;this.cols=2},M3x3:function(l,k,j,i,h,g,o,n,m){if(e.isArray(arguments[0])){this.elements=arguments[0].slice(0,9)}else{this.elements=Array.prototype.slice.call(arguments).slice(0,9)}this.rows=3;this.cols=3}});var c={e:function(j,g){var h=this.rows,i=this.cols;if(j>h||g>h||j<1||g<1){return 0}return this.elements[(j-1)*i+g-1]}};e.extend(e.matrix.M2x2.prototype,c,{toM3x3:function(){var g=this.elements;return new e.matrix.M3x3(g[0],g[1],0,g[2],g[3],0,0,0,1)},x:function(i){var j=typeof(i.rows)==="undefined";if(!j&&i.rows==3){return this.toM3x3().x(i)}var h=this.elements,g=i.elements;if(j&&g.length==2){return new e.matrix.V2(h[0]*g[0]+h[1]*g[1],h[2]*g[0]+h[3]*g[1])}else{if(g.length==h.length){return new e.matrix.M2x2(h[0]*g[0]+h[1]*g[2],h[0]*g[1]+h[1]*g[3],h[2]*g[0]+h[3]*g[2],h[2]*g[1]+h[3]*g[3])}}return false},inverse:function(){var h=1/this.determinant(),g=this.elements;return new e.matrix.M2x2(h*g[3],h*-g[1],h*-g[2],h*g[0])},determinant:function(){var g=this.elements;return g[0]*g[3]-g[1]*g[2]}});e.extend(e.matrix.M3x3.prototype,c,{x:function(i){var j=typeof(i.rows)==="undefined";if(!j&&i.rows<3){i=i.toM3x3()}var h=this.elements,g=i.elements;if(j&&g.length==3){return new e.matrix.V3(h[0]*g[0]+h[1]*g[1]+h[2]*g[2],h[3]*g[0]+h[4]*g[1]+h[5]*g[2],h[6]*g[0]+h[7]*g[1]+h[8]*g[2])}else{if(g.length==h.length){return new e.matrix.M3x3(h[0]*g[0]+h[1]*g[3]+h[2]*g[6],h[0]*g[1]+h[1]*g[4]+h[2]*g[7],h[0]*g[2]+h[1]*g[5]+h[2]*g[8],h[3]*g[0]+h[4]*g[3]+h[5]*g[6],h[3]*g[1]+h[4]*g[4]+h[5]*g[7],h[3]*g[2]+h[4]*g[5]+h[5]*g[8],h[6]*g[0]+h[7]*g[3]+h[8]*g[6],h[6]*g[1]+h[7]*g[4]+h[8]*g[7],h[6]*g[2]+h[7]*g[5]+h[8]*g[8])}}return false},inverse:function(){var h=1/this.determinant(),g=this.elements;return new e.matrix.M3x3(h*(g[8]*g[4]-g[7]*g[5]),h*(-(g[8]*g[1]-g[7]*g[2])),h*(g[5]*g[1]-g[4]*g[2]),h*(-(g[8]*g[3]-g[6]*g[5])),h*(g[8]*g[0]-g[6]*g[2]),h*(-(g[5]*g[0]-g[3]*g[2])),h*(g[7]*g[3]-g[6]*g[4]),h*(-(g[7]*g[0]-g[6]*g[1])),h*(g[4]*g[0]-g[3]*g[1]))},determinant:function(){var g=this.elements;return g[0]*(g[8]*g[4]-g[7]*g[5])-g[3]*(g[8]*g[1]-g[7]*g[2])+g[6]*(g[5]*g[1]-g[4]*g[2])}});var a={e:function(g){return this.elements[g-1]}};e.extend(e.matrix.V2.prototype,a);e.extend(e.matrix.V3.prototype,a)})(jQuery,this,this.document);(function(c,b,a,d){if(typeof(c.matrix)=="undefined"){c.extend({matrix:{}})}c.extend(c.matrix,{calc:function(e,f,g){this.matrix=e;this.outerHeight=f;this.outerWidth=g}});c.matrix.calc.prototype={coord:function(e,i,h){h=typeof(h)!=="undefined"?h:0;var g=this.matrix,f;switch(g.rows){case 2:f=g.x(new c.matrix.V2(e,i));break;case 3:f=g.x(new c.matrix.V3(e,i,h));break}return f},corners:function(e,h){var f=!(typeof(e)!=="undefined"||typeof(h)!=="undefined"),g;if(!this.c||!f){h=h||this.outerHeight;e=e||this.outerWidth;g={tl:this.coord(0,0),bl:this.coord(0,h),tr:this.coord(e,0),br:this.coord(e,h)}}else{g=this.c}if(f){this.c=g}return g},sides:function(e){var f=e||this.corners();return{top:Math.min(f.tl.e(2),f.tr.e(2),f.br.e(2),f.bl.e(2)),bottom:Math.max(f.tl.e(2),f.tr.e(2),f.br.e(2),f.bl.e(2)),left:Math.min(f.tl.e(1),f.tr.e(1),f.br.e(1),f.bl.e(1)),right:Math.max(f.tl.e(1),f.tr.e(1),f.br.e(1),f.bl.e(1))}},offset:function(e){var f=this.sides(e);return{height:Math.abs(f.bottom-f.top),width:Math.abs(f.right-f.left)}},area:function(e){var h=e||this.corners();var g={x:h.tr.e(1)-h.tl.e(1)+h.br.e(1)-h.bl.e(1),y:h.tr.e(2)-h.tl.e(2)+h.br.e(2)-h.bl.e(2)},f={x:h.bl.e(1)-h.tl.e(1)+h.br.e(1)-h.tr.e(1),y:h.bl.e(2)-h.tl.e(2)+h.br.e(2)-h.tr.e(2)};return 0.25*Math.abs(g.e(1)*f.e(2)-g.e(2)*f.e(1))},nonAffinity:function(){var f=this.sides(),g=f.top-f.bottom,e=f.left-f.right;return parseFloat(parseFloat(Math.abs((Math.pow(g,2)+Math.pow(e,2))/(f.top*f.bottom+f.left*f.right))).toFixed(8))},originOffset:function(h,g){h=h?h:new c.matrix.V2(this.outerWidth*0.5,this.outerHeight*0.5);g=g?g:new c.matrix.V2(0,0);var e=this.coord(h.e(1),h.e(2));var f=this.coord(g.e(1),g.e(2));return{top:(f.e(2)-g.e(2))-(e.e(2)-h.e(2)),left:(f.e(1)-g.e(1))-(e.e(1)-h.e(1))}}}})(jQuery,this,this.document);(function(c,b,a,d){if(typeof(c.matrix)=="undefined"){c.extend({matrix:{}})}c.extend(c.matrix,{identity:function(g){g=g||2;var h=g*g,j=new Array(h),f=g+1;for(var e=0;e<h;e++){j[e]=(e%f)===0?1:0}return new c.matrix["M"+g+"x"+g](j)},matrix:function(){var e=Array.prototype.slice.call(arguments);switch(arguments.length){case 4:return new c.matrix.M2x2(e[0],e[2],e[1],e[3]);case 6:return new c.matrix.M3x3(e[0],e[2],e[4],e[1],e[3],e[5],0,0,1)}},reflect:function(){return new c.matrix.M2x2(-1,0,0,-1)},reflectX:function(){return new c.matrix.M2x2(1,0,0,-1)},reflectXY:function(){return new c.matrix.M2x2(0,1,1,0)},reflectY:function(){return new c.matrix.M2x2(-1,0,0,1)},rotate:function(i){var f=c.angle.degreeToRadian(i),h=Math.cos(f),j=Math.sin(f);var g=h,e=j,l=-j,k=h;return new c.matrix.M2x2(g,l,e,k)},scale:function(f,e){f=f||f===0?f:1;e=e||e===0?e:f;return new c.matrix.M2x2(f,0,0,e)},scaleX:function(e){return c.matrix.scale(e,1)},scaleY:function(e){return c.matrix.scale(1,e)},skew:function(h,f){h=h||0;f=f||0;var i=c.angle.degreeToRadian(h),g=c.angle.degreeToRadian(f),e=Math.tan(i),j=Math.tan(g);return new c.matrix.M2x2(1,e,j,1)},skewX:function(e){return c.matrix.skew(e)},skewY:function(e){return c.matrix.skew(0,e)},translate:function(f,e){f=f||0;e=e||0;return new c.matrix.M3x3(1,0,f,0,1,e,0,0,1)}})})(jQuery,this,this.document);
View
1  src/jquery.angle.js
@@ -1,3 +1,4 @@
+
///////////////////////////////////////////////////////
// Angle
///////////////////////////////////////////////////////
View
1  src/jquery.matrix.calculations.js
@@ -1,3 +1,4 @@
+
///////////////////////////////////////////////////////
// Matrix Calculations
///////////////////////////////////////////////////////
View
3  src/jquery.matrix.functions.js
@@ -1,3 +1,4 @@
+
///////////////////////////////////////////////////////
// 2d Matrix Functions
///////////////////////////////////////////////////////
@@ -42,14 +43,12 @@
args[0], args[2],
args[1], args[3]
);
- break;
case 6:
return new $.matrix.M3x3(
args[0], args[2], args[4],
args[1], args[3], args[5],
0, 0, 1
);
- break;
}
},
View
3  src/jquery.matrix.js
@@ -1,3 +1,4 @@
+
///////////////////////////////////////////////////////
// Matrix
///////////////////////////////////////////////////////
@@ -105,7 +106,7 @@
a[2], a[3], 0,
0, 0, 1
);
- }
+ },
/**
* Multiply a 2x2 matrix by a similar matrix or a vector
View
1  src/jquery.transform.animate.js
@@ -1,3 +1,4 @@
+
///////////////////////////////////////////////////////
// Animation
///////////////////////////////////////////////////////
View
12 src/jquery.transform.attributes.js
@@ -1,8 +1,9 @@
+
///////////////////////////////////////////////////////
// Attr
///////////////////////////////////////////////////////
(function($, window, document, undefined) {
- var rfuncvalue = /([\w-]*?)\((.*?)\)/g, // with values
+ var rfuncvalue = /([\w\-]*?)\((.*?)\)/g, // with values
attr = 'data-transform',
rspace = /\s/,
rcspace = /,\s/;
@@ -77,8 +78,7 @@
}
// replace the existing value
- var attrs = {},
- result, parts, value;
+ var attrs = {}, parts, value;
rfuncvalue.lastIndex = 0; // reset the regex pointer
while ((parts = rfuncvalue.exec(transform)) !== null) {
@@ -103,10 +103,10 @@
// animate needs sensible defaults for some props
switch (func) {
- case 'scale': return [1, 1]; break;
+ case 'scale': return [1, 1];
case 'scaleX': // no break;
- case 'scaleY': return 1; break;
- case 'matrix': return [1, 0, 0, 1, 0, 0]; break;
+ case 'scaleY': return 1;
+ case 'matrix': return [1, 0, 0, 1, 0, 0];
case 'origin':
if ($.support.csstransforms) {
// supported browsers return percentages always
View
82 src/jquery.transform.js
@@ -1,10 +1,12 @@
/*!
- * jQuery 2d Transform
+ * jQuery 2d Transform v@VERSION
* http://wiki.github.com/heygrady/transform/
*
* Copyright 2010, Grady Kuhnline
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
+ *
+ * Date:
*/
///////////////////////////////////////////////////////
// Transform
@@ -17,8 +19,43 @@
// Steal some code from Modernizr
var m = document.createElement( 'modernizr' ),
- m_style = m.style,
- docElement = document.documentElement;
+ m_style = m.style;
+
+ function stripUnits(arg) {
+ return parseFloat(arg);
+ }
+
+ /**
+ * Find the prefix that this browser uses
+ */
+ function getVendorPrefix() {
+ var property = {
+ transformProperty : '',
+ MozTransform : '-moz-',
+ WebkitTransform : '-webkit-',
+ OTransform : '-o-',
+ msTransform : '-ms-'
+ };
+ for (var p in property) {
+ if (typeof m_style[p] != 'undefined') {
+ return property[p];
+ }
+ }
+ return null;
+ }
+
+ function supportCssTransforms() {
+ if (typeof(window.Modernizr) !== 'undefined') {
+ return Modernizr.csstransforms;
+ }
+
+ var props = [ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ];
+ for ( var i in props ) {
+ if ( m_style[ props[i] ] !== undefined ) {
+ return true;
+ }
+ }
+ }
// Capture some basic properties
var vendorPrefix = getVendorPrefix(),
@@ -345,8 +382,7 @@
// IE glues the top-most and left-most pixels of the transformed object to top/left of the original object
//TODO: This seems wrong in the calculations
- var sides = calc.sides(),
- size = calc.offset();
+ var sides = calc.sides();
// Protect against an item that is already positioned
var cssPosition = this.$elem.css('position');
@@ -370,42 +406,6 @@
}
};
- function stripUnits(arg) {
- return parseFloat(arg);
- }
-
- /**
- * Find the prefix that this browser uses
- */
- function getVendorPrefix() {
- var property = {
- transformProperty : '',
- MozTransform : '-moz-',
- WebkitTransform : '-webkit-',
- OTransform : '-o-',
- msTransform : '-ms-'
- };
- for (var p in property) {
- if (typeof m_style[p] != 'undefined') {
- return property[p];
- }
- }
- return null;
- }
-
- function supportCssTransforms() {
- if (typeof(window.Modernizr) !== 'undefined') {
- return Modernizr.csstransforms;
- }
-
- var props = [ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ];
- for ( var i in props ) {
- if ( m_style[ props[i] ] !== undefined ) {
- return true;
- }
- }
- }
-
/**
* Ensure that values have the appropriate units on them
* @param string func
View
1  version.txt
@@ -0,0 +1 @@
+0.9.0
Please sign in to comment.
Something went wrong with that request. Please try again.