Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial CSS3 animation support with move.js and a test on modal windows

  • Loading branch information...
commit f68af74a9ec0f04702d9777065ffadd6076808f0 1 parent 371054e
@mattpardee mattpardee authored
Showing with 648 additions and 0 deletions.
  1. +642 −0 core/lib/tween.js
  2. +6 −0 elements/modalwindow.js
View
642 core/lib/tween.js
@@ -21,6 +21,648 @@
// #ifdef __WITH_TWEEN
+/*!
+ * move
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+;(function(exports){
+
+ /**
+ * Computed style.
+ */
+
+ var current = window.getComputedStyle || window.currentStyle;
+
+ /**
+ * Map of prop -> type for numeric values.
+ */
+
+ var map = {
+ 'top': 'px'
+ , 'bottom': 'px'
+ , 'left': 'px'
+ , 'right': 'px'
+ , 'width': 'px'
+ , 'height': 'px'
+ , 'font-size': 'px'
+ , 'margin': 'px'
+ , 'margin-top': 'px'
+ , 'margin-bottom': 'px'
+ , 'margin-left': 'px'
+ , 'margin-right': 'px'
+ , 'padding': 'px'
+ , 'padding-top': 'px'
+ , 'padding-bottom': 'px'
+ , 'padding-left': 'px'
+ , 'padding-right': 'px'
+ };
+
+ /**
+ * Initialize a `Move` instance with the given `selector`.
+ *
+ * @param {String} selector
+ * @return {Move}
+ * @api public
+ */
+
+ exports.move = function(selector) {
+ return new Move(move.select(selector));
+ };
+
+ /**
+ * Library version.
+ */
+
+ exports.move.version = '0.0.3';
+
+ /**
+ * Defaults.
+ *
+ * `duration` - default duration of 500ms
+ *
+ */
+
+ move.defaults = {
+ duration: 1500
+ };
+
+ /**
+ * Easing functions.
+ */
+
+ move.ease = {
+ 'in': 'ease-in'
+ , 'out': 'ease-out'
+ , 'in-out': 'ease-in-out'
+ , 'snap': 'cubic-bezier(0,1,.5,1)'
+ , 'linear': 'cubic-bezier(0.250, 0.250, 0.750, 0.750)'
+ , 'ease-in-quad': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)'
+ , 'ease-in-cubic': 'cubic-bezier(0.550, 0.055, 0.675, 0.190)'
+ , 'ease-in-quart': 'cubic-bezier(0.895, 0.030, 0.685, 0.220)'
+ , 'ease-in-quint': 'cubic-bezier(0.755, 0.050, 0.855, 0.060)'
+ , 'ease-in-sine': 'cubic-bezier(0.470, 0.000, 0.745, 0.715)'
+ , 'ease-in-expo': 'cubic-bezier(0.950, 0.050, 0.795, 0.035)'
+ , 'ease-in-circ': 'cubic-bezier(0.600, 0.040, 0.980, 0.335)'
+ , 'ease-in-back': 'cubic-bezier(0.600, -0.280, 0.735, 0.045)'
+ , 'ease-out-quad': 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'
+ , 'ease-out-cubic': 'cubic-bezier(0.215, 0.610, 0.355, 1.000)'
+ , 'ease-out-quart': 'cubic-bezier(0.165, 0.840, 0.440, 1.000)'
+ , 'ease-out-quint': 'cubic-bezier(0.230, 1.000, 0.320, 1.000)'
+ , 'ease-out-sine': 'cubic-bezier(0.390, 0.575, 0.565, 1.000)'
+ , 'ease-out-expo': 'cubic-bezier(0.190, 1.000, 0.220, 1.000)'
+ , 'ease-out-circ': 'cubic-bezier(0.075, 0.820, 0.165, 1.000)'
+ , 'ease-out-back': 'cubic-bezier(0.175, 0.885, 0.320, 1.275)'
+ , 'ease-out-quad': 'cubic-bezier(0.455, 0.030, 0.515, 0.955)'
+ , 'ease-out-cubic': 'cubic-bezier(0.645, 0.045, 0.355, 1.000)'
+ , 'ease-in-out-quart': 'cubic-bezier(0.770, 0.000, 0.175, 1.000)'
+ , 'ease-in-out-quint': 'cubic-bezier(0.860, 0.000, 0.070, 1.000)'
+ , 'ease-in-out-sine': 'cubic-bezier(0.445, 0.050, 0.550, 0.950)'
+ , 'ease-in-out-expo': 'cubic-bezier(1.000, 0.000, 0.000, 1.000)'
+ , 'ease-in-out-circ': 'cubic-bezier(0.785, 0.135, 0.150, 0.860)'
+ , 'ease-in-out-back': 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'
+ };
+
+ /**
+ * Default element selection utilized by `move(selector)`.
+ *
+ * Override to implement your own selection, for example
+ * with jQuery one might write:
+ *
+ * move.select = function(selector) {
+ * return jQuery(selector).get(0);
+ * };
+ *
+ * @param {Object|String} selector
+ * @return {Element}
+ * @api public
+ */
+
+ move.select = function(selector){
+ if ('string' != typeof selector) return selector;
+ return document.getElementById(selector)
+ || document.querySelectorAll(selector)[0];
+ };
+
+ /**
+ * EventEmitter.
+ */
+
+ function EventEmitter() {
+ this.callbacks = {};
+ }
+
+ /**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ */
+
+ EventEmitter.prototype.on = function(event, fn){
+ (this.callbacks[event] = this.callbacks[event] || [])
+ .push(fn);
+ return this;
+ };
+
+ /**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ */
+
+ EventEmitter.prototype.emit = function(event){
+ var args = Array.prototype.slice.call(arguments, 1)
+ , callbacks = this.callbacks[event]
+ , len;
+
+ if (callbacks) {
+ len = callbacks.length;
+ for (var i = 0; i < len; ++i) {
+ callbacks[i].apply(this, args)
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Initialize a new `Move` with the given `el`.
+ *
+ * @param {Element} el
+ * @api public
+ */
+
+ exports.Move = function Move(el) {
+ if (!(this instanceof Move)) return new Move(el);
+ EventEmitter.call(this);
+ this.el = el;
+ this._props = {};
+ this._rotate = 0;
+ this._transitionProps = [];
+ this._transforms = [];
+ // Use hardware acceleration in webkit
+ this._transforms.push("translateZ(0)");
+ this.duration(move.defaults.duration)
+ };
+
+ /**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+ Move.prototype = new EventEmitter;
+ Move.prototype.constructor = Move;
+
+ /**
+ * Buffer `transform`.
+ *
+ * @param {String} transform
+ * @return {Move} for chaining
+ * @api private
+ */
+
+ Move.prototype.transform = function(transform){
+ this._transforms.push(transform);
+ return this;
+ };
+
+ /**
+ * Skew `x` and `y`.
+ *
+ * @param {Number} x
+ * @param {Number} y
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.skew = function(x, y){
+ y = y || 0;
+ return this.transform('skew('
+ + x + 'deg, '
+ + y + 'deg)');
+ };
+
+ /**
+ * Skew x by `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.skewX = function(n){
+ return this.transform('skewX(' + n + 'deg)');
+ };
+
+ /**
+ * Skew y by `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.skewY = function(n){
+ return this.transform('skewY(' + n + 'deg)');
+ };
+
+ /**
+ * Translate `x` and `y` axis.
+ *
+ * @param {Number} x
+ * @param {Number} y
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.translate =
+ Move.prototype.to = function(x, y){
+ y = y || 0;
+ return this.transform('translate('
+ + x + 'px, '
+ + y + 'px)');
+ };
+
+ /**
+ * Translate on the x axis to `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.translateX =
+ Move.prototype.x = function(n){
+ return this.transform('translateX(' + n + 'px)');
+ };
+
+ /**
+ * Translate on the y axis to `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.translateY =
+ Move.prototype.y = function(n){
+ return this.transform('translateY(' + n + 'px)');
+ };
+
+ /**
+ * Scale the x and y axis by `x`, or
+ * individually scale `x` and `y`.
+ *
+ * @param {Number} x
+ * @param {Number} y
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.scale = function(x, y){
+ y = null == y ? x : y;
+ return this.transform('scale('
+ + x + ', '
+ + y + ')');
+ };
+
+ /**
+ * Scale x axis by `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.scaleX = function(n){
+ return this.transform('scaleX(' + n + ')')
+ };
+
+ /**
+ * Scale y axis by `n`.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.scaleY = function(n){
+ return this.transform('scaleY(' + n + ')')
+ };
+
+ /**
+ * Rotate `n` degrees.
+ *
+ * @param {Number} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.rotate = function(n){
+ return this.transform('rotate(' + n + 'deg)');
+ };
+
+ /**
+ * Set transition easing function to to `fn` string.
+ *
+ * When:
+ *
+ * - null "ease" is used
+ * - "in" "ease-in" is used
+ * - "out" "ease-out" is used
+ * - "in-out" "ease-in-out" is used
+ *
+ * @param {String} fn
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.ease = function(fn){
+ fn = move.ease[fn] || fn || 'ease';
+ return this.setVendorProperty('transition-timing-function', fn);
+ };
+
+ /**
+ * Set animation properties
+ *
+ * @param {String} name
+ * @param {Object} props
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.animate = function(name, props){
+ for (var i in props){
+ if (props.hasOwnProperty(i)){
+ this.setVendorProperty('animation-' + i, props[i])
+ }
+ }
+ return this.setVendorProperty('animation-name', name);
+ }
+
+ /**
+ * Set duration to `n`.
+ *
+ * @param {Number|String} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.duration = function(n){
+ n = this._duration = 'string' == typeof n
+ ? parseFloat(n) * 1000
+ : n;
+ return this.setVendorProperty('transition-duration', n + 'ms');
+ };
+
+ /**
+ * Delay the animation by `n`.
+ *
+ * @param {Number|String} n
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.delay = function(n){
+ n = 'string' == typeof n
+ ? parseFloat(n) * 1000
+ : n;
+ return this.setVendorProperty('transition-delay', n + 'ms');
+ };
+
+ /**
+ * Set `prop` to `val`, deferred until `.end()` is invoked.
+ *
+ * @param {String} prop
+ * @param {String} val
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.setProperty = function(prop, val){
+ this._props[prop] = val;
+ return this;
+ };
+
+ /**
+ * Set a vendor prefixed `prop` with the given `val`.
+ *
+ * @param {String} prop
+ * @param {String} val
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.setVendorProperty = function(prop, val){
+ this.setProperty('-webkit-' + prop, val);
+ this.setProperty('-moz-' + prop, val);
+ this.setProperty('-ms-' + prop, val);
+ this.setProperty('-o-' + prop, val);
+ return this;
+ };
+
+ /**
+ * Set `prop` to `value`, deferred until `.end()` is invoked
+ * and adds the property to the list of transition props.
+ *
+ * @param {String} prop
+ * @param {String} val
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.set = function(prop, val){
+ this.transition(prop);
+ if ('number' == typeof val && map[prop]) val += map[prop];
+ this._props[prop] = val;
+ return this;
+ };
+
+ /**
+ * Increment `prop` by `val`, deferred until `.end()` is invoked
+ * and adds the property to the list of transition props.
+ *
+ * @param {String} prop
+ * @param {Number} val
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.add = function(prop, val){
+ if (!current) return;
+ var self = this;
+ return this.on('start', function(){
+ var curr = parseInt(self.current(prop), 10);
+ self.set(prop, curr + val + 'px');
+ });
+ };
+
+ /**
+ * Decrement `prop` by `val`, deferred until `.end()` is invoked
+ * and adds the property to the list of transition props.
+ *
+ * @param {String} prop
+ * @param {Number} val
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.sub = function(prop, val){
+ if (!current) return;
+ var self = this;
+ return this.on('start', function(){
+ var curr = parseInt(self.current(prop), 10);
+ self.set(prop, curr - val + 'px');
+ });
+ };
+
+ /**
+ * Get computed or "current" value of `prop`.
+ *
+ * @param {String} prop
+ * @return {String}
+ * @api public
+ */
+
+ Move.prototype.current = function(prop){
+ return current(this.el).getPropertyValue(prop);
+ };
+
+ /**
+ * Add `prop` to the list of internal transition properties.
+ *
+ * @param {String} prop
+ * @return {Move} for chaining
+ * @api private
+ */
+
+ Move.prototype.transition = function(prop){
+ if (!this._transitionProps.indexOf(prop)) return this;
+ this._transitionProps.push(prop);
+ return this;
+ };
+
+ /**
+ * Commit style properties, aka apply them to `el.style`.
+ *
+ * @return {Move} for chaining
+ * @see Move#end()
+ * @api private
+ */
+
+ Move.prototype.applyProperties = function(){
+ var props = this._props
+ , el = this.el;
+
+ console.log(this._props);
+ for (var prop in props) {
+ if (props.hasOwnProperty(prop)) {
+ el.style.setProperty(prop, props[prop], '');
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Re-select element via `selector`, replacing
+ * the current element.
+ *
+ * @param {String} selector
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.move =
+ Move.prototype.select = function(selector){
+ this.el = move.select(selector);
+ return this;
+ };
+
+ /**
+ * Defer the given `fn` until the animation
+ * is complete. `fn` may be one of the following:
+ *
+ * - a function to invoke
+ * - an instanceof `Move` to call `.end()`
+ * - nothing, to return a clone of this `Move` instance for chaining
+ *
+ * @param {Function|Move} fn
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.then = function(fn){
+ // invoke .end()
+ if (fn instanceof Move) {
+ this.on('end', function(){
+ fn.end();
+ });
+ // callback
+ } else if ('function' == typeof fn) {
+ this.on('end', fn);
+ // chain
+ } else {
+ var clone = new Move(this.el);
+ clone._transforms = this._transforms.slice(0);
+ this.then(clone);
+ clone.parent = this;
+ return clone;
+ }
+
+ return this;
+ };
+
+ /**
+ * Pop the move context.
+ *
+ * @return {Move} parent Move
+ * @api public
+ */
+
+ Move.prototype.pop = function(){
+ return this.parent;
+ };
+
+ /**
+ * Start animation, optionally calling `fn` when complete.
+ *
+ * @param {Function} fn
+ * @return {Move} for chaining
+ * @api public
+ */
+
+ Move.prototype.end = function(fn){
+ var self = this;
+
+ // emit "start" event
+ this.emit('start');
+
+ // transforms
+ if (this._transforms.length) {
+ this.setVendorProperty('transform', this._transforms.join(' '));
+ }
+
+ // transition properties
+ //this.setVendorProperty('transition-property', this._transitionProps.join(', '));
+ this.applyProperties();
+
+ // callback given
+ if (fn) this.then(fn);
+
+ // emit "end" when complete
+ setTimeout(function(){
+ self.emit('end');
+ }, this._duration);
+
+ return this;
+ };
+
+})(this);
+
+
/**
* The animation library that is used for the animations inside elements
* @default_private
View
6 elements/modalwindow.js
@@ -410,7 +410,13 @@ apf.AmlWindow = function(struct, tagName){
this.state = this.state.split("|").remove("closed").join("|");
+ var _self = this;
+ this.$ext.style.opacity = 0;
this.$ext.style.display = ""; //Some form of inheritance detection
+ move(this.$ext).scale(0.2).duration("0.0s").end(function() {
+ _self.$ext.style.opacity = 0.3;
+ move(_self.$ext).scale(1).set("opacity", 1).duration("0.23s").end();
+ });
//if (this.modal)
//this.$ext.style.position = "fixed";

0 comments on commit f68af74

Please sign in to comment.
Something went wrong with that request. Please try again.