Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Animation tests #76

Merged
merged 16 commits into from

3 participants

@mzgoddard
Collaborator

Progress on #56.

@rwaldron rwaldron commented on the diff
src/abacus.animation.js
@@ -252,6 +252,16 @@
// at end of layer?
if ( nextFrame == null ) {
+ doTween(
+ lastFrame.value,
+ lastFrame.value,
+ lastFrame.tweenable,
+ lastFrame.keys,
+ target,
+ ( lastFrame.tween || this.tween || animation.tween ).type,
+ 0
+ );
+
@rwaldron
rwaldron added a note

Why not pass an object to doTween instead of the longest param list ever?

@mzgoddard Collaborator

I can understand the maintainability of an object here to explicitly state the use of each parameter locally. But each parameter is required and not optional. Since all parameters are required and it is used internally I think using a parameter list is fine.

I am trying to balance a maintainable design and a fast design for this function (layer.step) since it will be run frequently. One of the things I am trying to avoid to achieve that is unnecessary object instantiation and later garbage collection. I view this as an instance where object instantiation would be unnecessary.

Since the function is recursive, creating objects for the parameter list would be even heavier performance wise.

@rwaldron
rwaldron added a note

Nothing better then a sound argument :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@rwaldron rwaldron merged commit 251da13 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 20, 2011
  1. @mzgoddard
  2. @andrewdolce @mzgoddard
  3. @andrewdolce @mzgoddard

    Removed use of arugments.length from tween.get and added unit test fo…

    andrewdolce authored mzgoddard committed
    …r tween.get() with no args.
  4. @mzgoddard
  5. @mzgoddard
  6. @mzgoddard
Commits on Oct 21, 2011
  1. @mzgoddard
Commits on Nov 27, 2011
  1. @mzgoddard
  2. @mzgoddard
  3. @mzgoddard
Commits on Nov 28, 2011
  1. @mzgoddard
Commits on Nov 30, 2011
  1. @mzgoddard
  2. @mzgoddard

    test: animation.stop stops #56

    mzgoddard authored
  3. @mzgoddard

    test: deep object animation #56

    mzgoddard authored
  4. @mzgoddard
  5. @mzgoddard
This page is out of date. Refresh to see the latest.
Showing with 216 additions and 2 deletions.
  1. +11 −1 src/abacus.animation.js
  2. +205 −1 test/unit/abacus.animation.js
View
12 src/abacus.animation.js
@@ -87,7 +87,7 @@
}
for ( key = 0, length = keys.length; key < length; key++ ) {
- keys.push( cacheKeys( values[ key ] , [] ) );
+ keys.push( cacheKeys( values[ keys[ key ] ] , [] ) );
}
return keys;
@@ -252,6 +252,16 @@
// at end of layer?
if ( nextFrame == null ) {
+ doTween(
+ lastFrame.value,
+ lastFrame.value,
+ lastFrame.tweenable,
+ lastFrame.keys,
+ target,
+ ( lastFrame.tween || this.tween || animation.tween ).type,
+ 0
+ );
+
@rwaldron
rwaldron added a note

Why not pass an object to doTween instead of the longest param list ever?

@mzgoddard Collaborator

I can understand the maintainability of an object here to explicitly state the use of each parameter locally. But each parameter is required and not optional. Since all parameters are required and it is used internally I think using a parameter list is fine.

I am trying to balance a maintainable design and a fast design for this function (layer.step) since it will be run frequently. One of the things I am trying to avoid to achieve that is unnecessary object instantiation and later garbage collection. I view this as an instance where object instantiation would be unnecessary.

Since the function is recursive, creating objects for the parameter list would be even heavier performance wise.

@rwaldron
rwaldron added a note

Nothing better then a sound argument :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
return false;
}
}
View
206 test/unit/abacus.animation.js
@@ -6,6 +6,155 @@ test('animation defined functions exists', 3, function() {
ok( Abacus.animation.frame, 'animation.frame exists' );
});
+test('animation methods', 5, function() {
+ var animation = Abacus.animation({});
+
+ ok( animation.reset, 'animation.reset exists' );
+ ok( animation.start, 'animation.start exists' );
+ ok( animation.stop, 'animation.stop exists' );
+ ok( animation.addLayer, 'animation.addLayer exists' );
+ ok( animation.layer, 'animation.layer exists' );
+});
+
+test('layer methods', 5, function() {
+ var layer = Abacus.animation.layer();
+
+ ok( layer.reset, 'layer.reset exists' );
+ ok( layer.step, 'layer.step exists' );
+ ok( layer.addFrame, 'layer.addFrame exists' );
+ ok( layer.removeFrame, 'layer.removeFrame exists' );
+ ok( layer.getFrame, 'layer.getFrame exists' );
+});
+
+test('animation() fails', 1, function() {
+ raises(function() {
+ Abacus.animation();
+ }, 'animation() cannot be called without options object');
+});
+
+test('layer.removeFrame', 8, function() {
+ var obj = {'x': 0, 'y': 0},
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }),
+ fourthFrame = Abacus.animation.frame({
+ index: 40,
+ value: {'x': 8, 'y': 8}
+ });
+
+ layer.addFrame({
+ index: 0,
+ value: {'x': 0, 'y': 0}
+ });
+
+ layer.addFrame({
+ index: 10,
+ value: {'x': 1, 'y': 1}
+ });
+
+ layer.addFrame({
+ index: 20,
+ value: {'x': 4, 'y': 4}
+ });
+
+ layer.addFrame( fourthFrame );
+
+ layer.step( {rate: 5}, obj, {sinceStart: 1000} );
+
+ equal( obj.x, 0.5, 'x value in between first two frames' );
+ equal( obj.y, 0.5, 'y value in between first two frames' );
+
+ layer.removeFrame( 10 );
+
+ layer.step( {rate: 5}, obj, {sinceStart: 1000} );
+
+ equal( obj.x, 1, 'x value in between first and third frames (after removal of second frame)' );
+ equal( obj.y, 1, 'y value in between first and third frames (after removal of second frame)' );
+
+ layer.step( {rate: 5}, obj, {sinceStart: 8000} );
+
+ equal( obj.x, 8, 'x value at end of fourth frame' );
+ equal( obj.y, 8, 'y value at end of fourth frame' );
+
+ layer.removeFrame( fourthFrame );
+
+ layer.reset();
+ layer.step( {rate: 5}, obj, {sinceStart: 8000} );
+
+ equal( obj.x, 4, 'x value at end of third frame (after removal of third)' );
+ equal( obj.y, 4, 'y value at end of third frame (after removal of third)' );
+});
+
+test('layer sets values after hitting end of last frame', 2, function(){
+ var obj = {'x': 0, 'y': 0},
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 0,
+ value: {'x': 1, 'y': 1}
+ });
+
+ layer.step({rate: 5}, obj, {sinceStart: 1000});
+
+ equal( obj.x, 1 );
+ equal( obj.y, 1 );
+});
+
+test('layer does not set values before first frame (aka non-zero index )', 2, function(){
+ var obj = {'x': 0, 'y': 0},
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 10,
+ value: {'x': 1, 'y': 1}
+ });
+
+ layer.step({rate: 5}, obj, {sinceStart: 1000});
+
+ notEqual( obj.x, 1 );
+ notEqual( obj.y, 1 );
+});
+
+asyncTest('animation.stop stops animation', 6, function(){
+ var obj = {'x': 0, 'y': 0},
+ animation = Abacus.animation({
+ rate: 50,
+ tween: 'linear'
+ }).addLayer(Abacus.animation.layer().addFrame({
+ index: 0,
+ value: {'x': 0, 'y': 0}
+ }).addFrame({
+ index: 10,
+ value: {'x': 1, 'y': 1}
+ })),
+ x,
+ y;
+
+ animation.start( obj );
+
+ setTimeout(function(){
+ animation.stop();
+
+ // not equal to the start of the animation
+ notEqual( obj.x, 0 );
+ notEqual( obj.y, 0 );
+
+ x = obj.x;
+ y = obj.y;
+
+ setTimeout(function(){
+ // not equal to the end of the animation
+ notEqual( obj.x, 1 );
+ notEqual( obj.y, 1 );
+
+ equal( obj.x, x );
+ equal( obj.y, y );
+
+ start();
+ }, 200);
+ }, 100);
+});
+
test('layer.step updates values', 2, function() {
var position = [0, 0],
layer = Abacus.animation.layer({
@@ -100,7 +249,7 @@ asyncTest('animation stops timer after completion', 3, function() {
setTimeout(function() {
ok( timePlayed > 1000/6, 'timePlayed (' + timePlayed + ') > ' + Math.floor(1000/6) );
- equal( animation.layers[0].frameIndex, -1, 'reached end of frames' );
+ equal( animation.layers[0].frameIndex, -1, 'auto-reset to start of animatio' );
ok( animation.timer.isPaused );
if ( !animation.timer.isPaused ) {
animation.timer.pause();
@@ -109,6 +258,61 @@ asyncTest('animation stops timer after completion', 3, function() {
}, 300);
});
+test('deep object animation', 2, function() {
+ var obj = {
+ x: 0,
+ ary: [ 0, 0, 0 ],
+ deep: {
+ ary: [{x: 0, y: 0}, {x: 0, y: 0}]
+ }
+ },
+ layer = Abacus.animation.layer({
+ tween: 'linear'
+ }).addFrame({
+ index: 0,
+ value: {
+ x: 0,
+ ary: [ 0, 0, 0 ],
+ deep: {
+ ary: [{}, {
+ x: 0,
+ y: 0
+ }]
+ }
+ }
+ }).addFrame({
+ index: 10,
+ value: {
+ x: 6,
+ ary: [ 1, 2, 3 ],
+ deep: {
+ ary: [{}, {
+ x: 4,
+ y: 5
+ }]
+ }
+ }
+ });
+
+ layer.step({ rate: 5 }, obj, { sinceStart: 2000 });
+
+ equal( obj.x, 6 );
+
+ deepEqual( obj, {
+ x: 6,
+ ary: [ 1, 2, 3 ],
+ deep: {
+ ary: [{
+ x: 0,
+ y: 0
+ }, {
+ x: 4,
+ y: 5
+ }]
+ }
+ }, 'deep object animation set all appropriate values' );
+});
+
test('layer works with typed arrays', 7, function() {
ok( window.Float32Array, 'browser supports Float32Array' );
Something went wrong with that request. Please try again.