-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS tween branch #49
base: master
Are you sure you want to change the base?
CSS tween branch #49
Changes from all commits
b97d697
1dd07c0
06bf5ca
cc56fdd
759db7c
d388fc3
0e25774
19fcce5
77b6c19
7156fd1
b40500f
f3a16f8
8e474f9
2bd2fa7
8585d80
d8c4993
6b51f15
908bcf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Tina - CSS</title> | ||
<meta charset="utf-8"> | ||
<link rel="stylesheet" type="text/css" href="../styles.css"> | ||
<style type="text/css"> | ||
#demodiv { | ||
position: absolute; | ||
left: 50px; | ||
top: 50px; | ||
height: 100px; | ||
width: 100px; | ||
background-color: aquamarine; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<span class="title"> tina - CSS</span> | ||
<div class="democontainer"> | ||
<div id="demodiv"></div> | ||
</div> | ||
|
||
<!--<script src="../../build/tina.js" type="text/javascript"></script>--> | ||
<script src="https://rawgit.com/Wizcorp/tina/master/build/tina.min.js" type="text/javascript"></script>--> | ||
<script src="index.js" type="text/javascript"></script> | ||
<a href="http://jsfiddle.net/cstoquer/k8dghonL/"> jsfiddle </a> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
var demoDiv = document.getElementById('demodiv'); | ||
|
||
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ | ||
|
||
TINA.onUpdate(function update(t, dt) { | ||
// At this point, all my tweens are up to date for the current iteration | ||
}); | ||
|
||
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ | ||
|
||
var duration = 2000; | ||
var bouncing = 4; | ||
|
||
// NOTE: The available CSS properties options are currently: | ||
// top, bottom, left, right, width, height and opacity | ||
var csstween = new TINA.CSSTween(demodiv, ['top', 'width', 'opacity', 'height']) | ||
.from({ | ||
top: 50, | ||
width: 100, | ||
height: 100, | ||
opacity: 1 | ||
}) | ||
.to({ | ||
top: 200, | ||
width: 200, | ||
height: 200, | ||
opacity: 0 | ||
}, 2000) | ||
.iterations(Infinity) | ||
.pingpong(true) | ||
.start(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
var Transition = require('./Transition'); | ||
var TransitionRelative = require('./TransitionRelative'); | ||
|
||
var easingFunctions = require('./easing'); | ||
var interpolationFunctions = require('./interpolation'); | ||
var Transition = require('./Transition'); | ||
var TransitionCSS = require('./TransitionCSS'); | ||
var TransitionRelative = require('./TransitionRelative'); | ||
var easingFunctions = require('./easing'); | ||
var interpolationFunctions = require('./interpolation'); | ||
|
||
|
||
// Temporisation, used for waiting | ||
|
@@ -45,6 +45,13 @@ function AbstractTween(object, properties) { | |
} | ||
} | ||
|
||
// Determine if we are are tweening a CSS object | ||
// The undefined check is to avoid a crash when running Tina in | ||
// environments where the DOM is not available, such as in node. | ||
if (typeof CSSStyleDeclaration !== 'undefined') { | ||
this._css = (object instanceof CSSStyleDeclaration) ? true : false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it's not necessary to keep the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah sorry actually no, my bad |
||
} | ||
|
||
// Properties to tween | ||
this._properties = properties; | ||
|
||
|
@@ -155,7 +162,16 @@ AbstractTween.prototype.to = function (toObject, duration, easing, easingParam, | |
// Getting previous transition ending as the beginning for the new transition | ||
var fromObject = this._getLastTransitionEnding(); | ||
|
||
var TransitionConstructor = (this._relative === true) ? TransitionRelative : Transition; | ||
// Determine the appropriate transition constructor for the given object | ||
var TransitionConstructor = null; | ||
if (this._relative === true) { | ||
TransitionConstructor = TransitionRelative; | ||
} else if (this._css === true) { | ||
TransitionConstructor = TransitionCSS; | ||
} else { | ||
TransitionConstructor = Transition; | ||
} | ||
|
||
var transition = new TransitionConstructor( | ||
this._properties, | ||
fromObject, | ||
|
@@ -220,4 +236,4 @@ AbstractTween.prototype._validate = function () { | |
} | ||
|
||
return true; | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* | ||
* Maps the given properties to a unit type | ||
* | ||
* Currently only supports basic CSS methods - in order to support more advance CSS3 properties, such as | ||
* transform, we will need to modify the way the properties array is handled and moved through the system. | ||
* In the case of CSS methods such as "transform: rotate(Xdeg)" - the mapping will need to be more advanced, | ||
* possibly adding a prefix / suffix mapping. | ||
* | ||
* @param {array} properties - Properties of the object to tween | ||
* @returns {array} - The suffix mapped to the property name | ||
* | ||
*/ | ||
module.exports = function (properties) { | ||
|
||
var cssMap = { height: 'px', width: 'px', top: 'px', left: 'px', bottom: 'px', right: 'px', opacity: '' }; | ||
var mapping = {}; | ||
|
||
for (var i = 0; i < properties.length; i++) { | ||
if (properties[i] in cssMap) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What should we do if the property is not in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A very good question. I guess the most appropriate course of action would be to throw an error. If we can't provide a CSS Tween for that given property, it probably shouldn't fail silently. However, having a quick look through the source for Tina I can't see any other instances of a thrown error. So I'm not sure what the site policy for error handling is. Any thoughts would be appreciated. |
||
var property = properties[i]; | ||
mapping[property] = cssMap[property]; | ||
} | ||
} | ||
|
||
return mapping; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
// Provides transitions for CSS style objects | ||
var CSSMap = require('./CSSMap'); | ||
|
||
// One property | ||
function update(object, t) { | ||
var p = this.prop; | ||
object[p] = (this.from[p] * (1 - t) + this.to[p] * t) + this.cssMap[p]; | ||
} | ||
|
||
// Several Properties | ||
function updateP(object, t) { | ||
var q = this.props; | ||
for (var i = 0; i < this.props.length; i += 1) { | ||
var p = q[i]; | ||
object[p] = (this.from[p] * (1 - t) + this.to[p] * t) + this.cssMap[p]; | ||
} | ||
} | ||
|
||
// Interpolation | ||
function updateI(object, t) { | ||
var p = this.prop; | ||
object[p] = this.interps[p](t, this.from[p], this.to[p], this.interpParams[p]) + this.cssMap[p]; | ||
} | ||
|
||
// Interpolation | ||
// Several Properties | ||
function updatePI(object, t) { | ||
var q = this.props; | ||
for (var i = 0; i < q.length; i += 1) { | ||
var p = q[i]; | ||
object[p] = this.interps[p](t, this.from[p], this.to[p], this.interpParams[p]) + this.cssMap[p]; | ||
} | ||
} | ||
|
||
// Easing | ||
function updateE(object, t) { | ||
t = this.easing(t, this.easingParam); | ||
var p = this.prop; | ||
object[p] = (this.from[p] * (1 - t) + this.to[p] * t) + this.cssMap[p]; | ||
} | ||
|
||
// Easing | ||
// Several Properties | ||
function updatePE(object, t, interpFunc) { | ||
var q = this.props; | ||
t = this.easing(t, this.easingParam); | ||
for (var i = 0; i < q.length; i += 1) { | ||
var p = q[i]; | ||
object[p] = (this.from[p] * (1 - t) + this.to[p] * t) + this.cssMap[p]; | ||
} | ||
} | ||
|
||
// Easing | ||
// Interpolation | ||
function updateIE(object, t, interpFunc) { | ||
var p = this.prop; | ||
t = this.easing(t, this.easingParam); | ||
object[p] = this.interps[p](t, this.from[p], this.to[p], this.interpParams[p]) + this.cssMap[p]; | ||
} | ||
|
||
// Easing | ||
// Interpolation | ||
// Several Properties | ||
function updatePIE(object, t, interpFunc) { | ||
var q = this.props; | ||
t = this.easing(t, this.easingParam); | ||
for (var i = 0; i < q.length; i += 1) { | ||
var p = q[i]; | ||
object[p] = this.interps[p](t, this.from[p], this.to[p], this.interpParams[p]) + this.cssMap[p]; | ||
} | ||
} | ||
|
||
|
||
var updateMethods = [ | ||
[ | ||
[update, updateP], | ||
[updateI, updatePI] | ||
], [ | ||
[updateE, updatePE], | ||
[updateIE, updatePIE] | ||
] | ||
]; | ||
|
||
function TransitionCSS(properties, from, to, start, duration, easing, | ||
easingParam, interpolations, interpolationParams) { | ||
|
||
this.start = start; | ||
this.end = start + duration; | ||
this.duration = duration; | ||
this.from = from; | ||
this.to = to; | ||
this.cssMap = CSSMap(properties); | ||
|
||
// Easing flag - Whether an easing function is used | ||
// 0 => Using linear easing | ||
// 1 => Using custom easing | ||
var easingFlag; | ||
if (easing) { | ||
easingFlag = 1; | ||
this.easing = easing; | ||
this.easingParam = easingParam; | ||
} else { | ||
easingFlag = 0; | ||
} | ||
|
||
// Interpolation flag - Whether an interpolation function is used | ||
// 0 => No Interpolation | ||
// 1 => At least one interpolation | ||
var interpFlag; | ||
if (interpolations === null) { | ||
interpFlag = 0; | ||
} else { | ||
interpFlag = 1; | ||
this.interps = interpolations; | ||
this.interpParams = interpolationParams || {}; | ||
} | ||
|
||
// Property flag - Whether the transition has several properties | ||
// 0 => Only one property | ||
// 1 => Several properties | ||
var propsFlag; | ||
if (properties.length === 1) { | ||
propsFlag = 0; | ||
this.prop = properties[0]; // string | ||
this.props = null; | ||
} else { | ||
propsFlag = 1; | ||
this.prop = null; | ||
this.props = properties; // array | ||
} | ||
|
||
this.update = updateMethods[easingFlag][interpFlag][propsFlag]; | ||
} | ||
|
||
module.exports = TransitionCSS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if it is undefined? What should the behavior be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of the check is actually to prevent a crash when running Tina outside the browser, in node (i.e. benchmarking). I can't actually imagine a case where CSSStyleDeclaration would be undefined (and required) in a typical use case. I have to admit, I haven't written a lot of code where the same code path has to run both in the front end and backend - so if there is a more appropriate pattern to avoid these issues, I'd be happy to hear it. :)
Either way, I will make that clearer in the comment.