Skip to content

Commit

Permalink
Merge pull request #847 from bryan-m-hughes/timob-6017
Browse files Browse the repository at this point in the history
Timob 6017 Mobile web animation.
  • Loading branch information
cb1kenobi committed Dec 8, 2011
2 parents 17ff3b9 + ca42ee8 commit b6d2b78
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 66 deletions.
65 changes: 53 additions & 12 deletions mobileweb/src/Ti.UI/2dmatrix.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,64 @@
Ti._5.createClass('Titanium.UI.2DMatrix', function(args){
var obj = this;
// Interfaces
Ti._5.DOMView(this, '2dmatrix', args, '2DMatrix');

// Initialize the matrix to unity
obj._a = 1,
obj._b = 0,
obj._c = 0,
obj._d = 1,
obj._tx = 0,
obj._ty = 0;

// Internal methods
function _multiplyInternal(_a2,_b2,_c2,_d2,_tx2,_ty2) {
var newMatrix = Ti.UI.create2DMatrix();
newMatrix._a = obj._a * _a2 + obj._b * _c2,
newMatrix._b = obj._a * _b2 + obj._b * _d2;
newMatrix._c = obj._c * _a2 + obj._d * _c2;
newMatrix._d = obj._c * _b2 + obj._d * _d2;
newMatrix._tx = obj._a * _tx2 + obj._b * _ty2 + obj._tx;
newMatrix._ty = obj._c * _tx2 + obj._d * _ty2 + obj._ty;
return newMatrix;
}

this._toCSS = function() {

// Round off the elements because scientific notation in CSS isn't allowed (apparently)
var roundedValues = [obj._a.toFixed(6),obj._b.toFixed(6),obj._c.toFixed(6),obj._d.toFixed(6),obj._tx.toFixed(6),obj._ty.toFixed(6)];

// Firefox requires tx and ty to have "px" postfixed, but the other browsers require it *not* to be there.
if (navigator.userAgent.indexOf("Firefox")!=-1) {
roundedValues[4] += "px";
roundedValues[5] += "px";
}
return "matrix(" + roundedValues.join(",") + ")";
}
this._fromCSS = function(matrixString) {
parsedString = matrixString.substring(7,matrixString.length - 1).split(",");
obj._a = parseFloat(parsedString[0]);
obj._b = parseFloat(parsedString[1]);
obj._c = parseFloat(parsedString[2]);
obj._d = parseFloat(parsedString[3]);
obj._tx = parseFloat(parsedString[4]);
obj._ty = parseFloat(parsedString[5]);
}

// Methods
this.invert = function(){
console.debug('Method "Titanium.UI.2DMatrix#.invert" is not implemented yet.');
};
this.multiply = function(){
console.debug('Method "Titanium.UI.2DMatrix#.multiply" is not implemented yet.');
this.multiply = function(t2){
return _multiplyInternal(t2._a,t2._b,t2._c,t2._d,t2._tx,t2._ty);
};
this.rotate = function(){
console.debug('Method "Titanium.UI.2DMatrix#.rotate" is not implemented yet.');
this.rotate = function(angle){
// Math.xxx trig functions take radians, so convert from degrees first
angleInRadians = angle * Math.PI / 180;
return _multiplyInternal(Math.cos(angleInRadians),Math.sin(angleInRadians),-Math.sin(angleInRadians),Math.cos(angleInRadians),0,0);
};
this.scale = function(){
console.debug('Method "Titanium.UI.2DMatrix#.scale" is not implemented yet.');
this.scale = function(sx,sy){
return _multiplyInternal(sx,0,0,sy,0,0);
};
this.translate = function(){
console.debug('Method "Titanium.UI.2DMatrix#.translate" is not implemented yet.');
this.translate = function(tx,ty){
return _multiplyInternal(1,0,0,1,tx,ty);
};

Ti._5.presetUserDefinedElements(this, args);
});
78 changes: 57 additions & 21 deletions mobileweb/src/Ti.UI/animation.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,131 @@
Ti._5.createClass('Titanium.UI.Animation', function(args){
var obj = this;
// Interfaces
Ti._5.DOMView(this, 'animation', args, 'Animation');
Ti._5.Positionable(this, args);

// Properties
var _autoreverse = null;
var _autoreverse;
Object.defineProperty(this, 'autoreverse', {
get: function(){return _autoreverse;},
set: function(val){return _autoreverse = val;}
});

var _backgroundColor = null;
var _backgroundColor;
Object.defineProperty(this, 'backgroundColor', {
get: function(){return _backgroundColor;},
set: function(val){return _backgroundColor = val;}
});

var _color = null;
var _color;
Object.defineProperty(this, 'color', {
get: function(){return _color;},
set: function(val){return _color = val;}
});

var _curve = null;
var _curve;
Object.defineProperty(this, 'curve', {
get: function(){return _curve;},
set: function(val){return _curve = val;}
});

var _delay = null;
var _delay;
Object.defineProperty(this, 'delay', {
get: function(){return _delay;},
set: function(val){return _delay = val;}
});

var _duration = null;
var _duration;
Object.defineProperty(this, 'duration', {
get: function(){return _duration;},
set: function(val){return _duration = val;}
});

var _opacity = null;
var _opacity;
Object.defineProperty(this, 'opacity', {
get: function(){return _opacity;},
set: function(val){return _opacity = val;}
});

var _opaque = null;
var _opaque;
Object.defineProperty(this, 'opaque', {
get: function(){return _opaque;},
set: function(val){return _opaque = val;}
});

var _repeat = null;
var _repeat;
Object.defineProperty(this, 'repeat', {
get: function(){return _repeat;},
set: function(val){return _repeat = val;}
});

var _transform = null;
var _transform;
Object.defineProperty(this, 'transform', {
get: function(){return _transform;},
set: function(val){return _transform = val;}
});

var _transition = null;
var _transition;
Object.defineProperty(this, 'transition', {
get: function(){return _transition;},
set: function(val){return _transition = val;}
});

var _rotation;
Object.defineProperty(this, 'rotation', {
get: function(){return _rotation;},
set: function(val){return _rotation = val;}
});

var _visible = null;
var _visible;
Object.defineProperty(this, 'visible', {
get: function(){return _visible;},
set: function(val){return _visible = val;}
});

var _zIndex = null;
var _zIndex;
Object.defineProperty(this, 'zIndex', {
get: function(){return _zIndex;},
set: function(val){return _zIndex = val;}
});

var _top;
Object.defineProperty(obj, 'top', {
get: function(){return _top;},
set: function(val){return _top = val;}
});

var _bottom;
Object.defineProperty(obj, 'bottom', {
get: function(){return _bottom;},
set: function(val){return _bottom = val;}
});

// Events
this.addEventListener('complete', function(){
console.debug('Event "complete" is not implemented yet.');
var _left;
Object.defineProperty(obj, 'left', {
get: function(){return _left;},
set: function(val){return _left = val;}
});

var _right;
Object.defineProperty(obj, 'right', {
get: function(){return _right;},
set: function(val){return _right = val;}
});

var _width;
Object.defineProperty(obj, 'width', {
get: function(){return _width;},
set: function(val){return _width = val;}
});

var _height;
Object.defineProperty(obj, 'height', {
get: function(){return _height;},
set: function(val){return _height = val;}
});
this.addEventListener('start', function(){
console.debug('Event "start" is not implemented yet.');

var _center;
Object.defineProperty(obj, 'center', {
get: function(){return _center;},
set: function(val){return _center = val;}
});

Ti._5.presetUserDefinedElements(this, args);
Expand Down
2 changes: 1 addition & 1 deletion mobileweb/src/Ti.UI/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,5 @@ Ti._5.createClass('Titanium.UI.Button', function(args){
"backgroundDisabledColor", "enabled"
], args);

Ti._5.presetUserDefinedElements(this, args);
Ti._5.presetUserArguments(this, args);
});
8 changes: 4 additions & 4 deletions mobileweb/src/Ti.UI/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@
//document.body.style.backgroundRepeat = "no-repeat";
};

api.create2DMatrix = function(){
console.debug('Method "Titanium.UI.create2DMatrix" is not implemented yet.');
api.create2DMatrix = function(args){
return new Titanium.UI["2DMatrix"](args);
};
api.create3DMatrix = function(){
console.debug('Method "Titanium.UI.create3DMatrix" is not implemented yet.');
Expand All @@ -141,8 +141,8 @@
api.createAlertDialog = function(args){
return new Ti.UI.AlertDialog(args);
};
api.createAnimation = function(){
console.debug('Method "Titanium.UI.createAnimation" is not implemented yet.');
api.createAnimation = function(args){
return new Ti.UI.Animation(args);
};
api.createButton = function(args) {
return new Ti.UI.Button(args);
Expand Down
117 changes: 94 additions & 23 deletions mobileweb/src/styleable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var spinningAngle = 0;
(function(oParentNamespace) {
// Create object
oParentNamespace.Styleable = function(obj, args) {
Expand Down Expand Up @@ -451,34 +452,104 @@
}
}
});
obj.animate = function(val) {
var duration = null;
var props = [];
for (prop in val) {
if (prop == 'duration') {
duration = val[prop]
} else {
props.push(prop);
obj._getPrefixedCSSRuleName = function(rule) {
var style = obj.dom.style,
upperCaseRule = rule[0].toUpperCase() + rule.substring(1),
possibleRuleNames = ["Moz" + upperCaseRule,"Webkit" + upperCaseRule,"O" + upperCaseRule,"ms" + upperCaseRule,rule];
for (var i = 0; i < 5; i++) {
var prefixedRule = possibleRuleNames[i];
if (prefixedRule in style) {
return prefixedRule;
}
}
if ('Firefox' == Titanium.Platform.name) {
duration = duration || 0;
var sProperty = '';
for (var iCounter=0; iCounter < props.length; iCounter++) {
sProperty += sProperty ? ', ' : '';
sProperty += props[iCounter] + ' ' + duration + 'ms ease 0s';
}
obj.dom.style.MozTransition= sProperty;
} else {
obj.dom.style['-webkit-transition-property'] = props;
if (duration != null) {
obj.dom.style['-webkit-transition-duration'] = duration;
}
obj._setPrefixedCSSRule = function(rule,value) {
var prefixedRule = obj._getPrefixedCSSRuleName(rule);
prefixedRule && (obj.dom.style[prefixedRule] = value);
}
obj._getPrefixedCSSRuleValue = function(rule) {
var prefixedRule = obj._getPrefixedCSSRuleName(rule);
return prefixedRule && obj.dom.style[prefixedRule];
}
obj.animate = function(animation,callback) {

// Set default values
animation.duration = (animation.duration ? animation.duration : 0);
animation.delay = (animation.delay ? animation.delay : 0);

var _curve = "ease";
switch(animation.curve) {
case Ti.UI.ANIMATION_CURVE_LINEAR: _curve = "linear"; break;
case Ti.UI.ANIMATION_CURVE_EASE_IN: _curve = "ease-in"; break;
case Ti.UI.ANIMATION_CURVE_EASE_OUT: _curve = "ease-out"; break;
case Ti.UI.ANIMATION_CURVE_EASE_IN_OUT: _curve = "ease-in-out"; break;
}

// Determine which coordinates are valid and combine with previous coordinates where appropriate.
var _style = obj.dom.style;
if (isDefined(animation.center)) {
animation.left = animation.center.x - obj.dom.offsetWidth / 2;
animation.top = animation.center.y - obj.dom.offsetHeight / 2;
}

// Create the transition, must be set before setting the other properties
var transitionValue = "all " + animation.duration + "ms " + _curve;
isDefined(animation.delay) && (transitionValue += " " + animation.delay + "ms");
obj._setPrefixedCSSRule("transition", transitionValue);

// We need to explicitly test if a variable is defined because 0 or false can be a legitimate value
function isDefined(value) {
return !require.is(value,"Undefined");
}

// Set the color and opacity properties
isDefined(animation.backgroundColor) && (_style.backgroundColor = animation.backgroundColor);
isDefined(animation.color) && (_style.color = animation.color);
isDefined(animation.opacity) && (_style.opacity = animation.opacity);
(animation.opaque === true || animation.visible === true) && (_style.opacity = 1.0);
(animation.opaque === false || animation.visible === false) && (_style.opacity = 0.0);

// Set the position and size properties
function setUnits(value) {
return require.is(value,"Number") ? value + "px" : value
}
isDefined(animation.top) && (_style.top = setUnits(animation.top));
isDefined(animation.bottom) && (_style.bottom = setUnits(animation.bottom));
isDefined(animation.left) && (_style.left = setUnits(animation.left));
isDefined(animation.right) && (_style.right = setUnits(animation.right));
isDefined(animation.height) && (_style.height = setUnits(animation.height));
isDefined(animation.width) && (_style.width = setUnits(animation.width));

// Set the z-order
isDefined(animation.zIndex) && (_style.zIndex = animation.zIndex);

// Set the transform properties
var transform = "";
if (animation.rotation) {
if(obj._currentRotation) {
obj._currentRotation += animation.rotation;
} else {
obj._currentRotation = animation.rotation;
}
transform += "rotate(" + obj._currentRotation + "deg) ";
}
for (prop in val) {
if (prop != 'duration') {
obj.dom.style[prop] = val[prop];
if (animation.transform) {
if (obj._currentTransform) {
obj._currentTransform = obj._currentTransform.multiply(animation.transform);
} else {
obj._currentTransform = animation.transform;
}
transform += obj._currentTransform._toCSS();
}
obj._setPrefixedCSSRule("transform",transform);

if(callback) {
// Note: no IE9 support for transitions, so instead we just set a timer that matches the duration so things don't break
setTimeout(function(){
// Clear the transform so future modifications in these areas are not animated
obj._setPrefixedCSSRule("transition", "");
callback();
},animation.duration + animation.delay + 1);
}
};

Expand Down

0 comments on commit b6d2b78

Please sign in to comment.