Cards Against Humanity
+
+
<%-- cah must be first, ajax must be before app. app probably has to be last. --%>
<%-- TODO make this be dynamic with looking at the filesystem and using jquery --%>
@@ -31,6 +33,16 @@
< % = new net.socialgamer.cah.data.WhiteDeck().getNextCard().toString() % >
--%>
+
+
+
Cards Against Humanity is known to have graphical glitches in
+ $BROWSER_NAME. The game should work,
+ but it looks much better in Google Chrome.
+
We will not bug you about this again after you dismiss this dialog.
+
+
+
+
Nickname:
diff --git a/WebContent/js/QTransform.js b/WebContent/js/QTransform.js
new file mode 100644
index 0000000..5a9df30
--- /dev/null
+++ b/WebContent/js/QTransform.js
@@ -0,0 +1,438 @@
+/*
+ * 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;
+ $.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('