Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

input tests work

  • Loading branch information...
commit 5f887e3987a951bc390a9fccb03a9464341a0ec7 2 parents 4e52eeb + 3dd38fb
@boazsender boazsender authored
View
39 Jakefile.js
@@ -229,7 +229,7 @@ task( "hint", function() {
}).join( "\n" );
if ( files.src.length ) {
- write( "Hnting concatenated source: " + files.src.length + " scripts..." );
+ write( "Hinting concatenated source: " + files.src.length + " scripts..." );
ok();
if ( files.posthint ) {
hint( concat, "post" );
@@ -287,3 +287,40 @@ task( "min", function() {
});
});
+desc( "View static analysis of JavaScript program code" );
+task( "stats", [], function() {
+
+ header( "Statistics" );
+
+ var exts = [ ".js", ".min.js" ],
+ comp, stat, diff, color;
+
+ _.keys( config.files ).forEach(function( file ) {
+
+ exts.forEach(function( ext ) {
+
+ stat = stats.parse( readFile( file + ext ) );
+
+ _.keys( stat ).forEach( function( key, idx ) {
+
+ write( " " + key + ": " + this[ key ] );
+
+ if ( comp ) {
+ diff = (comp[ key ] - this[ key ]);
+
+ color = Math.abs(diff) > 0 ? "red" : "grey";
+
+ write( " (-" + (diff + "")[ color ] + ")" );
+ }
+
+ write( "\n" );
+ }, stat );
+
+ if ( comp == null ) {
+ comp = stat;
+ }
+
+ });
+ });
+});
+
View
297 src/abacus.animation.js
@@ -0,0 +1,297 @@
+(function( window ) {
+
+ // Animation constructor (internal)
+ // Mapped from calls to Abacus.animation( options )
+ // groups of animated layers
+ function Animation( options ) {
+ Abacus.extend(this, options);
+
+ if ( this.tween ) {
+ this.tween = Abacus.tween({
+ type: this.tween
+ });
+ }
+
+ if ( !this.layers ) {
+ this.layers = [];
+ }
+ }
+
+ Animation.prototype = {
+
+ // Animation.start()
+ // Returns Animation
+ start: function( target ) {
+ var animation = this;
+
+ // timerCallback context |this| is Timer instance
+ function timerCallback( timerData ) {
+
+ var layers = animation.layers,
+ allComplete = true,
+ idx;
+
+ for ( idx = 0; idx < layers.length; idx++ ) {
+ allComplete = layers[ idx ].step( animation, target, timerData ) && allComplete;
+ }
+
+ if ( !allComplete ) {
+ this.pause();
+ }
+ }
+
+ if ( !this.timer ) {
+ this.timer = Abacus.timer({
+ callback: timerCallback
+ });
+ }
+
+ this.timer.start();
+
+ return this;
+ },
+
+ // Animation.stop()
+ // Returns Animation
+ stop: function() {
+ if ( this.timer ) {
+ this.timer.pause();
+ }
+ return this;
+ },
+
+ // Animation.addLayer
+ // add new layer. returns Animation
+ addLayer: function ( layer ) {
+ var index = this.layers.length;
+
+ this.layers.push(layer);
+ layer.index = index;
+
+ return this;
+ },
+
+ // Animation.layer( number || {} )
+ // get layer or shortcut add and get layer
+ layer: function( idx ) {
+
+ var layer, options;
+
+ // if idx is null or undefined
+ if ( idx == null ) {
+ // Create a new layer
+ layer = Abacus.animation.layer();
+
+ // Add to current layers
+ this.addLayer(layer);
+
+ return layer;
+ }
+
+ if ( this.layers[ idx ] ) {
+ return this.layers[ idx ];
+ }
+
+ if ( typeof idx == 'object' ) {
+
+ options = idx;
+
+ if ( options.index != null &&
+ options.index < this.layers.length ) {
+
+ layer = this.layers[ options.index ];
+
+ Abacus.extend( layer, options );
+
+ return layer;
+ } else {
+ // shortcut for Abacus.animation.layer
+ layer = Abacus.animation.layer( options );
+
+ this.addLayer(layer);
+
+ return layer;
+ }
+ }
+ }
+ };
+
+ // groups of frames
+ function Layer( options ) {
+ options = options || {};
+
+ Abacus.extend(this, options);
+
+ if ( this.tween ) {
+ this.tween = Abacus.tween({
+ type: this.tween
+ });
+ }
+
+ if ( !this.frames ) {
+ this.frames = [];
+ }
+
+ // stored index value to avoid constantly looking up the correct frame
+ this.frameIndex = -1;
+ }
+
+ Layer.prototype = {
+ // Layer.addFrame(frame)
+ // insert animation.frame object according to frame.index. returns Layer
+ addFrame: function( frame ) {
+ var frameAdded = false,
+ framesLength = this.frames.length,
+ i = 0;
+
+ if ( !(frame instanceof Frame) ) {
+ frame = Abacus.animation.frame( frame );
+ }
+
+ for ( ; i < framesLength; i++ ) {
+ if ( this.frames[i].index > frame.index ) {
+ this.frames.splice( i, 0, frame );
+ frameAdded = true;
+ break;
+ }
+ }
+
+ if ( !frameAdded ) {
+ this.frames.push( frame );
+ }
+
+ return this;
+ },
+ // Layer.step( ... )
+ // updates target and returns true if there are no further frames
+ step: function( animation, target, timerData ) {
+ var sinceStart = timerData.sinceStart / 1000,
+ frameIndex = this.frameIndex,
+ lastFrame = this.frames[ frameIndex ],
+ nextFrame = this.frames[ frameIndex + 1 ],
+ framePlus;
+
+ // at end of layer?
+ if ( nextFrame == null ) {
+ return false;
+ }
+
+ if ( lastFrame && lastFrame.index / animation.rate > sinceStart ) {
+ return true;
+ }
+
+ // increment to the next usable frame
+ if ( nextFrame.index / animation.rate <= sinceStart ) {
+ for ( frameIndex++; frameIndex < this.frames.length; frameIndex++ ) {
+
+ framePlus = frameIndex + 1;
+
+ if ( frameIndex == 0 && nextFrame.beforeTween ) {
+ nextFrame.beforeTween();
+ }
+
+ lastFrame = this.frames[ frameIndex ];
+ nextFrame = this.frames[ framePlus ];
+
+ if ( nextFrame && nextFrame.beforeTween ) {
+ nextFrame.beforeTween();
+ }
+
+ if ( lastFrame && lastFrame.afterTween ) {
+ lastFrame.afterTween();
+ }
+
+ if ( this.frames[ framePlus ] &&
+ this.frames[ framePlus ].index / animation.rate > sinceStart ||
+ !this.frames[ framePlus ] )
+ {
+ break;
+ }
+ }
+
+ this.frameIndex = frameIndex;
+
+ // at end of layer?
+ if ( nextFrame == null ) {
+ return false;
+ }
+ }
+
+ if ( lastFrame && nextFrame ) {
+ doTween(
+ lastFrame.value,
+ nextFrame.value,
+ nextFrame.isTweenable,
+ target,
+ ( nextFrame.tween || this.tween || animation.tween ).type,
+ ( sinceStart - lastFrame.index / animation.rate ) *
+ animation.rate / ( nextFrame.index - lastFrame.index )
+ );
+ }
+
+ // this layer is not complete
+ return true;
+ }
+ };
+
+ // doTween( ... )
+ // recursively tween values
+ function doTween( lastValue, nextValue, isTweenable, target, tween, index ) {
+ if ( isTweenable === true ) {
+ return tween( lastValue, nextValue, index );
+ }
+
+ var key;
+
+ for ( key in nextValue ) {
+ target[ key ] = doTween(
+ lastValue[ key ],
+ nextValue[ key ],
+ isTweenable[ key ],
+ target[ key ],
+ tween,
+ index
+ );
+ }
+ return target;
+ };
+
+ // contains new target value and how to get there
+ function Frame( options ) {
+ Abacus.extend( this, options );
+
+ if ( this.tween ) {
+ this.tween = Abacus.tween({
+ type: this.tween
+ });
+ }
+
+ this.isTweenable = Abacus.clone( this.value );
+ calculateIsTweenable( this.value, this.isTweenable );
+ }
+
+ function calculateIsTweenable( values, isTweenable ) {
+ var key;
+
+ for ( key in values ) {
+ if ( typeof values[ key ] === 'number' ) {
+ isTweenable[ key ] = true;
+ } else {
+ calculateIsTweenable( values[ key ], isTweenable[ key ] );
+ }
+ }
+ }
+
+ Abacus.animation = function( options ) {
+ return new Animation( options );
+ };
+
+ Abacus.animation.layer = function( options ) {
+ return new Layer( options );
+ };
+
+ Abacus.animation.frame = function( options ) {
+ return new Frame( options );
+ };
+
+})( this );
View
8 src/abacus.js
@@ -84,6 +84,14 @@
return arg;
};
+ // Abacus.prefix
+ // This user agent's vendor prefix
+ Abacus.prefix = (function( window ) {
+ return [ "webkit", "moz", "ms", "o" ].filter(function( val ) {
+ return val + "RequestAnimationFrame" in window;
+ })[ 0 ] || "";
+ })( window );
+
// Expose global Abacus object
window.Abacus = Abacus;
View
5 src/abacus.timer.js
@@ -33,7 +33,8 @@
}
};
- // Timer constructor (Internal)
+ // Timer constructor (internal)
+ // Mapped from calls to Abacus.timer( options )
function Timer( options ) {
// options is expected to have optional
// callback and element properties
@@ -50,6 +51,7 @@
this.isPaused = false;
this.timing = {
delta: 0,
+ sinceStart: 0,
// how many times callback is called
ticks: 0
@@ -60,6 +62,7 @@
var now = Date.now();
this.timing.delta = now - this.lastTick;
+ this.timing.sinceStart = now - this.lastStart;
this.lastTick = now;
// Check to see if the timer is paused, or run over until time but ran
View
7 src/abacus.tween.js
@@ -28,7 +28,8 @@
return Abacus.noop;
}
-
+ // Tween constructor (internal)
+ // Mapped from calls to Abacus.tween( options )
function Tween( options ) {
options = options || {};
@@ -52,8 +53,10 @@
tweenFn( val );
}
});
- } //Tween
+ }
+ // Abacus.tween( options )
+ // Returns new Tween object instance
Abacus.tween = function( options ) {
return new Tween( options );
};
View
2  test/index.html
@@ -12,11 +12,13 @@
<script src="../src/abacus.tween.js"></script>
<script src="../src/abacus.timer.js"></script>
<script src="../src/abacus.input.js"></script>
+ <script src="../src/abacus.animation.js"></script>
<!-- tests -->
<script src="unit/abacus.js"></script>
<script src="unit/abacus.tween.js"></script>
<script src="unit/abacus.timer.js"></script>
<script src="unit/abacus.input.js"></script>
+ <script src="unit/abacus.animation.js"></script>
</head>
<body>
<h1 id="qunit-header">Abacus Unit Tests</h1>
View
109 test/unit/abacus.animation.js
@@ -0,0 +1,109 @@
+module('Animation');
+
+test('animation defined functions exists', 3, function() {
+ ok( Abacus.animation, 'animation exists' );
+ ok( Abacus.animation.layer, 'animation.layer exists' );
+ ok( Abacus.animation.frame, 'animation.frame exists' );
+});
+
+test('layer.step updates values', 2, function() {
+ var position = [0, 0],
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 0,
+ value: [0, 0]
+ }).addFrame({
+ index: 10,
+ value: [1, 1]
+ });
+
+ layer.step({rate: 5}, position, {sinceStart: 1000});
+
+ equal(position[0], 0.5);
+ equal(position[1], 0.5);
+});
+
+test('layer.step moves to correct frame', 1, function() {
+ var obj = {'a': 0},
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 0,
+ value: {'a': 0}
+ }).addFrame({
+ index: 5,
+ value: {'a': 1}
+ }).addFrame({
+ index: 10,
+ value: {'a': 2}
+ });
+
+ layer.step({rate: 5}, obj, {sinceStart: 1500});
+
+ equal(obj.a, 1.5);
+});
+
+test('layer.step returns false after completion', function() {
+ var layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 0,
+ value: []
+ }).addFrame({
+ index: 10,
+ value: []
+ });
+
+ ok(!layer.step({rate: 5}, [], {sinceStart: 3000}));
+ ok(!layer.step({rate: 5}, [], {sinceStart: 4000}));
+});
+
+test('layer.step calls beforeTween and afterTween', 2, function() {
+ var layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 10,
+ value: [],
+ beforeTween: function() {
+ ok(true, 'before');
+ },
+ afterTween: function() {
+ ok(true, 'and after');
+ }
+ });
+
+ layer.step({rate: 5}, [], {sinceStart: 3000});
+ layer.step({rate: 5}, [], {sinceStart: 4000});
+});
+
+asyncTest('animation stops timer after completion', 3, function() {
+ var timePlayed = 0,
+ animation = Abacus.animation({
+ rate: 60,
+ tween: 'linear'
+ });
+
+ animation.layer().addFrame({
+ index: 0,
+ value: []
+ }).addFrame({
+ index: 10,
+ value: [],
+ afterTween: function() {
+ timePlayed = animation.timer.timing.sinceStart;
+ }
+ });
+
+ animation.start([]);
+
+ setTimeout(function() {
+ ok(timePlayed > 1000/6, 'timePlayed (' + timePlayed + ') > ' + Math.floor(1000/6));
+ equal(animation.layers[0].frameIndex, 1, 'reached end of frames');
+ ok(animation.timer.isPaused);
+ if (!animation.timer.isPaused) {
+ animation.timer.pause();
+ }
+ start();
+ }, 300);
+});
View
30 test/unit/abacus.input.js
@@ -1,24 +1,22 @@
-/*
-document.addEventListener('keydown', function( e ){
+module('Timer Module');
+test('Test that the Abacus.inputs exists', 1, function() {
+ ok( Abacus.inputs, 'Abacus.inputs exists' );
+});
+
- // write some code to trigger an event
+test('Test that the Abacus.inputs for char code 0 is updating', 1, function() {
document.addEventListener('keydown', function( e ){
- Abacus.inputs.state( e.keyCode, 'active')
- console.log( Abacus.inputs.state( Abacus.inputsLookup[ e.keyCode ] ) )
- }, false);
+ equal( Abacus.inputs['0'], 'inActive', 'Abacus.inputs["0"] is active' );
+ console.log(Abacus.inputs['0'], 'its happening')
-}, false);
-*/
+ }, false);
-/*
-// Trigger a keyboard event, not yet sure how to get it
-// to fire a keyCode:
-var event = document.createEvent("KeyboardEvent");
-event.initKeyboardEvent('keydown', true, true, window, 1);
-event.keyCode = 67;
-document.dispatchEvent(event);
+var evt = document.createEvent( 'KeyboardEvent' );
+evt.initKeyboardEvent( 'keydown', true, false, null, 0, false, 0, false, 65, 0 );
+document.dispatchEvent(evt);
-*/
+
+});
View
6 test/unit/abacus.js
@@ -1,4 +1,4 @@
-module('Abacus Core');
+module('Core');
test('Test that the Abacus object exists', 1, function() {
ok( Abacus, 'Abacus exists' );
});
@@ -83,3 +83,7 @@ test('Abacus.identity( arg )', 2, function() {
equal( typeof Abacus.identity, 'function', 'Abacus.identity is a function' );
equal( Abacus.identity( Abacus.noop ), Abacus.noop, 'Abacus.identity(Abacus.noop) returns Abacus.noop' );
});
+
+test('Abacus.prefix (ua vendor prefix)', 1, function() {
+ equal( typeof Abacus.prefix, 'string', 'Abacus.prefix is a string' );
+});
View
16 test/unit/abacus.timer.js
@@ -1,4 +1,4 @@
-module('Timer Module');
+module('Timer');
test('Test that the Abacus.timer exists', 1, function() {
ok( Abacus.timer, 'Abacus.timer exists' );
});
@@ -163,3 +163,17 @@ asyncTest('timerData.tick increments with 0-index', 5, function() {
});
timer.start();
});
+
+asyncTest('timerData.sinceStart is time since start', 5, function() {
+ var startTime = Date.now(),
+ timer = Abacus.timer({
+ callback: function( timerData ) {
+ ok(Math.abs(timerData.sinceStart - (Date.now() - startTime)) < 2, "" + timerData.sinceStart + " ~= " + (Date.now() - startTime));
+ if (timerData.ticks == 4) {
+ this.stop();
+ start();
+ }
+ }
+ });
+ timer.start();
+});
View
2  test/unit/abacus.tween.js
@@ -1,4 +1,4 @@
-module('Tween Module');
+module('Tween');
test('Test that the Abacus.tween exists', 1, function() {
ok( Abacus.tween, 'Abacus.tween exists' );
});
Please sign in to comment.
Something went wrong with that request. Please try again.