commit
e7674226de
7 changed files with 1291 additions and 0 deletions
Split View
Diff Options
-
1build/origami.min.css
-
1build/origami.min.js
-
30component.json
-
551dependencies/transform2d.js
-
92dependencies/transform3d.js
-
114src/origami.css
-
502src/origami.js
@ -0,0 +1 @@ |
|||
.origami.module{position:relative;-webkit-perspective:2000px;-moz-perspective:2000px;-ms-perspective:2000px;perspective:2000px}.origami.module .box{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.origami.module .side{display:none;opacity:1;width:100%;background-color:#fff;-moz-box-shadow:0 1px 3px rgba(0,0,0,0.3);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.3);box-shadow:0 1px 3px rgba(0,0,0,0.3);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.origami.module .handle{cursor:pointer;position:absolute;bottom:-28px;right:50%;margin-left:-22px;width:44px;height:44px;background:url(/images/modules/origami-handle.png) no-repeat 0 0}.origami.module .down.handle{background-position:0 -50px}.origami.module.animating .box{position:absolute}.origami.module .animating.side{position:absolute;width:100%;top:0;left:0;z-index:100}.origami.module .hidden.side{opacity:.5}.origami.css.module{-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;transition:all .5s ease-in-out}.origami.css.module .box{-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;transition:all .5s ease-in-out}.origami.css.module .side{-webkit-transition:opacity .5s ease-out;-moz-transition:opacity .5s ease-out;-o-transition:opacity .5s ease-out;-ms-transition:opacity .5s ease-out;transition:opacity .5s ease-out}.origami.module .active.side{display:block} |
1
build/origami.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,30 @@ |
|||
{ |
|||
"name" : "Origami", |
|||
"version" : "0.1", |
|||
"description" : "3D animation made easy, using the Semantic module spec.", |
|||
|
|||
"homepage" : "https://github.com/quirkyinc/", |
|||
"author": { |
|||
"name" : "Jack Lukic", |
|||
"web" : "http://www.github.com/quirkyjack/" |
|||
}, |
|||
"keywords": [ |
|||
"origami", |
|||
"animation", |
|||
"css3" |
|||
], |
|||
"license" : [ |
|||
"http://bartaz.mit-license.org/", |
|||
"http://www.gnu.org/licenses/" |
|||
], |
|||
|
|||
"main": [ |
|||
"./build/origami.js", |
|||
"./build/origami.css" |
|||
], |
|||
"dependencies": { |
|||
"jquery" : ">=1.8", |
|||
"transform2d" : "./dependencies/transform2d.js", |
|||
"transform3d" : "./dependencies/transform3d.js" |
|||
} |
|||
} |
@ -0,0 +1,551 @@ |
|||
/* |
|||
* transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate() |
|||
* |
|||
* limitations: |
|||
* - requires jQuery 1.4.3+ |
|||
* - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**. |
|||
* - transformOrigin is not accessible |
|||
* |
|||
* latest version and complete README available on Github: |
|||
* https://github.com/louisremi/jquery.transform.js
|
|||
* |
|||
* Copyright 2011 @louis_remi |
|||
* Licensed under the MIT license. |
|||
* |
|||
* This saved you an hour of work? |
|||
* Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
|
|||
* |
|||
*/ |
|||
(function( $, window, document, Math, undefined ) { |
|||
|
|||
/* |
|||
* Feature tests and global variables |
|||
*/ |
|||
var div = document.createElement("div"), |
|||
divStyle = div.style, |
|||
suffix = "Transform", |
|||
testProperties = [ |
|||
"O" + suffix, |
|||
"ms" + suffix, |
|||
"Webkit" + suffix, |
|||
"Moz" + suffix |
|||
], |
|||
i = testProperties.length, |
|||
supportProperty, |
|||
supportMatrixFilter, |
|||
supportFloat32Array = "Float32Array" in window, |
|||
propertyHook, |
|||
propertyGet, |
|||
rMatrix = /Matrix([^)]*)/, |
|||
rAffine = /^\s*matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*(?:,\s*0(?:px)?\s*){2}\)\s*$/, |
|||
_transform = "transform", |
|||
_transformOrigin = "transformOrigin", |
|||
_translate = "translate", |
|||
_rotate = "rotate", |
|||
_scale = "scale", |
|||
_skew = "skew", |
|||
_matrix = "matrix"; |
|||
|
|||
// test different vendor prefixes of these properties
|
|||
while ( i-- ) { |
|||
if ( testProperties[i] in divStyle ) { |
|||
$.support[_transform] = supportProperty = testProperties[i]; |
|||
$.support[_transformOrigin] = supportProperty + "Origin"; |
|||
continue; |
|||
} |
|||
} |
|||
// IE678 alternative
|
|||
if ( !supportProperty ) { |
|||
$.support.matrixFilter = supportMatrixFilter = divStyle.filter === ""; |
|||
} |
|||
|
|||
// px isn't the default unit of these properties
|
|||
$.cssNumber[_transform] = $.cssNumber[_transformOrigin] = true; |
|||
|
|||
/* |
|||
* fn.css() hooks |
|||
*/ |
|||
if ( supportProperty && supportProperty != _transform ) { |
|||
// Modern browsers can use jQuery.cssProps as a basic hook
|
|||
$.cssProps[_transform] = supportProperty; |
|||
$.cssProps[_transformOrigin] = supportProperty + "Origin"; |
|||
|
|||
// Firefox needs a complete hook because it stuffs matrix with "px"
|
|||
if ( supportProperty == "Moz" + suffix ) { |
|||
propertyHook = { |
|||
get: function( elem, computed ) { |
|||
return (computed ? |
|||
// remove "px" from the computed matrix
|
|||
$.css( elem, supportProperty ).split("px").join(""): |
|||
elem.style[supportProperty] |
|||
); |
|||
}, |
|||
set: function( elem, value ) { |
|||
// add "px" to matrices
|
|||
elem.style[supportProperty] = /matrix\([^)p]*\)/.test(value) ? |
|||
value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, _matrix+"$1$2px,$3px"): |
|||
value; |
|||
} |
|||
}; |
|||
/* Fix two jQuery bugs still present in 1.5.1 |
|||
* - rupper is incompatible with IE9, see http://jqbug.com/8346
|
|||
* - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402
|
|||
*/ |
|||
} else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) { |
|||
propertyHook = { |
|||
get: function( elem, computed ) { |
|||
return (computed ? |
|||
$.css( elem, supportProperty.replace(/^ms/, "Ms") ): |
|||
elem.style[supportProperty] |
|||
); |
|||
} |
|||
}; |
|||
} |
|||
/* TODO: leverage hardware acceleration of 3d transform in Webkit only |
|||
else if ( supportProperty == "Webkit" + suffix && support3dTransform ) { |
|||
propertyHook = { |
|||
set: function( elem, value ) { |
|||
elem.style[supportProperty] = |
|||
value.replace(); |
|||
} |
|||
} |
|||
}*/ |
|||
|
|||
} else if ( supportMatrixFilter ) { |
|||
propertyHook = { |
|||
get: function( elem, computed, asArray ) { |
|||
var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ), |
|||
matrix, data; |
|||
|
|||
if ( elemStyle && rMatrix.test( elemStyle.filter ) ) { |
|||
matrix = RegExp.$1.split(","); |
|||
matrix = [ |
|||
matrix[0].split("=")[1], |
|||
matrix[2].split("=")[1], |
|||
matrix[1].split("=")[1], |
|||
matrix[3].split("=")[1] |
|||
]; |
|||
} else { |
|||
matrix = [1,0,0,1]; |
|||
} |
|||
|
|||
if ( ! $.cssHooks[_transformOrigin] ) { |
|||
matrix[4] = elemStyle ? parseInt(elemStyle.left, 10) || 0 : 0; |
|||
matrix[5] = elemStyle ? parseInt(elemStyle.top, 10) || 0 : 0; |
|||
|
|||
} else { |
|||
data = $._data( elem, "transformTranslate", undefined ); |
|||
matrix[4] = data ? data[0] : 0; |
|||
matrix[5] = data ? data[1] : 0; |
|||
} |
|||
|
|||
return asArray ? matrix : _matrix+"(" + matrix + ")"; |
|||
}, |
|||
set: function( elem, value, animate ) { |
|||
var elemStyle = elem.style, |
|||
currentStyle, |
|||
Matrix, |
|||
filter, |
|||
centerOrigin; |
|||
|
|||
if ( !animate ) { |
|||
elemStyle.zoom = 1; |
|||
} |
|||
|
|||
value = matrix(value); |
|||
|
|||
// rotate, scale and skew
|
|||
Matrix = [ |
|||
"Matrix("+ |
|||
"M11="+value[0], |
|||
"M12="+value[2], |
|||
"M21="+value[1], |
|||
"M22="+value[3], |
|||
"SizingMethod='auto expand'" |
|||
].join(); |
|||
filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || ""; |
|||
|
|||
elemStyle.filter = rMatrix.test(filter) ? |
|||
filter.replace(rMatrix, Matrix) : |
|||
filter + " progid:DXImageTransform.Microsoft." + Matrix + ")"; |
|||
|
|||
if ( ! $.cssHooks[_transformOrigin] ) { |
|||
|
|||
// center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie
|
|||
if ( (centerOrigin = $.transform.centerOrigin) ) { |
|||
elemStyle[centerOrigin == "margin" ? "marginLeft" : "left"] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + "px"; |
|||
elemStyle[centerOrigin == "margin" ? "marginTop" : "top"] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + "px"; |
|||
} |
|||
|
|||
// translate
|
|||
// We assume that the elements are absolute positionned inside a relative positionned wrapper
|
|||
elemStyle.left = value[4] + "px"; |
|||
elemStyle.top = value[5] + "px"; |
|||
|
|||
} else { |
|||
$.cssHooks[_transformOrigin].set( elem, value ); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
// populate jQuery.cssHooks with the appropriate hook if necessary
|
|||
if ( propertyHook ) { |
|||
$.cssHooks[_transform] = propertyHook; |
|||
} |
|||
// we need a unique setter for the animation logic
|
|||
propertyGet = propertyHook && propertyHook.get || $.css; |
|||
|
|||
/* |
|||
* fn.animate() hooks |
|||
*/ |
|||
$.fx.step.transform = function( fx ) { |
|||
var elem = fx.elem, |
|||
start = fx.start, |
|||
end = fx.end, |
|||
pos = fx.pos, |
|||
transform = "", |
|||
precision = 1E5, |
|||
i, startVal, endVal, unit; |
|||
|
|||
// fx.end and fx.start need to be converted to interpolation lists
|
|||
if ( !start || typeof start === "string" ) { |
|||
|
|||
// the following block can be commented out with jQuery 1.5.1+, see #7912
|
|||
if ( !start ) { |
|||
start = propertyGet( elem, supportProperty ); |
|||
} |
|||
|
|||
// force layout only once per animation
|
|||
if ( supportMatrixFilter ) { |
|||
elem.style.zoom = 1; |
|||
} |
|||
|
|||
// replace "+=" in relative animations (-= is meaningless with transforms)
|
|||
end = end.split("+=").join(start); |
|||
|
|||
// parse both transform to generate interpolation list of same length
|
|||
$.extend( fx, interpolationList( start, end ) ); |
|||
start = fx.start; |
|||
end = fx.end; |
|||
} |
|||
|
|||
i = start.length; |
|||
|
|||
// interpolate functions of the list one by one
|
|||
while ( i-- ) { |
|||
startVal = start[i]; |
|||
endVal = end[i]; |
|||
unit = +false; |
|||
|
|||
switch ( startVal[0] ) { |
|||
|
|||
case _translate: |
|||
unit = "px"; |
|||
case _scale: |
|||
unit || ( unit = ""); |
|||
|
|||
transform = startVal[0] + "(" + |
|||
Math.round( (startVal[1][0] + (endVal[1][0] - startVal[1][0]) * pos) * precision ) / precision + unit +","+ |
|||
Math.round( (startVal[1][1] + (endVal[1][1] - startVal[1][1]) * pos) * precision ) / precision + unit + ")"+ |
|||
transform; |
|||
break; |
|||
|
|||
case _skew + "X": |
|||
case _skew + "Y": |
|||
case _rotate: |
|||
transform = startVal[0] + "(" + |
|||
Math.round( (startVal[1] + (endVal[1] - startVal[1]) * pos) * precision ) / precision +"rad)"+ |
|||
transform; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
fx.origin && ( transform = fx.origin + transform ); |
|||
|
|||
propertyHook && propertyHook.set ? |
|||
propertyHook.set( elem, transform, +true ): |
|||
elem.style[supportProperty] = transform; |
|||
}; |
|||
|
|||
/* |
|||
* Utility functions |
|||
*/ |
|||
|
|||
// turns a transform string into its "matrix(A,B,C,D,X,Y)" form (as an array, though)
|
|||
function matrix( transform ) { |
|||
transform = transform.split(")"); |
|||
var |
|||
trim = $.trim |
|||
, i = -1 |
|||
// last element of the array is an empty string, get rid of it
|
|||
, l = transform.length -1 |
|||
, split, prop, val |
|||
, prev = supportFloat32Array ? new Float32Array(6) : [] |
|||
, curr = supportFloat32Array ? new Float32Array(6) : [] |
|||
, rslt = supportFloat32Array ? new Float32Array(6) : [1,0,0,1,0,0] |
|||
; |
|||
|
|||
prev[0] = prev[3] = rslt[0] = rslt[3] = 1; |
|||
prev[1] = prev[2] = prev[4] = prev[5] = 0; |
|||
|
|||
// Loop through the transform properties, parse and multiply them
|
|||
while ( ++i < l ) { |
|||
split = transform[i].split("("); |
|||
prop = trim(split[0]); |
|||
val = split[1]; |
|||
curr[0] = curr[3] = 1; |
|||
curr[1] = curr[2] = curr[4] = curr[5] = 0; |
|||
|
|||
switch (prop) { |
|||
case _translate+"X": |
|||
curr[4] = parseInt(val, 10); |
|||
break; |
|||
|
|||
case _translate+"Y": |
|||
curr[5] = parseInt(val, 10); |
|||
break; |
|||
|
|||
case _translate: |
|||
val = val.split(","); |
|||
curr[4] = parseInt(val[0], 10); |
|||
curr[5] = parseInt(val[1] || 0, 10); |
|||
break; |
|||
|
|||
case _rotate: |
|||
val = toRadian(val); |
|||
curr[0] = Math.cos(val); |
|||
curr[1] = Math.sin(val); |
|||
curr[2] = -Math.sin(val); |
|||
curr[3] = Math.cos(val); |
|||
break; |
|||
|
|||
case _scale+"X": |
|||
curr[0] = +val; |
|||
break; |
|||
|
|||
case _scale+"Y": |
|||
curr[3] = val; |
|||
break; |
|||
|
|||
case _scale: |
|||
val = val.split(","); |
|||
curr[0] = val[0]; |
|||
curr[3] = val.length>1 ? val[1] : val[0]; |
|||
break; |
|||
|
|||
case _skew+"X": |
|||
curr[2] = Math.tan(toRadian(val)); |
|||
break; |
|||
|
|||
case _skew+"Y": |
|||
curr[1] = Math.tan(toRadian(val)); |
|||
break; |
|||
|
|||
case _matrix: |
|||
val = val.split(","); |
|||
curr[0] = val[0]; |
|||
curr[1] = val[1]; |
|||
curr[2] = val[2]; |
|||
curr[3] = val[3]; |
|||
curr[4] = parseInt(val[4], 10); |
|||
curr[5] = parseInt(val[5], 10); |
|||
break; |
|||
} |
|||
|
|||
// Matrix product (array in column-major order)
|
|||
rslt[0] = prev[0] * curr[0] + prev[2] * curr[1]; |
|||
rslt[1] = prev[1] * curr[0] + prev[3] * curr[1]; |
|||
rslt[2] = prev[0] * curr[2] + prev[2] * curr[3]; |
|||
rslt[3] = prev[1] * curr[2] + prev[3] * curr[3]; |
|||
rslt[4] = prev[0] * curr[4] + prev[2] * curr[5] + prev[4]; |
|||
rslt[5] = prev[1] * curr[4] + prev[3] * curr[5] + prev[5]; |
|||
|
|||
prev = [rslt[0],rslt[1],rslt[2],rslt[3],rslt[4],rslt[5]]; |
|||
} |
|||
return rslt; |
|||
} |
|||
|
|||
// turns a matrix into its rotate, scale and skew components
|
|||
// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp
|
|||
function unmatrix(matrix) { |
|||
var |
|||
scaleX |
|||
, scaleY |
|||
, skew |
|||
, A = matrix[0] |
|||
, B = matrix[1] |
|||
, C = matrix[2] |
|||
, D = matrix[3] |
|||
; |
|||
|
|||
// Make sure matrix is not singular
|
|||
if ( A * D - B * C ) { |
|||
// step (3)
|
|||
scaleX = Math.sqrt( A * A + B * B ); |
|||
A /= scaleX; |
|||
B /= scaleX; |
|||
// step (4)
|
|||
skew = A * C + B * D; |
|||
C -= A * skew; |
|||
D -= B * skew; |
|||
// step (5)
|
|||
scaleY = Math.sqrt( C * C + D * D ); |
|||
C /= scaleY; |
|||
D /= scaleY; |
|||
skew /= scaleY; |
|||
// step (6)
|
|||
if ( A * D < B * C ) { |
|||
A = -A; |
|||
B = -B; |
|||
skew = -skew; |
|||
scaleX = -scaleX; |
|||
} |
|||
|
|||
// matrix is singular and cannot be interpolated
|
|||
} else { |
|||
// In this case the elem shouldn't be rendered, hence scale == 0
|
|||
scaleX = scaleY = skew = 0; |
|||
} |
|||
|
|||
// The recomposition order is very important
|
|||
// see http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp#l971
|
|||
return [ |
|||
[_translate, [+matrix[4], +matrix[5]]], |
|||
[_rotate, Math.atan2(B, A)], |
|||
[_skew + "X", Math.atan(skew)], |
|||
[_scale, [scaleX, scaleY]] |
|||
]; |
|||
} |
|||
|
|||
// build the list of transform functions to interpolate
|
|||
// use the algorithm described at http://dev.w3.org/csswg/css3-2d-transforms/#animation
|
|||
function interpolationList( start, end ) { |
|||
var list = { |
|||
start: [], |
|||
end: [] |
|||
}, |
|||
i = -1, l, |
|||
currStart, currEnd, currType; |
|||
|
|||
// get rid of affine transform matrix
|
|||
( start == "none" || isAffine( start ) ) && ( start = "" ); |
|||
( end == "none" || isAffine( end ) ) && ( end = "" ); |
|||
|
|||
// if end starts with the current computed style, this is a relative animation
|
|||
// store computed style as the origin, remove it from start and end
|
|||
if ( start && end && !end.indexOf("matrix") && toArray( start ).join() == toArray( end.split(")")[0] ).join() ) { |
|||
list.origin = start; |
|||
start = ""; |
|||
end = end.slice( end.indexOf(")") +1 ); |
|||
} |
|||
|
|||
if ( !start && !end ) { return; } |
|||
|
|||
// start or end are affine, or list of transform functions are identical
|
|||
// => functions will be interpolated individually
|
|||
if ( !start || !end || functionList(start) == functionList(end) ) { |
|||
|
|||
start && ( start = start.split(")") ) && ( l = start.length ); |
|||
end && ( end = end.split(")") ) && ( l = end.length ); |
|||
|
|||
while ( ++i < l-1 ) { |
|||
start[i] && ( currStart = start[i].split("(") ); |
|||
end[i] && ( currEnd = end[i].split("(") ); |
|||
currType = $.trim( ( currStart || currEnd )[0] ); |
|||
|
|||
append( list.start, parseFunction( currType, currStart ? currStart[1] : 0 ) ); |
|||
append( list.end, parseFunction( currType, currEnd ? currEnd[1] : 0 ) ); |
|||
} |
|||
|
|||
// otherwise, functions will be composed to a single matrix
|
|||
} else { |
|||
list.start = unmatrix(matrix(start)); |
|||
list.end = unmatrix(matrix(end)) |
|||
} |
|||
|
|||
return list; |
|||
} |
|||
|
|||
function parseFunction( type, value ) { |
|||
var |
|||
// default value is 1 for scale, 0 otherwise
|
|||
defaultValue = +(!type.indexOf(_scale)), |
|||
scaleX, |
|||
// remove X/Y from scaleX/Y & translateX/Y, not from skew
|
|||
cat = type.replace( /e[XY]/, "e" ); |
|||
|
|||
switch ( type ) { |
|||
case _translate+"Y": |
|||
case _scale+"Y": |
|||
|
|||
value = [ |
|||
defaultValue, |
|||
value ? |
|||
parseFloat( value ): |
|||
defaultValue |
|||
]; |
|||
break; |
|||
|
|||
case _translate+"X": |
|||
case _translate: |
|||
case _scale+"X": |
|||
scaleX = 1; |
|||
case _scale: |
|||
|
|||
value = value ? |
|||
( value = value.split(",") ) && [ |
|||
parseFloat( value[0] ), |
|||
parseFloat( value.length>1 ? value[1] : type == _scale ? scaleX || value[0] : defaultValue+"" ) |
|||
]: |
|||
[defaultValue, defaultValue]; |
|||
break; |
|||
|
|||
case _skew+"X": |
|||
case _skew+"Y": |
|||
case _rotate: |
|||
value = value ? toRadian( value ) : 0; |
|||
break; |
|||
|
|||
case _matrix: |
|||
return unmatrix( value ? toArray(value) : [1,0,0,1,0,0] ); |
|||
break; |
|||
} |
|||
|
|||
return [[ cat, value ]]; |
|||
} |
|||
|
|||
function isAffine( matrix ) { |
|||
return rAffine.test(matrix); |
|||
} |
|||
|
|||
function functionList( transform ) { |
|||
return transform.replace(/(?:\([^)]*\))|\s/g, ""); |
|||
} |
|||
|
|||
function append( arr1, arr2, value ) { |
|||
while ( value = arr2.shift() ) { |
|||
arr1.push( value ); |
|||
} |
|||
} |
|||
|
|||
// converts an angle string in any unit to a radian Float
|
|||
function toRadian(value) { |
|||
return ~value.indexOf("deg") ? |
|||
parseInt(value,10) * (Math.PI * 2 / 360): |
|||
~value.indexOf("grad") ? |
|||
parseInt(value,10) * (Math.PI/200): |
|||
parseFloat(value); |
|||
} |
|||
|
|||
// Converts "matrix(A,B,C,D,X,Y)" to [A,B,C,D,X,Y]
|
|||
function toArray(matrix) { |
|||
// remove the unit of X and Y for Firefox
|
|||
matrix = /([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix); |
|||
return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]]; |
|||
} |
|||
|
|||
$.transform = { |
|||
centerOrigin: "margin" |
|||
}; |
|||
|
|||
})( jQuery, window, document, Math ); |
@ -0,0 +1,92 @@ |
|||
/* |
|||
* transform: A jQuery cssHooks adding 2D/3D transform capabilities to $.fn.css() and $.fn.animate() |
|||
* |
|||
* Requirements: |
|||
* - jQuery 1.5.1+ |
|||
* - jquery.transition.js for animations |
|||
* - browser implementing W3C's CSS 2DTransforms for 2D tranform |
|||
* - browser implementing W3C's CSS 3DTransforms for 3D tranform |
|||
* |
|||
* latest version and complete README available on Github: |
|||
* https://github.com/louisremi/jquery.transform.js
|
|||
* |
|||
* Copyright 2011 @louis_remi |
|||
* Licensed under the MIT license. |
|||
* |
|||
* This saved you an hour of work? |
|||
* Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
|
|||
* |
|||
*/ |
|||
(function( $, window, document ) { |
|||
"use strict"; |
|||
|
|||
var div = document.createElement("div"), |
|||
divStyle = div.style, |
|||
prefixes = [ |
|||
"O", |
|||
"ms", |
|||
"Webkit", |
|||
"Moz" |
|||
], |
|||
prefix, |
|||
i = prefixes.length, |
|||
properties = [ |
|||
"transform", |
|||
"transformOrigin", |
|||
"transformStyle", |
|||
"perspective", |
|||
"perspectiveOrigin", |
|||
"backfaceVisibility" |
|||
], |
|||
property, |
|||
j = prefixes.length; |
|||
|
|||
// Find the right prefix
|
|||
while ( i-- ) { |
|||
if ( prefixes[i] + leadingUppercase( properties[0] ) in divStyle ) { |
|||
prefix = prefixes[i]; |
|||
continue; |
|||
} |
|||
} |
|||
|
|||
// This browser is not compatible with transforms
|
|||
if ( !prefix ) { return; } |
|||
|
|||
// Build cssHooks for each property
|
|||
while ( j-- ) { |
|||
property = prefix + leadingUppercase( properties[j] ); |
|||
|
|||
if ( property in divStyle ) { |
|||
|
|||
// px isn't the default unit of this property
|
|||
$.cssNumber[ properties[j] ] = true; |
|||
|
|||
// populate cssProps
|
|||
$.cssProps[ properties[j] ] = property; |
|||
|
|||
// MozTranform requires a complete hook because "px" is required in translate
|
|||
property === "MozTransform" && ($.cssHooks[ properties[j] ] = { |
|||
get: function( elem, computed ) { |
|||
return (computed ? |
|||
// remove "px" from the computed matrix
|
|||
$.css( elem, property ).split("px").join(""): |
|||
elem.style[property] |
|||
); |
|||
}, |
|||
set: function( elem, value ) { |
|||
// add "px" to matrices
|
|||
/matrix\([^)p]*\)/.test(value) && ( |
|||
value = value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, "matrix$1$2px,$3px") |
|||
); |
|||
elem.style[property] = value; |
|||
} |
|||
}); |
|||
|
|||
} |
|||
} |
|||
|
|||
function leadingUppercase( word ) { |
|||
return word.slice(0,1).toUpperCase() + word.slice(1); |
|||
} |
|||
|
|||
})( jQuery, window, document ); |
@ -0,0 +1,114 @@ |
|||
/******************************* |
|||
Origami Module |
|||
*******************************/ |
|||
|
|||
.origami.module { |
|||
position: relative; |
|||
|
|||
-webkit-perspective: 2000px; |
|||
-moz-perspective: 2000px; |
|||
-ms-perspective: 2000px; |
|||
perspective: 2000px; |
|||
} |
|||
|
|||
.origami.module .box { |
|||
-webkit-transform-style: preserve-3d; |
|||
-moz-transform-style: preserve-3d; |
|||
-ms-transform-style: preserve-3d; |
|||
transform-style: preserve-3d; |
|||
} |
|||
|
|||
.origami.module .side { |
|||
display: none; |
|||
opacity: 1; |
|||
width: 100%; |
|||
background-color: #FFFFFF; |
|||
|
|||
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.3); |
|||
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.3); |
|||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.3); |
|||
|
|||
-webkit-box-sizing: border-box; |
|||
-moz-box-sizing: border-box; |
|||
-ms-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
|
|||
-webkit-backface-visibility: hidden; |
|||
-moz-backface-visibility: hidden; |
|||
-ms-backface-visibility: hidden; |
|||
backface-visibility: hidden; |
|||
} |
|||
|
|||
/* Handle (Stubbed as image will fix) */ |
|||
.origami.module .handle { |
|||
cursor: pointer; |
|||
position: absolute; |
|||
bottom: -28px; |
|||
right: 50%; |
|||
|
|||
margin-left: -22px; |
|||
width: 44px; |
|||
height: 44px; |
|||
background: url(/images/modules/origami-handle.png) no-repeat 0px 0px; |
|||
} |
|||
.origami.module .down.handle { |
|||
background-position: 0px -50px; |
|||
} |
|||
|
|||
|
|||
/*--------------- |
|||
States |
|||
----------------*/ |
|||
|
|||
/* Animating */ |
|||
.origami.module.animating .box { |
|||
position: absolute; |
|||
} |
|||
.origami.module .animating.side { |
|||
position: absolute; |
|||
width: 100%; |
|||
top: 0px; |
|||
left: 0px; |
|||
z-index: 100; |
|||
} |
|||
.origami.module .hidden.side { |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
/* Animate using CSS */ |
|||
.origami.css.module { |
|||
-webkit-transition: |
|||
all 0.5s ease-in-out; |
|||
; |
|||
-moz-transition: |
|||
all 0.5s ease-in-out; |
|||
; |
|||
-o-transition: |
|||
all 0.5s ease-in-out; |
|||
; |
|||
-ms-transition: |
|||
all 0.5s ease-in-out; |
|||
; |
|||
transition: |
|||
all 0.5s ease-in-out; |
|||
; |
|||
} |
|||
.origami.css.module .box { |
|||
-webkit-transition: all 0.5s ease-in-out; |
|||
-moz-transition: all 0.5s ease-in-out; |
|||
-o-transition: all 0.5s ease-in-out; |
|||
-ms-transition: all 0.5s ease-in-out; |
|||
transition: all 0.5s ease-in-out; |
|||
} |
|||
.origami.css.module .side { |
|||
-webkit-transition: opacity 0.5s ease-out; |
|||
-moz-transition: opacity 0.5s ease-out; |
|||
-o-transition: opacity 0.5s ease-out; |
|||
-ms-transition: opacity 0.5s ease-out; |
|||
transition: opacity 0.5s ease-out; |
|||
} |
|||
|
|||
/* Active */ |
|||
.origami.module .active.side { |
|||
display: block; |
|||
} |
@ -0,0 +1,502 @@ |
|||
/* ****************************** |
|||
Module |
|||
Origami |
|||
Author: Jack Lukic |
|||
Created: Mar 28, 2013 |
|||
Last revision: Mar 2013 |
|||
|
|||
Creates a cube which can be rotated |
|||
|
|||
Usage: |
|||
|
|||
$origami |
|||
.origami() |
|||
; |
|||
|
|||
$origami |
|||
.origami('flip.up') |
|||
; |
|||
|
|||
****************************** */ |
|||
|
|||
;(function ( $, window, document, undefined ) { |
|||
|
|||
$.fn.origami = function(parameters) { |
|||
var |
|||
$allModules = $(this), |
|||
|
|||
settings = $.extend(true, {}, $.fn.origami.settings, parameters), |
|||
// make arguments available
|
|||
query = arguments[0], |
|||
passedArguments = [].slice.call(arguments, 1), |
|||
invokedResponse |
|||
; |
|||
$allModules |
|||
.each(function() { |
|||
var |
|||
// selector cache
|
|||
$module = $(this), |
|||
$box = $module.find(settings.selector.box), |
|||
$side = $module.find(settings.selector.side), |
|||
|
|||
$activeSide, |
|||
$nextSide, |
|||
|
|||
// private variables
|
|||
selector = $module.selector || '', |
|||
element = this, |
|||
instance = $module.data('module-' + settings.namespace), |
|||
methodInvoked = (typeof query == 'string'), |
|||
|
|||
endTransition = 'transitionend msTransitionEnd oTransitionEnd', |
|||
|
|||
// shortcuts
|
|||
namespace = settings.namespace, |
|||
metadata = settings.metadata, |
|||
className = settings.className, |
|||
|
|||
module |
|||
; |
|||
module = { |
|||
|
|||
initialize: function() { |
|||
module.verbose('Initializing module for', element); |
|||
module.set.defaultSide(); |
|||
$module |
|||
.data('module-' + namespace, module) |
|||
; |
|||
}, |
|||
|
|||
destroy: function() { |
|||
module.verbose('Destroying previous module for', element); |
|||
$module |
|||
.off('.' + namespace) |
|||
; |
|||
}, |
|||
|
|||
refresh: function() { |
|||
module.verbose('Refreshing selector cache for', element); |
|||
$module = $(element); |
|||
$box = $(this).find(settings.selector.box); |
|||
$side = $(this).find(settings.selector.side); |
|||
}, |
|||
|
|||
repaint: function() { |
|||
var |
|||
fakeAssignment = $module.get(0).offsetWidth |
|||
; |
|||
}, |
|||
|
|||
animate: function(propertyObject) { |
|||
module.verbose('Animating box with properties', propertyObject); |
|||
var |
|||
callback = function() { |
|||
module.reset(); |
|||
module.set.active(); |
|||
} |
|||
; |
|||
if(settings.useCSS) { |
|||
module.verbose('Using CSS transitions to animate'); |
|||
$module |
|||
.addClass(className.animating) |
|||
; |
|||
module.set.stageSize(); |
|||
module.repaint(); |
|||
$module |
|||
.addClass(className.css) |
|||
; |
|||
$activeSide |
|||
.addClass(className.hidden) |
|||
; |
|||
$box |
|||
.css(propertyObject) |
|||
.one(endTransition, callback) |
|||
; |
|||
} |
|||
else { |
|||
// not yet supported until .animate() is extended to allow RotateX/Y
|
|||
module.verbose('Using javascript to animate'); |
|||
$module |
|||
.addClass(className.animating) |
|||
.removeClass(className.css) |
|||
; |
|||
module.set.stageSize(); |
|||
module.repaint(); |
|||
$activeSide |
|||
.animate({ |
|||
opacity: 0 |
|||
}, settings.duration, settings.easing) |
|||
; |
|||
$box |
|||
.animate(propertyObject, settings.duration, settings.easing, callback) |
|||
; |
|||
} |
|||
}, |
|||
|
|||
reset: function() { |
|||
module.verbose('Animating states reset'); |
|||
$module |
|||
.removeClass(className.css) |
|||
.removeClass(className.animating) |
|||
.removeAttr('style') |
|||
; |
|||
$box |
|||
.removeAttr('style') |
|||
; |
|||
$side |
|||
.removeAttr('style') |
|||
.removeClass(className.hidden) |
|||
; |
|||
$nextSide |
|||
.removeClass(className.animating) |
|||
.removeAttr('style') |
|||
; |
|||
}, |
|||
|
|||
set: { |
|||
|
|||
defaultSide: function() { |
|||
$activeSide = $module.find('.' + settings.className.active); |
|||
$nextSide = ( $activeSide.next(settings.selector.side).size() > 0 ) |
|||
? $activeSide.next(settings.selector.side) |
|||
: $module.find(settings.selector.side).first() |
|||
; |
|||
module.verbose('Active side set to', $activeSide); |
|||
module.verbose('Next side set to', $nextSide); |
|||
}, |
|||
|
|||
stageSize: function() { |
|||
$module |
|||
.css({ |
|||
width : $nextSide.outerWidth(), |
|||
height : $nextSide.outerHeight() |
|||
}) |
|||
; |
|||
}, |
|||
|
|||
nextSide: function(selector) { |
|||
$nextSide = $module.find(selector); |
|||
module.verbose('Next side manually set to', $nextSide); |
|||
}, |
|||
|
|||
active: function() { |
|||
module.verbose('Setting new side to active', $nextSide); |
|||
$side |
|||
.removeClass(className.active) |
|||
; |
|||
$nextSide |
|||
.addClass(className.active) |
|||
; |
|||
module.set.defaultSide(); |
|||
} |
|||
|
|||
}, |
|||
|
|||
getTransform: { |
|||
up: function() { |
|||
var |
|||
translate = { |
|||
y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
|||
z: -($activeSide.outerHeight() / 2) |
|||
} |
|||
; |
|||
return { |
|||
transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)' |
|||
}; |
|||
}, |
|||
down: function() { |
|||
var |
|||
translate = { |
|||
y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
|||
z: -($activeSide.outerHeight() / 2) |
|||
} |
|||
; |
|||
return { |
|||
transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)' |
|||
}; |
|||
}, |
|||
left: function() { |
|||
var |
|||
translate = { |
|||
x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2), |
|||
z : -($activeSide.outerWidth() / 2) |
|||
} |
|||
; |
|||
return { |
|||
transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)' |
|||
}; |
|||
}, |
|||
right: function() { |
|||
var |
|||
translate = { |
|||
x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2), |
|||
z : -($activeSide.outerWidth() / 2) |
|||
} |
|||
; |
|||
return { |
|||
transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)' |
|||
}; |
|||
} |
|||
}, |
|||
|
|||
stage: { |
|||
above: function() { |
|||
var |
|||
box = { |
|||
origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
|||
depth : { |
|||
active : ($nextSide.outerHeight() / 2), |
|||
next : ($activeSide.outerHeight() / 2) |
|||
} |
|||
} |
|||
; |
|||
module.verbose('Setting the initial animation position as above', $nextSide, box); |
|||
$activeSide |
|||
.css({ |
|||
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
|||
}) |
|||
; |
|||
$nextSide |
|||
.addClass(className.animating) |
|||
.css({ |
|||
'display' : 'block', |
|||
'top' : box.origin + 'px', |
|||
'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)' |
|||
}) |
|||
; |
|||
}, |
|||
below: function() { |
|||
var |
|||
box = { |
|||
origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
|||
depth : { |
|||
active : ($nextSide.outerHeight() / 2), |
|||
next : ($activeSide.outerHeight() / 2) |
|||
} |
|||
} |
|||
; |
|||
module.verbose('Setting the initial animation position as below', $nextSide, box); |
|||
$activeSide |
|||
.css({ |
|||
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
|||
}) |
|||
; |
|||
$nextSide |
|||
.addClass(className.animating) |
|||
.css({ |
|||
'display' : 'block', |
|||
'top' : box.origin + 'px', |
|||
'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)' |
|||
}) |
|||
; |
|||
}, |
|||
left: function() { |
|||
var |
|||
box = { |
|||
origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2), |
|||
depth : { |
|||
active : ($nextSide.outerWidth() / 2), |
|||
next : ($activeSide.outerWidth() / 2) |
|||
} |
|||
} |
|||
; |
|||
module.verbose('Setting the initial animation position as left', $nextSide, box); |
|||
$activeSide |
|||
.css({ |
|||
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
|||
}) |
|||
; |
|||
$nextSide |
|||
.addClass(className.animating) |
|||
.css({ |
|||
'display' : 'block', |
|||
'left' : box.origin + 'px', |
|||
'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)' |
|||
}) |
|||
; |
|||
}, |
|||
right: function() { |
|||
var |
|||
box = { |
|||
origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2), |
|||
depth : { |
|||
active : ($nextSide.outerWidth() / 2), |
|||
next : ($activeSide.outerWidth() / 2) |
|||
} |
|||
} |
|||
; |
|||
module.verbose('Setting the initial animation position as left', $nextSide, box); |
|||
$activeSide |
|||
.css({ |
|||
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
|||
}) |
|||
; |
|||
$nextSide |
|||
.addClass(className.animating) |
|||
.css({ |
|||
'display' : 'block', |
|||
'left' : box.origin + 'px', |
|||
'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)' |
|||
}) |
|||
; |
|||
} |
|||
}, |
|||
|
|||
flip: { |
|||
up: function() { |
|||
module.debug('Flipping up', $nextSide); |
|||
module.stage.above(); |
|||
module.animate( module.getTransform.up(), element); |
|||
}, |
|||
down: function() { |
|||
module.debug('Flipping down', $nextSide); |
|||
module.stage.below(); |
|||
module.animate( module.getTransform.down(), element); |
|||
}, |
|||
left: function() { |
|||
module.debug('Flipping left', $nextSide); |
|||
module.stage.left(); |
|||
module.animate(module.getTransform.left(), element); |
|||
|
|||
}, |
|||
right: function() { |
|||
module.debug('Flipping right', $nextSide); |
|||
module.stage.right(); |
|||
module.animate(module.getTransform.right(), element); |
|||
} |
|||
}, |
|||
|
|||
/* standard module */ |
|||
setting: function(name, value) { |
|||
if(value === undefined) { |
|||
return settings[name]; |
|||
} |
|||
settings[name] = value; |
|||
}, |
|||
verbose: function() { |
|||
if(settings.verbose) { |
|||
module.debug.apply(this, arguments); |
|||
} |
|||
}, |
|||
debug: function() { |
|||
var |
|||
output = [], |
|||
message = settings.moduleName + ': ' + arguments[0], |
|||
variables = [].slice.call( arguments, 1 ), |
|||
log = console.info || console.log || function(){} |
|||
; |
|||
log = Function.prototype.bind.call(log, console); |
|||
if(settings.debug) { |
|||
output.push(message); |
|||
log.apply(console, output.concat(variables) ); |
|||
} |
|||
}, |
|||
error: function() { |
|||
var |
|||
output = [], |
|||
errorMessage = settings.moduleName + ': ' + arguments[0], |
|||
variables = [].slice.call( arguments, 1 ), |
|||
log = console.warn || console.log || function(){} |
|||
; |
|||
log = Function.prototype.bind.call(log, console); |
|||
if(settings.debug) { |
|||
output.push(errorMessage); |
|||
output.concat(variables); |
|||
log.apply(console, output.concat(variables) ); |
|||
} |
|||
}, |
|||
invoke: function(query, context, passedArguments) { |
|||
var |
|||
maxDepth, |
|||
found |
|||
; |
|||
passedArguments = passedArguments || [].slice.call( arguments, 2 ); |
|||
if(typeof query == 'string' && instance !== undefined) { |
|||
query = query.split('.'); |
|||
maxDepth = query.length - 1; |
|||
$.each(query, function(depth, value) { |
|||
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) { |
|||
instance = instance[value]; |
|||
return true; |
|||
} |
|||
else if( instance[value] !== undefined ) { |
|||
found = instance[value]; |
|||
return true; |
|||
} |
|||
module.error(settings.errors.method); |
|||
return false; |
|||
}); |
|||
} |
|||
if ( $.isFunction( found ) ) { |
|||
return found.apply(context, passedArguments); |
|||
} |
|||
// return retrieved variable or chain
|
|||
return found; |
|||
} |
|||
}; |
|||
|
|||
// check for invoking internal method
|
|||
if(methodInvoked) { |
|||
invokedResponse = module.invoke(query, this, passedArguments); |
|||
} |
|||
// otherwise initialize
|
|||
else { |
|||
if(instance !== undefined) { |
|||
module.destroy(); |
|||
} |
|||
module.initialize(); |
|||
} |
|||
}) |
|||
; |
|||
// chain or return queried method
|
|||
return (invokedResponse !== undefined) |
|||
? invokedResponse |
|||
: this |
|||
; |
|||
}; |
|||
|
|||
$.fn.origami.settings = { |
|||
|
|||
// module info
|
|||
moduleName : 'Origami Module', |
|||
|
|||
// debug output
|
|||
debug : true, |
|||
// verbose debug output
|
|||
verbose : true, |
|||
|
|||
namespace : 'origami', |
|||
|
|||
// callback occurs on side change
|
|||
onChange : function() {}, |
|||
|
|||
useCSS : true, |
|||
duration : 1000, |
|||
easing : 'easeInOutQuad', |
|||
|
|||
errors: { |
|||
api : 'You tried to switch to a side that does not exist.', |
|||
method : 'The method you called is not defined' |
|||
}, |
|||
|
|||
metadata : { |
|||
|
|||
}, |
|||
|
|||
className : { |
|||
css : 'css', |
|||
animating : 'animating', |
|||
hidden : 'hidden', |
|||
active : 'active' |
|||
}, |
|||
|
|||
selector : { |
|||
box : '.box', |
|||
side : '.side' |
|||
} |
|||
|
|||
}; |
|||
|
|||
|
|||
|
|||
})( jQuery, window , document ); |
Write
Preview
Loading…
Cancel
Save