Permalink
Browse files

added rotate3Di.js and dependency submodule

  • Loading branch information...
1 parent 76b15d4 commit 08e863d7ee205393d55280376e0ddd90adfb20b5 @zachstronaut committed Nov 27, 2010
Showing with 146 additions and 1 deletion.
  1. +3 −0 .gitmodules
  2. +4 −1 README
  3. +1 −0 jquery-css-transform
  4. +138 −0 rotate3Di.js
View
@@ -0,0 +1,3 @@
+[submodule "jquery-css-transform"]
+ path = jquery-css-transform
+ url = git@github.com:zachstronaut/jquery-css-transform.git
View
5 README
@@ -23,5 +23,8 @@ under both MIT and GPL licenses, just like jQuery.
Change Log
-----------------------------
-2010.11.26 - Added to GitHub
+2010.11.26 - Added to GitHub, including updated dependencies to enabled
+ IE9 (Platform Preview 7+) support
+
+2009.03.11 - First release of project as rotate3Di v0.9
Submodule jquery-css-transform added at 776f3b
View
@@ -0,0 +1,138 @@
+(function ($) {
+ // rotate3Di v0.9 - 2009.03.11 Zachary Johnson www.zachstronaut.com
+ // "3D" isometric rotation and animation using CSS3 transformations
+ // currently supported in Safari/WebKit/Chrome, Firefox 3.5+,
+ // IE9 (Platform Preview 7+), and probably Opera.
+
+ var calcRotate3Di = {
+ direction: function (now) {return (now < 0 ? -1 : 1);},
+ degrees: function (now) {return (Math.floor(Math.abs(now))) % 360;},
+ scale: function (degrees) {return (1 - (degrees % 180) / 90)
+ * (degrees >= 180 ? -1 : 1);}
+ }
+
+ // Custom animator
+ $.fx.step.rotate3Di = function (fx) {
+ direction = calcRotate3Di.direction(fx.now);
+ degrees = calcRotate3Di.degrees(fx.now);
+ scale = calcRotate3Di.scale(degrees);
+
+ if (fx.options && typeof fx.options['sideChange'] != 'undefined') {
+ if (fx.options['sideChange']) {
+ var prevScale = $(fx.elem).data('rotate3Di.prevScale');
+
+ // negative scale means back side
+ // positive scale means front side
+ // if one is pos and one is neg then we have changed sides
+ // (but one could actually be zero).
+ if (scale * prevScale <= 0) {
+ // if one was zero, deduce from the other which way we are
+ // flipping: to the front (pos) or to the back (neg)?
+ fx.options['sideChange'].call(
+ fx.elem,
+ (scale > 0 || prevScale < 0)
+ );
+ // this was commented out to prevent calling it more than
+ // once, but then that broke legitimate need to call it
+ // more than once for rotations of 270+ degrees!
+ //fx.options['sideChange'] = null;
+
+ // this is my answer to commenting the above thing out...
+ // if we just flipped sides, flip-flop the old previous
+ // scale so that we can fire the sideChange event correctly
+ // if we flip sides again.
+ $(fx.elem).data(
+ 'rotate3Di.prevScale',
+ $(fx.elem).data('rotate3Di.prevScale') * -1
+ );
+ }
+ }
+
+ // Making scale positive before setting it prevents flip-side
+ // content from showing up mirrored/reversed.
+ scale = Math.abs(scale);
+ }
+
+ // Since knowing the current degrees is important for detecting side
+ // change, and since Firefox 3.0.x seems to not be able to reliably get
+ // a value for css('transform') the first time after the page is loaded
+ // with my flipbox demo... I am storing degrees someplace where I know
+ // I can get them.
+ $(fx.elem).data('rotate3Di.degrees', direction * degrees);
+ $(fx.elem).css(
+ 'transform',
+ 'skew(0deg, ' + direction * degrees + 'deg)'
+ + ' scale(' + scale + ', 1)'
+ );
+ }
+
+ // fx.cur() must be monkey patched because otherwise it would always
+ // return 0 for current rotate3Di value
+ var proxied = $.fx.prototype.cur;
+ $.fx.prototype.cur = function () {
+ if(this.prop == 'rotate3Di') {
+ var style = $(this.elem).css('transform');
+ if (style) {
+ var m = style.match(/, (-?[0-9]+)deg\)/);
+ if (m && m[1]) {
+ return parseInt(m[1]);
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ return proxied.apply(this, arguments);
+ }
+
+ $.fn.rotate3Di = function (degrees, duration, options) {
+ if (typeof duration == 'undefined') {
+ duration = 0;
+ }
+
+ if (typeof options == 'object') {
+ $.extend(options, {duration: duration});
+ } else {
+ options = {duration: duration};
+ }
+
+ if (degrees == 'toggle') {
+ // Yes, jQuery has the toggle() event but that's only good for
+ // clicks, and likewise hover() is only good for mouse in/out.
+ // What if you want to toggle based on a timer or something else?
+ if ($(this).data('rotate3Di.flipped')) {
+ degrees = 'unflip';
+
+ } else {
+ degrees = 'flip';
+ }
+ }
+
+ if (degrees == 'flip') {
+ $(this).data('rotate3Di.flipped', true);
+
+ var direction = -1;
+ if (
+ typeof options == 'object'
+ && options['direction']
+ && options['direction'] == 'clockwise'
+ ) {
+ direction = 1;
+ }
+
+ degrees = direction * 180;
+
+ } else if (degrees == 'unflip') {
+ $(this).data('rotate3Di.flipped', false);
+
+ degrees = 0;
+ }
+
+ var d = $(this).data('rotate3Di.degrees') || 0;
+ $(this).data(
+ 'rotate3Di.prevScale',
+ calcRotate3Di.scale(calcRotate3Di.degrees(d))
+ );
+ $(this).animate({rotate3Di: degrees}, options);
+ }
+})(jQuery);

0 comments on commit 08e863d

Please sign in to comment.