Permalink
Browse files

CSS3 support, replaces the normal Fx.Morph, Fx.Tween and Fx.Elements

Add CSS3 transition support in place of Fx.Elements

Fix missing variable

Trying again

Problems

Problem

Working

CSS3 functions moved from core

Fixes and a test for tween

Fixes and tests for the rest
  • Loading branch information...
1 parent e830bb9 commit 445a47b4a0318557d5e443cb33d7cd5b1bf22bf4 @mcfedr committed Aug 31, 2011
View
@@ -0,0 +1,152 @@
+/*
+---
+name: Fx.CSS3
+script: Fx.CSS3.js
+license: MIT-style license.
+description: Provides the base functionality of the CSS3 Fx classes
+copyright: Copyright (c) 2010, Dipl.-Ing. (FH) André Fiedler <kontakt at visualdrugs dot net>, based on code by eskimoblood (mootools users group)
+copyright: Copyright (c) 2011 Fred Cox mcfedr@gmail.com
+authors: [Fred Cox, André Fiedler, eskimoblood]
+
+requires: [Core/Class.Extras, Core/Element.Event, Core/Element.Style, Core/Fx, Array.Extras]
+
+provides: [Fx.CSS3Funcs]
+...
+*/
+
+(function() {
+
+ var css3Features = (function(){
+
+ var prefix = (function(){
+ var prefixes = ['ms', 'O', 'Moz', 'webkit'],
+ style = document.documentElement.style;
+ for (var l = prefixes.length; l--;){
+ var prefix = prefixes[l];
+ if (typeof style[(prefix ? prefix + 'T' : 't') + 'ransition'] != 'undefined') return prefix;
+ }
+ return false;
+ })();
+
+ if(prefix) {
+ var t = prefix ? prefix + 'T' : 't';
+ return {
+ transition: t + 'ransition',
+ transitionProperty: t + 'ransitionProperty',
+ transitionDuration: t + 'ransitionDuration',
+ transitionTimingFunction : t + 'ransitionTimingFunction',
+ transitionend: (prefix == 'ms' || prefix == 'Moz') ? 'transitionEnd' : prefix + 'TransitionEnd'
+ }
+ }
+ return false;
+ })();
+
+ Element.NativeEvents[css3Features.transitionend] = 2;
+
+ Event.implement({
+ getPropertyName: function(){
+ return this.event.propertyName;
+ },
+
+ getElapsedTime: function(nativeTime){
+ return nativeTime ? this.event.elapsedTime : (this.event.elapsedTime * 1000).toInt();
+ }
+ });
+
+ Array.implement({
+ containsArray: function(array) {
+ return array.every(function(v) {
+ return this.contains(v);
+ }, this);
+ }
+ });
+
+ var transitionTimings = {
+ 'linear' : '0,0,1,1',
+ 'expo:in' : '0.71,0.01,0.83,0',
+ 'expo:out' : '0.14,1,0.32,0.99',
+ 'expo:in:out' : '0.85,0,0.15,1',
+ 'circ:in' : '0.34,0,0.96,0.23',
+ 'circ:out' : '0,0.5,0.37,0.98',
+ 'circ:in:out' : '0.88,0.1,0.12,0.9',
+ 'sine:in' : '0.22,0.04,0.36,0',
+ 'sine:out' : '0.04,0,0.5,1',
+ 'sine:in:out' : '0.37,0.01,0.63,1',
+ 'quad:in' : '0.14,0.01,0.49,0',
+ 'quad:out' : '0.01,0,0.43,1',
+ 'quad:in:out' : '0.47,0.04,0.53,0.96',
+ 'cubic:in' : '0.35,0,0.65,0',
+ 'cubic:out' : '0.09,0.25,0.24,1',
+ 'cubic:in:out' : '0.66,0,0.34,1',
+ 'quart:in' : '0.69,0,0.76,0.17',
+ 'quart:out' : '0.26,0.96,0.44,1',
+ 'quart:in:out' : '0.76,0,0.24,1',
+ 'quint:in' : '0.64,0,0.78,0',
+ 'quint:out' : '0.22,1,0.35,1',
+ 'quint:in:out' : '0.9,0,0.1,1'
+ };
+
+ var animatable = ['background-color', 'background-image', 'background-position', 'border-bottom-color', 'border-bottom-width',
+ 'border-color', 'border-left-color', 'border-left-width', 'border-right-color', 'border-right-width', 'border-spacing',
+ 'border-top-color', 'border-top-width', 'border-width', 'bottom', 'color', 'crop', 'font-size', 'font-weight',
+ 'grid-*', 'height', 'left', 'letter-spacing', 'line-height', 'margin-bottom', 'margin-left', 'margin-right',
+ 'margin-top', 'max-height', 'max-width', 'min-height', 'min-width', 'opacity', 'outline-color', 'outline-offset',
+ 'outline-width', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'right', 'text-indent', 'text-shadow',
+ 'top', 'vertical-align', 'visibility', 'width', 'word-spacing', 'z-index', 'zoom'];
+
+
+ Fx.CSS3Funcs = {
+ initialize: function(element, options){
+ if(css3Features) {
+ options = options || {};
+ if(!options.transition || !transitionTimings[options.transition]) {
+ options.transition = 'sine:in:out';
+ }
+ }
+ this.parent(element, options);
+ },
+
+ cancel: function(){
+ if (this.css3Supported){
+ this.element.setStyle(css3Features.transition, 'none');
+ this.element.removeEvent(css3Features.transitionend, this.boundComplete);
+ this.boundComplete = null;
+ }
+ this.parent();
+ return this;
+ },
+
+ stop: function() {
+ if (this.css3Supported){
+ return this;
+ }
+ return this.parent();
+ },
+
+ pause: function() {
+ if (this.css3Supported){
+ return this;
+ }
+ return this.parent();
+ },
+
+ resume: function() {
+ if (this.css3Supported){
+ return this;
+ }
+ return this.parent();
+ },
+
+ isRunning: function() {
+ if (this.css3Supported){
+ return !!this.boundComplete;
+ }
+ return this.parent();
+ }
+ };
+
+ Fx.CSS3Funcs.css3Features = css3Features;
+ Fx.CSS3Funcs.transitionTimings = transitionTimings;
+ Fx.CSS3Funcs.animatable = animatable;
+
+})();
@@ -0,0 +1,65 @@
+/*
+---
+name: Fx.Elements.CSS3
+script: Fx.Elements.CSS3.js
+license: MIT-style license.
+description: Provides a CSS3 implementaton of Fx.Elements
+copyright: Copyright (c) 2010, Dipl.-Ing. (FH) André Fiedler <kontakt at visualdrugs dot net>, based on code by eskimoblood (mootools users group)
+copyright: Copyright (c) 2011 Fred Cox mcfedr@gmail.com
+authors: [Fred Cox, André Fiedler, eskimoblood]
+
+requires: [Fx.CSS3Funcs, Fx.Morph.CSS3, Fx.Elements]
+
+provides: [Fx.Elements.CSS3]
+...
+*/
+(function() {
+
+ var elementsCSS2 = Fx.Elements;
+
+ Fx.Elements = new Class({
+ Extends: elementsCSS2,
+
+ checkCSS3: function(obj){
+ return (Fx.CSS3Funcs.css3Features && Object.every(obj, function(properties, key) {
+ if(properties && this.elements[key]) {
+ return Fx.CSS3Funcs.animatable.containsArray(Object.keys(properties));
+ }
+ return true;
+ }, this));
+ },
+
+ count: 0,
+
+ start: function(obj){
+ if ((this.css3Supported = this.checkCSS3(obj))) {
+ if(this.count != 0) return this;
+ this.count = 0;
+ var complete = function() {
+ if(this.count-- == 0) {
+ this.fireEvent('complete', this);
+ }
+ }.bind(this);
+
+ Object.each(obj, function(properties, key) {
+ if(properties && this.elements[key]) {
+ this.count++;
+ new Fx.Morph(this.elements[key], Object.merge({}, this.options, {
+ onComplete: complete
+ })).start(properties);
+ }
+ }, this);
+
+ this.fireEvent('start', this);
+ return this;
+ }
+ return this.parent(obj);
+ }
+ });
+
+ Fx.Elements.implement(Fx.CSS3Funcs);
+
+ Fx.Elements.CSS2 = elementsCSS2;
+ Fx.Elements.CSS3 = Fx.Elements;
+
+})();
@@ -0,0 +1,116 @@
+/*
+---
+name: Fx.Morph.CSS3
+script: Fx.Morph.CSS3.js
+license: MIT-style license.
+description: Provides a CSS3 implementaton of Fx.Morph
+copyright: Copyright (c) 2010, Dipl.-Ing. (FH) André Fiedler <kontakt at visualdrugs dot net>, based on code by eskimoblood (mootools users group)
+copyright: Copyright (c) 2011 Fred Cox mcfedr@gmail.com
+authors: [Fred Cox, André Fiedler, eskimoblood]
+
+requires: [Fx.CSS3Funcs, Core/Fx.Morph]
+
+provides: [Fx.Morph.CSS3]
+...
+*/
+(function() {
+
+ var morphCSS2 = Fx.Morph;
+
+ function isEqual(a, b) {
+ // Check object identity.
+ if (a === b) return true;
+ // Different types?
+ var atype = typeOf(a), btype = typeOf(b);
+ if (atype != btype) return false;
+ // Basic equality test (watch out for coercions).
+ if (a == b) return true;
+ // One is falsy and the other truthy.
+ if ((!a && b) || (a && !b)) return false;
+ // One of them implements an isEqual()?
+ if (a.isEqual) return a.isEqual(b);
+ if (b.isEqual) return b.isEqual(a);
+ // Both are NaN?
+ if ((a !== a) && (b !== b)) return false;
+ // Check dates' integer values.
+ if (atype == 'date') return a.getTime() === b.getTime();
+ if (atype == 'function') return true;
+ // Compare regular expressions.
+ if (atype == 'regexp')
+ return a.source === b.source &&
+ a.global === b.global &&
+ a.ignoreCase === b.ignoreCase &&
+ a.multiline === b.multiline;
+ // If a is not an object by this point, we can't handle it.
+ if (atype !== 'object' && atype !== 'array') return false;
+ // Check for different array lengths before comparing contents.
+ if (a.length && (a.length !== b.length)) return false;
+ // Nothing else worked, deep compare the contents.
+ var aKeys = Object.keys(a), bKeys = Object.keys(b);
+ // Different object sizes?
+ if (aKeys.length != bKeys.length) return false;
+ // Recursive comparison of contents.
+ for (var key in a) if (!(key in b) || !isEqual(a[key], b[key])) return false;
+ return true;
+ }
+
@mcfedr
mcfedr Sep 10, 2011 Owner

There is a possibility of refactoring this into Object, I think it could be a useful function to have there

+ Fx.Morph = new Class({
+
+ Extends: morphCSS2,
+
+ checkCSS3: function(properties){
+ return (Fx.CSS3Funcs.css3Features && Fx.CSS3Funcs.animatable.containsArray(Object.keys(properties)));
+ },
+
+ start: function(properties){
+ if ((this.css3Supported = this.checkCSS3(properties))) {
+ if(this.boundComplete) return this;
+ if (typeof properties == 'string') properties = this.search(properties);
+ var from = {}, to = {};
+ for (var p in properties){
+ var parsed = this.prepare(this.element, p, properties[p]);
+ from[p] = parsed.from;
+ to[p] = parsed.to;
+ }
+ if(!isEqual(from, to)) {
+ var incomplete = Object.map(properties, function() { return false; });
+ this.boundComplete = function(event){
+ incomplete[event.getPropertyName()] = true;
+ if(Object.every(incomplete, function(v) { return v; })) {
+ this.element.removeEvent(Fx.CSS3Funcs.css3Features.transitionend, this.boundComplete);
+ this.boundComplete = null;
+ this.fireEvent('complete', this);
+ }
+ }.bind(this);
+
+ this.element.addEvent(Fx.CSS3Funcs.css3Features.transitionend, this.boundComplete);
+
+ var trans = function(){
+ var transStyles = {};
+ transStyles[Fx.CSS3Funcs.css3Features.transitionProperty] = Object.keys(properties).reduce(function(a, b) { return a + ', ' + b; });
+ transStyles[Fx.CSS3Funcs.css3Features.transitionDuration] = this.options.duration + 'ms';
+ transStyles[Fx.CSS3Funcs.css3Features.transitionTimingFunction] = 'cubic-bezier(' + Fx.CSS3Funcs.transitionTimings[this.options.transition] + ')';
+ this.element.setStyles(transStyles);
+ this.set(this.compute(from, to, 1));
+ }.bind(this);
+ this.element.setStyle(Fx.CSS3Funcs.css3Features.transitionProperty, 'none');
+ this.set(this.compute(from, to, 0));
+ trans.delay(0.1);
+ this.fireEvent('start', this);
+ }
+ else {
+ this.fireEvent('start', this);
+ this.fireEvent('complete', this);
+ }
+ return this;
+ }
+ return this.parent(properties);
+ }
+ });
+
+ Fx.Morph.implement(Fx.CSS3Funcs);
+
+ Fx.Morph.CSS2 = morphCSS2;
+ Fx.Morph.CSS3 = Fx.Morph;
+
+})();
Oops, something went wrong.

0 comments on commit 445a47b

Please sign in to comment.