1suite('group-player', function() { 2 setup(function() { 3 document.timeline._players = []; 4 webAnimations1.timeline._players = []; 5 this.elements = []; 6 7 var animationMargin = function(target) { 8 return new Animation( 9 target, 10 [ 11 {marginLeft: '0px'}, 12 {marginLeft: '100px'} 13 ], 14 500); 15 }; 16 var animationColor = function(target) { 17 return new Animation( 18 target, 19 [ 20 {backgroundColor: 'black'}, 21 {backgroundColor: 'white'} 22 ], 23 500); 24 }; 25 var sequenceEmpty = function() { 26 return new AnimationSequence(); 27 }; 28 var groupEmpty = function() { 29 return new AnimationGroup(); 30 }; 31 var sequenceWithEffects = function(target) { 32 return new AnimationSequence( 33 [ 34 animationMargin(target), 35 animationColor(target) 36 ]); 37 }; 38 var groupWithEffects = function(target) { 39 return new AnimationGroup( 40 [ 41 animationMargin(target), 42 animationColor(target) 43 ]); 44 }; 45 46 var seqEmpty_source = sequenceEmpty(); 47 48 var seqSimple_target = document.createElement('div'); 49 this.elements.push(seqSimple_target); 50 var seqSimple_source = sequenceWithEffects(seqSimple_target); 51 52 var seqWithSeq_target = document.createElement('div'); 53 this.elements.push(seqWithSeq_target); 54 var seqWithSeq_source = new AnimationSequence( 55 [ 56 animationMargin(seqWithSeq_target), 57 animationColor(seqWithSeq_target), 58 sequenceWithEffects(seqWithSeq_target) 59 ]); 60 61 var seqWithGroup_target = document.createElement('div'); 62 this.elements.push(seqWithGroup_target); 63 var seqWithGroup_source = new AnimationSequence( 64 [ 65 animationMargin(seqWithGroup_target), 66 animationColor(seqWithGroup_target), 67 groupWithEffects(seqWithGroup_target) 68 ]); 69 70 var seqWithEmptyGroup_source = new AnimationSequence([groupEmpty()]); 71 var seqWithEmptySeq_source = new AnimationSequence([sequenceEmpty()]); 72 73 var groupEmpty_source = groupEmpty(); 74 75 var groupSimple_target = document.createElement('div'); 76 var groupSimple_source = groupWithEffects(groupSimple_target); 77 78 var groupWithSeq_target = document.createElement('div'); 79 this.elements.push(groupWithSeq_target); 80 var groupWithSeq_source = new AnimationGroup( 81 [ 82 animationMargin(groupWithSeq_target), 83 animationColor(groupWithSeq_target), 84 sequenceWithEffects(groupWithSeq_target) 85 ]); 86 87 var groupWithGroup_target = document.createElement('div'); 88 this.elements.push(groupWithGroup_target); 89 var groupWithGroup_source = new AnimationGroup( 90 [ 91 animationMargin(groupWithGroup_target), 92 animationColor(groupWithGroup_target), 93 groupWithEffects(groupWithGroup_target) 94 ]); 95 96 var groupWithEmptyGroup_source = new AnimationGroup([groupEmpty()]); 97 var groupWithEmptySeq_source = new AnimationGroup([sequenceEmpty()]); 98 99 this.seqEmpty_source = seqEmpty_source; 100 this.seqSimple_source = seqSimple_source; 101 this.seqWithSeq_source = seqWithSeq_source; 102 this.seqWithGroup_source = seqWithGroup_source; 103 this.seqWithEmptyGroup_source = seqWithEmptyGroup_source; 104 this.seqWithEmptySeq_source = seqWithEmptySeq_source; 105 106 this.groupEmpty_source = groupEmpty_source; 107 this.groupSimple_source = groupSimple_source; 108 this.groupWithSeq_source = groupWithSeq_source; 109 this.groupWithGroup_source = groupWithGroup_source; 110 this.groupWithEmptyGroup_source = groupWithEmptyGroup_source; 111 this.groupWithEmptySeq_source = groupWithEmptySeq_source; 112 113 this.staticAnimation = function(target, value, duration) { 114 var animation = new Animation(target, [{marginLeft: value}, {marginLeft: value}], duration); 115 animation.testValue = value; 116 return animation; 117 }; 118 // The following animation structure looks like: 119 // 44444 120 // 11 121 // 33 122 // 2 123 // 0 124 this.complexTarget = document.createElement('div'); 125 this.elements.push(this.complexTarget); 126 this.complexSource = new AnimationGroup([ 127 this.staticAnimation(this.complexTarget, '4px', 5), 128 new AnimationSequence([ 129 this.staticAnimation(this.complexTarget, '1px', 2), 130 new AnimationGroup([ 131 this.staticAnimation(this.complexTarget, '3px', 2), 132 this.staticAnimation(this.complexTarget, '2px', 1), 133 ]), 134 ]), 135 this.staticAnimation(this.complexTarget, '0px', 1), 136 ]); 137 138 this.target = document.createElement('div'); 139 this.elements.push(this.target); 140 141 for (var i = 0; i < this.elements.length; i++) 142 document.documentElement.appendChild(this.elements[i]); 143 }); 144 145 teardown(function() { 146 for (var i = 0; i < this.elements.length; i++) { 147 if (this.elements[i].parent) 148 this.elements[i].parent.removeChild(this.elements[i]); 149 } 150 }); 151 152 function simpleAnimationGroup() { 153 return new AnimationGroup([new Animation(document.body, [], 2000), new Animation(document.body, [], 1000), new Animation(document.body, [], 3000)]); 154 } 155 156 function simpleAnimationSequence() { 157 return new AnimationSequence([new Animation(document.body, [], 2000), new Animation(document.body, [], 1000), new Animation(document.body, [], 3000)]); 158 } 159 160 // FIXME: Remove _startOffset. 161 // playerState is [startTime, currentTime, _startOffset?, offset?] 162 // innerPlayerStates is a nested array tree of playerStates e.g. [[0, 0], [[1, -1], [2, -2]]] 163 function checkTimes(player, playerState, innerPlayerStates, description) { 164 description = description ? (description + ' ') : ''; 165 _checkTimes(player, playerState, 0, description + 'top player'); 166 _checkTimes(player, innerPlayerStates, 0, description + 'inner player'); 167 } 168 169 function _checkTimes(player, timingList, index, trace) { 170 assert.isDefined(player, trace + ' exists'); 171 if (timingList.length == 0) { 172 assert.equal(player._childPlayers.length, index, trace + ' no remaining players'); 173 return; 174 } 175 if (timingList[0] === null || typeof timingList[0] == 'number') { 176 assert.equal(player.startTime, timingList[0], trace + ' startTime'); 177 assert.equal(player.currentTime, timingList[1], trace + ' currentTime'); 178 } else { 179 _checkTimes(player._childPlayers[index], timingList[0], 0, trace + ' ' + index); 180 _checkTimes(player, timingList.slice(1), index + 1, trace); 181 } 182 } 183 184 test('playing an animationGroup works as expected', function() { 185 tick(90); 186 var p = document.timeline.play(simpleAnimationGroup()); 187 checkTimes(p, [null, 0], [[null, 0], [null, 0], [null, 0]]); 188 tick(100); 189 checkTimes(p, [100, 0], [[100, 0], [100, 0], [100, 0]]); 190 tick(300); 191 checkTimes(p, [100, 200], [[100, 200], [100, 200], [100, 200]]); 192 tick(1200); 193 checkTimes(p, [100, 1100], [[100, 1100], [100, 1000], [100, 1100]]); 194 tick(2200); 195 checkTimes(p, [100, 2100], [[100, 2000], [100, 1000], [100, 2100]]); 196 tick(3200); 197 checkTimes(p, [100, 3000], [[100, 2000], [100, 1000], [100, 3000]]); 198 }); 199 200 test('can seek an animationGroup', function() { 201 tick(90); 202 var p = document.timeline.play(simpleAnimationGroup()); 203 tick(100); 204 checkTimes(p, [100, 0], [[100, 0], [100, 0], [100, 0]]); 205 p.currentTime = 200; 206 checkTimes(p, [-100, 200], [[-100, 200], [-100, 200], [-100, 200]]); 207 p.currentTime = 1100; 208 checkTimes(p, [-1000, 1100], [[-1000, 1100], [-1000, 1100], [-1000, 1100]]); 209 p.currentTime = 2100; 210 checkTimes(p, [-2000, 2100], [[-2000, 2100], [-2000, 2100], [-2000, 2100]]); 211 p.currentTime = 3100; 212 checkTimes(p, [-3000, 3100], [[-3000, 3100], [-3000, 3100], [-3000, 3100]]); 213 }); 214 215 test('can startTime seek an animationGroup', function() { 216 tick(90); 217 var p = document.timeline.play(simpleAnimationGroup()); 218 tick(100); 219 checkTimes(p, [100, 0], [[100, 0], [100, 0], [100, 0]]); 220 p.startTime = -100; 221 checkTimes(p, [-100, 200], [[-100, 200], [-100, 200], [-100, 200]]); 222 p.startTime = -1000; 223 checkTimes(p, [-1000, 1100], [[-1000, 1100], [-1000, 1000], [-1000, 1100]]); 224 p.startTime = -2000; 225 checkTimes(p, [-2000, 2100], [[-2000, 2000], [-2000, 1000], [-2000, 2100]]); 226 p.startTime = -3000; 227 checkTimes(p, [-3000, 3000], [[-3000, 2000], [-3000, 1000], [-3000, 3000]]); 228 }); 229 230 test('playing an animationSequence works as expected', function() { 231 tick(100); 232 var p = document.timeline.play(simpleAnimationSequence()); 233 tick(110); 234 checkTimes(p, [110, 0], [[110, 0], [2110, -2000], [3110, -3000]]); 235 tick(210); 236 checkTimes(p, [110, 100], [[110, 100], [2110, -1900], [3110, -2900]]); 237 tick(2210); 238 checkTimes(p, [110, 2100], [[110, 2000], [2110, 100], [3110, -900]]); 239 tick(3210); 240 checkTimes(p, [110, 3100], [[110, 2000], [2110, 1000], [3110, 100]]); 241 tick(6210); 242 checkTimes(p, [110, 6000], [[110, 2000], [2110, 1000], [3110, 3000]]); 243 }); 244 245 test('can seek an animationSequence', function() { 246 tick(100); 247 var p = document.timeline.play(simpleAnimationSequence()); 248 tick(110); 249 checkTimes(p, [110, 0], [[110, 0], [2110, -2000], [3110, -3000]]); 250 p.currentTime = 100; 251 checkTimes(p, [10, 100], [[10, 100], [2010, -1900], [3010, -2900]]); 252 p.currentTime = 2100; 253 checkTimes(p, [-1990, 2100], [[-1990, 2100], [10, 100], [1010, -900]]); 254 p.currentTime = 3100; 255 checkTimes(p, [-2990, 3100], [[-2990, 3100], [-990, 1100], [10, 100]]); 256 p.currentTime = 6100; 257 checkTimes(p, [-5990, 6100], [[-5990, 6100], [-3990, 4100], [-2990, 3100]]); 258 }); 259 260 test('can startTime seek an animationSequence', function() { 261 tick(100); 262 var p = document.timeline.play(simpleAnimationSequence()); 263 tick(110); 264 checkTimes(p, [110, 0], [[110, 0], [2110, -2000], [3110, -3000]]); 265 p.startTime = 10; 266 checkTimes(p, [10, 100], [[10, 100], [2010, -1900], [3010, -2900]]); 267 p.startTime = -1990; 268 checkTimes(p, [-1990, 2100], [[-1990, 2000], [10, 100], [1010, -900]]); 269 p.startTime = -2990; 270 checkTimes(p, [-2990, 3100], [[-2990, 2000], [-990, 1000], [10, 100]]); 271 p.startTime = -5990; 272 checkTimes(p, [-5990, 6000], [[-5990, 2000], [-3990, 1000], [-2990, 3000]]); 273 }); 274 275 test('complex animation tree timing while playing', function() { 276 tick(90); 277 var player = document.timeline.play(this.complexSource); 278 tick(100); 279 checkTimes(player, [100, 0], [ 280 [100, 0], [ // 4 281 [100, 0], [ // 1 282 [102, -2], // 3 283 [102, -2]]], // 2 284 [100, 0], // 0 285 ], 't = 100'); 286 tick(101); 287 checkTimes(player, [100, 1], [ 288 [100, 1], [ // 4 289 [100, 1], [ // 1 290 [102, -1], // 3 291 [102, -1]]], // 2 292 [100, 1], // 0 293 ], 't = 101'); 294 tick(102); 295 checkTimes(player, [100, 2], [ 296 [100, 2], [ // 4 297 [100, 2], [ // 1 298 [102, 0], // 3 299 [102, 0]]], // 2 300 [100, 1], // 0 301 ], 't = 102'); 302 }); 303 304 test('effects apply in the correct order', function() { 305 tick(0); 306 var player = document.timeline.play(this.complexSource); 307 player.currentTime = 0; 308 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '0px'); 309 player.currentTime = 1; 310 checkTimes(player, [-1, 1], [[-1, 1, 0], [[-1, 1, 0], [[1, -1, 0], [1, -1, 0]]], [-1, 1, 0]]); 311 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '1px'); 312 player.currentTime = 2; 313 // TODO: When we seek we don't limit. Is this OK? 314 checkTimes(player, [-2, 2], [[-2, 2, 0], [[-2, 2, 0], [[0, 0, 0], [0, 0, 0]]], [-2, 2, 0]]); 315 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '2px'); 316 player.currentTime = 3; 317 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '3px'); 318 player.currentTime = 4; 319 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '4px'); 320 player.currentTime = 5; 321 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '0px'); 322 }); 323 324 test('cancelling group players', function() { 325 tick(0); 326 var player = document.timeline.play(this.complexSource); 327 tick(1); 328 tick(4); 329 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '3px'); 330 player.cancel(); 331 assert.equal(player.currentTime, null); 332 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '0px'); 333 }); 334 335 test('cancelling group players before tick', function() { 336 tick(0); 337 var player = document.timeline.play(this.complexSource); 338 player.cancel(); 339 assert.equal(player.currentTime, null); 340 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '0px'); 341 tick(4); 342 assert.equal(player.currentTime, null); 343 assert.equal(getComputedStyle(this.complexTarget).marginLeft, '0px'); 344 }); 345 346 test('redundant animation node wrapping', function() { 347 tick(100); 348 var animation = new AnimationSequence([ 349 this.staticAnimation(this.target, '0px', 1), 350 new AnimationGroup([ 351 new AnimationSequence([ 352 this.staticAnimation(this.target, '1px', 1), 353 this.staticAnimation(this.target, '2px', 1), 354 ]), 355 ]), 356 ]); 357 var player = document.timeline.play(animation); 358 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 359 checkTimes(player, [100, 0], [ 360 [100, 0, 0, 0], [[ // 0 361 [101, -1, 0, 1], // 1 362 [102, -2, 1, 2]]] // 2 363 ], 't = 100'); 364 tick(101); 365 assert.equal(getComputedStyle(this.target).marginLeft, '1px'); 366 checkTimes(player, [100, 1], [ 367 [100, 1, 0, 0], [[ // 0 368 [101, 0, 0, 1], // 1 369 [102, -1, 1, 2]]] // 2 370 ], 't = 101'); 371 tick(102); 372 assert.equal(getComputedStyle(this.target).marginLeft, '2px'); 373 assert.equal(document.timeline.currentTime, 102); 374 checkTimes(player, [100, 2], [ // FIXME: Implement limiting on group players 375 [100, 1, 0, 0], [[ // 0 376 [101, 1, 0, 1], // 1 377 [102, 0, 1, 2]]] // 2 378 ], 't = 102'); 379 tick(103); 380 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 381 checkTimes(player, [100, 3], [ // FIXME: Implement limiting on group players 382 [100, 1, 0, 0], [[ // 0 383 [101, 1, 0, 1], // 1 384 [102, 1, 1, 2]]] // 2 385 ], 't = 103'); 386 if (this.target.parent) 387 this.target.parent.removeChild(target); 388 }); 389 390 test('setting the playbackRate on group players', function() { 391 var group = new AnimationGroup([ 392 new Animation(null, [], 1234), 393 new Animation(null, [], 1234), 394 ]); 395 var p = document.timeline.play(group); 396 p.playbackRate = 2; 397 assert.equal(p._player.playbackRate, 2, 'Updates the playbackRate of the inner player'); 398 p._childPlayers.forEach(function(childPlayer) { 399 assert.equal(childPlayer.playbackRate, 2, 'It also updates the child players'); 400 }); 401 }); 402 403 test('delays on groups work correctly', function() { 404 // 444 405 // 1 406 // 0 407 // 33 408 // 2 409 var animation = new AnimationGroup([ 410 new AnimationGroup([ 411 this.staticAnimation(this.target, '4px', {duration: 3, delay: 1}), 412 this.staticAnimation(this.target, '1px', {duration: 1, delay: 0}), 413 ], {delay: 1}), 414 new AnimationSequence([ 415 this.staticAnimation(this.target, '0px', {duration: 1, delay: 0}), 416 this.staticAnimation(this.target, '3px', {duration: 2, delay: 1}), 417 this.staticAnimation(this.target, '2px', {duration: 1, delay: -2}), 418 ]), 419 ]); 420 var player = document.timeline.play(animation); 421 tick(100); 422 checkTimes(player, [100, 0], [ 423 [ 424 [101, -1], 425 [101, -1], 426 ], [ 427 [100, 0], 428 [101, -1], 429 [104, -4], 430 ] 431 ]); 432 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 433 tick(101); 434 assert.equal(getComputedStyle(this.target).marginLeft, '1px'); 435 tick(102); 436 assert.equal(getComputedStyle(this.target).marginLeft, '2px'); 437 tick(103); 438 assert.equal(getComputedStyle(this.target).marginLeft, '3px'); 439 tick(104); 440 assert.equal(getComputedStyle(this.target).marginLeft, '4px'); 441 tick(105); 442 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 443 }); 444 445 test('end delays on groups work correctly', function() { 446 // 11 447 // 4 448 // 0 449 // 33 450 // 2 451 var animation = new AnimationSequence([ 452 new AnimationSequence([ 453 this.staticAnimation(this.target, '1px', {duration: 2, endDelay: 2}), 454 this.staticAnimation(this.target, '4px', {duration: 1, endDelay: 1}), 455 ], {endDelay: -6}), 456 new AnimationSequence([ 457 this.staticAnimation(this.target, '0px', {duration: 1, endDelay: 1}), 458 this.staticAnimation(this.target, '3px', {duration: 2, endDelay: -2}), 459 this.staticAnimation(this.target, '2px', {duration: 1, endDelay: 2}), 460 ]), 461 ]); 462 var player = document.timeline.play(animation); 463 tick(100); 464 checkTimes(player, [100, 0], [ 465 [ 466 [100, 0], 467 [104, -4], 468 ], [ 469 [100, 0], 470 [102, -2], 471 [102, -2], 472 ] 473 ]); 474 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 475 tick(101); 476 assert.equal(getComputedStyle(this.target).marginLeft, '1px'); 477 tick(102); 478 assert.equal(getComputedStyle(this.target).marginLeft, '2px'); 479 tick(103); 480 assert.equal(getComputedStyle(this.target).marginLeft, '3px'); 481 tick(104); 482 // FIXME: Group child player limiting bounds should match the parent player's limiting bounds. 483 // assert.equal(getComputedStyle(this.target).marginLeft, '4px'); 484 // tick(105); 485 // assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 486 }); 487 488 // FIXME: This test can be removed when this suite is finished. 489 test('sources are working for basic operations', function() { 490 var players = []; 491 players.push(document.timeline.play(this.seqEmpty_source)); 492 players.push(document.timeline.play(this.seqSimple_source)); 493 players.push(document.timeline.play(this.seqWithSeq_source)); 494 players.push(document.timeline.play(this.seqWithGroup_source)); 495 players.push(document.timeline.play(this.seqWithEmptyGroup_source)); 496 players.push(document.timeline.play(this.seqWithEmptySeq_source)); 497 498 players.push(document.timeline.play(this.groupEmpty_source)); 499 players.push(document.timeline.play(this.groupSimple_source)); 500 players.push(document.timeline.play(this.groupWithSeq_source)); 501 players.push(document.timeline.play(this.groupWithGroup_source)); 502 players.push(document.timeline.play(this.groupWithEmptyGroup_source)); 503 players.push(document.timeline.play(this.groupWithEmptySeq_source)); 504 505 var length = players.length; 506 507 tick(50); 508 for (var i = 0; i < length; i++) 509 players[i].pause(); 510 511 tick(100); 512 for (var i = 0; i < length; i++) 513 players[i].play(); 514 515 tick(200); 516 for (var i = 0; i < length; i++) 517 players[i].currentTime += 1; 518 519 tick(300); 520 for (var i = 0; i < length; i++) 521 players[i].startTime += 1; 522 523 tick(350); 524 for (var i = 0; i < length; i++) 525 players[i].reverse(); 526 527 tick(400); 528 for (var i = 0; i < length; i++) 529 players[i].finish(); 530 531 tick(500); 532 tick(600); 533 for (var i = 0; i < length; i++) 534 players[i].cancel(); 535 536 for (var i = 0; i < length; i++) 537 players[i].play(); 538 }); 539 540 test('pausing works as expected with an empty AnimationSequence', function() { 541 var player = document.timeline.play(this.seqEmpty_source); 542 tick(0); 543 assert.equal(player.startTime, 0); 544 assert.equal(player.currentTime, 0); 545 546 player.pause(); 547 assert.equal(player.startTime, null); 548 assert.equal(player.currentTime, 0); 549 }); 550 551 test('pausing works as expected with a simple AnimationSequence', function() { 552 var player = document.timeline.play(this.seqSimple_source); 553 var target = this.seqSimple_source.children[0].target; 554 tick(0); 555 checkTimes(player, [0, 0], [[0, 0], [500, -500]], 't = 0'); 556 557 tick(200); 558 checkTimes(player, [0, 200], [[0, 200], [500, -300]], 't = 200'); 559 560 player.pause(); 561 checkTimes(player, [null, null], [[null, null], [null, null]], 't = 200'); 562 assert.equal(getComputedStyle(target).marginLeft, '40px'); 563 564 tick(300); 565 checkTimes(player, [null, 200], [[null, 200], [null, -300]], 't = 300'); 566 assert.equal(getComputedStyle(target).marginLeft, '40px'); 567 568 player.play(); 569 checkTimes(player, [null, 200], [[null, 200], [null, -300]], 't = 300'); 570 assert.equal(getComputedStyle(target).marginLeft, '40px'); 571 572 tick(301); 573 checkTimes(player, [101, 200], [[101, 200], [601, -300]], 't = 301'); 574 assert.equal(getComputedStyle(target).marginLeft, '40px'); 575 576 tick(401); 577 checkTimes(player, [101, 300], [[101, 300], [601, -200]], 't = 401'); 578 assert.equal(getComputedStyle(target).marginLeft, '60px'); 579 580 tick(700); 581 checkTimes(player, [101, 599], [[101, 500], [601, 99]], 't = 700'); 582 assert.equal(getComputedStyle(target).marginLeft, '0px'); 583 }); 584 585 test('pausing before tick works as expected with a simple AnimationSequence', function() { 586 var player = document.timeline.play(this.seqSimple_source); 587 var target = this.seqSimple_source.children[0].target; 588 checkTimes(player, [null, 0], [[null, 0], [null, -500]], 't = 0'); 589 590 player.pause(); 591 checkTimes(player, [null, null], [[null, null], [null, null]], 't = 0'); 592 assert.equal(getComputedStyle(target).marginLeft, '0px'); 593 594 tick(10); 595 checkTimes(player, [null, 0], [[null, 0], [null, -500]], 't = 10'); 596 assert.equal(getComputedStyle(target).marginLeft, '0px'); 597 598 tick(20); 599 checkTimes(player, [null, 0], [[null, 0], [null, -500]], 't = 10'); 600 assert.equal(getComputedStyle(target).marginLeft, '0px'); 601 }); 602 603 test('pausing and seeking before tick works as expected with a simple AnimationSequence', function() { 604 var player = document.timeline.play(this.seqSimple_source); 605 player.pause(); 606 607 player.currentTime = 0; 608 checkTimes(player, [null, 0], [[null, 0], [null, -500]], 't = 10'); 609 610 player.currentTime = 250; 611 checkTimes(player, [null, 250], [[null, 250], [null, -250]], 't = 10'); 612 613 player.currentTime = 500; 614 checkTimes(player, [null, 500], [[null, 500], [null, 0]], 't = 10'); 615 616 // FIXME: Expectation should be [null, 1000], [[null, 500], [null, 500]]. 617 player.currentTime = 1000; 618 checkTimes(player, [null, 1000], [[null, 1000], [null, 500]], 't = 10'); 619 }); 620 621 test('pausing works as expected with an AnimationSequence inside an AnimationSequence', function() { 622 var player = document.timeline.play(this.seqWithSeq_source); 623 tick(0); 624 checkTimes( 625 player, 626 [0, 0], [ 627 [0, 0], 628 [500, -500], [ 629 [1000, -1000], 630 [1500, -1500]]], 631 't = 0'); 632 633 tick(200); 634 checkTimes( 635 player, 636 [0, 200], [ 637 [0, 200], 638 [500, -300], [ 639 [1000, -800], 640 [1500, -1300]]], 641 't = 200'); 642 643 player.pause(); 644 checkTimes( 645 player, 646 [null, null], [ 647 [null, null], 648 [null, null], [ 649 [null, null], 650 [null, null]]], 651 't = 200'); 652 653 tick(300); 654 checkTimes( 655 player, 656 [null, 200], [ 657 [null, 200], 658 [null, -300], [ 659 [null, -800], 660 [null, -1300]]], 661 't = 300'); 662 663 player.play(); 664 tick(310); 665 checkTimes( 666 player, 667 [110, 200], [ 668 [110, 200], 669 [610, -300], [ 670 [1110, -800], 671 [1610, -1300]]], 672 't = 310'); 673 674 tick(1300); 675 checkTimes( 676 player, 677 [110, 1190], [ 678 [110, 500], 679 [610, 500], [ 680 [1110, 190], 681 [1610, -310]]], 682 't = 1300'); 683 684 player.pause(); 685 checkTimes( 686 player, 687 [null, null], [ 688 [null, 500], 689 [null, 500], [ 690 [null, null], 691 [null, null]]], 692 't = 1300'); 693 694 tick(1400); 695 checkTimes( 696 player, 697 [null, 1190], [ 698 [null, 500], 699 [null, 500], [ 700 [null, 190], 701 [null, -310]]], 702 't = 1400'); 703 704 player.play(); 705 checkTimes( 706 player, 707 [null, 1190], [ 708 [null, 500], 709 [null, 500], [ 710 [null, 190], 711 [null, -310]]], 712 't = 1400'); 713 714 tick(1410); 715 checkTimes( 716 player, 717 [220, 1190], [ 718 [220, 500], 719 [720, 500], [ 720 [1220, 190], 721 [1720, -310]]], 722 't = 1410'); 723 724 tick(1600); 725 checkTimes( 726 player, 727 [220, 1380], [ 728 [220, 500], 729 [720, 500], [ 730 [1220, 380], 731 [1720, -120]]], 732 't = 1600'); 733 734 player.pause(); 735 checkTimes( 736 player, 737 [null, null], [ 738 [null, 500], 739 [null, 500], [ 740 [null, null], 741 [null, null]]], 742 't = 1600'); 743 744 tick(1700); 745 checkTimes( 746 player, 747 [null, 1380], [ 748 [null, 500], 749 [null, 500], [ 750 [null, 380], 751 [null, -120]]], 752 't = 1700'); 753 754 player.play(); 755 tick(1710); 756 checkTimes( 757 player, 758 [330, 1380], [ 759 [330, 500], 760 [830, 500], [ 761 [1330, 380], 762 [1830, -120]]], 763 't = 1710'); 764 765 tick(2400); 766 checkTimes( 767 player, 768 [330, 2000], [ 769 [330, 500], 770 [830, 500], [ 771 [1330, 500], 772 [1830, 500]]], 773 't = 2400'); 774 }); 775 776 test('pausing works as expected with an AnimationGroup inside an AnimationSequence', function() { 777 var player = document.timeline.play(this.seqWithGroup_source); 778 tick(0); 779 checkTimes( 780 player, 781 [0, 0], [ 782 [0, 0], 783 [500, -500], [ 784 [1000, -1000], 785 [1000, -1000]]], 786 't = 0'); 787 788 tick(200); 789 checkTimes( 790 player, 791 [0, 200], [ 792 [0, 200], 793 [500, -300], [ 794 [1000, -800], 795 [1000, -800]]], 796 't = 200'); 797 798 player.pause(); 799 checkTimes( 800 player, 801 [null, null], [ 802 [null, null], 803 [null, null], [ 804 [null, null], 805 [null, null]]], 806 't = 200'); 807 808 tick(300); 809 checkTimes( 810 player, 811 [null, 200], [ 812 [null, 200], 813 [null, -300], [ 814 [null, -800], 815 [null, -800]]], 816 't = 300'); 817 818 player.play(); 819 tick(310); 820 checkTimes( 821 player, 822 [110, 200], [ 823 [110, 200], 824 [610, -300], [ 825 [1110, -800], 826 [1110, -800]]], 827 't = 310'); 828 829 tick(1310); 830 checkTimes( 831 player, 832 [110, 1200], [ 833 [110, 500], 834 [610, 500], [ 835 [1110, 200], 836 [1110, 200]]], 837 't = 1310'); 838 839 player.pause(); 840 checkTimes( 841 player, 842 [null, null], [ 843 [null, 500], 844 [null, 500], [ 845 [null, null], 846 [null, null]]], 847 't = 1310'); 848 849 tick(1400); 850 checkTimes( 851 player, 852 [null, 1200], [ 853 [null, 500], 854 [null, 500], [ 855 [null, 200], 856 [null, 200]]], 857 't = 1410'); 858 859 player.play(); 860 tick(1410); 861 checkTimes( 862 player, 863 [210, 1200], [ 864 [210, 500], 865 [710, 500], [ 866 [1210, 200], 867 [1210, 200]]], 868 't = 1410'); 869 870 tick(1610); 871 checkTimes( 872 player, 873 [210, 1400], [ 874 [210, 500], 875 [710, 500], [ 876 [1210, 400], 877 [1210, 400]]], 878 't = 1610'); 879 880 player.pause(); 881 tick(1810); 882 checkTimes( 883 player, 884 [null, 1400], [ 885 [null, 500], 886 [null, 500], [ 887 [null, 400], 888 [null, 400]]], 889 't = 1810'); 890 891 player.play(); 892 tick(1820); 893 checkTimes( 894 player, 895 [420, 1400], [ 896 [420, 500], 897 [920, 500], [ 898 [1420, 400], 899 [1420, 400]]], 900 't = 1820'); 901 902 tick(2020); 903 checkTimes( 904 player, 905 [420, 1500], [ 906 [420, 500], 907 [920, 500], [ 908 [1420, 500], 909 [1420, 500]]], 910 't = 2020'); 911 912 player.pause(); 913 checkTimes( 914 player, 915 [null, 1500], [ 916 [null, 500], 917 [null, 500], [ 918 [null, 500], 919 [null, 500]]], 920 't = 2020'); 921 }); 922 923 test('pausing works as expected with an empty AnimationSequence inside an AnimationSequence', function() { 924 var player = document.timeline.play(this.seqWithEmptySeq_source); 925 tick(0); 926 checkTimes( 927 player, 928 [0, 0], [0, 0], 929 't = 0'); 930 931 player.pause(); 932 checkTimes( 933 player, 934 [null, 0], [null, 0], 935 't = 0 after pause'); 936 }); 937 938 test('pausing works as expected with an empty AnimationGroup inside an AnimationSequence', function() { 939 var player = document.timeline.play(this.seqWithEmptyGroup_source); 940 tick(0); 941 checkTimes( 942 player, 943 [0, 0], [0, 0], 944 't = 0'); 945 946 player.pause(); 947 checkTimes( 948 player, 949 [null, 0], [null, 0], 950 't = 0 after pause'); 951 }); 952 953 test('playState works for groups', function() { 954 var target = document.createElement('div'); 955 document.body.appendChild(target); 956 var anim = new AnimationSequence([new Animation(target, [], 100), new Animation(target, [], 100)]); 957 var p = document.timeline.play(anim); 958 assert.equal(p.playState, 'pending'); 959 tick(1); 960 assert.equal(p.playState, 'running'); 961 assert.equal(p._childPlayers[0]._player.playState, 'running'); 962 assert.equal(p._childPlayers[1]._player.playState, 'running'); 963 tick(101); 964 assert.equal(p.playState, 'running'); 965 assert.equal(p._childPlayers[0]._player.playState, 'finished'); 966 assert.equal(p._childPlayers[1]._player.playState, 'running'); 967 p.pause(); 968 assert.equal(p.playState, 'pending'); 969 assert.equal(p._childPlayers[0]._player.playState, 'paused'); 970 assert.equal(p._childPlayers[1]._player.playState, 'pending'); 971 tick(102); 972 assert.equal(p.playState, 'paused'); 973 assert.equal(p._childPlayers[0]._player.playState, 'paused'); 974 assert.equal(p._childPlayers[1]._player.playState, 'paused'); 975 p.play(); 976 assert.equal(p.playState, 'pending'); 977 assert.equal(p._childPlayers[0]._player.playState, 'pending'); 978 assert.equal(p._childPlayers[1]._player.playState, 'pending'); 979 tick(103); 980 assert.equal(p.playState, 'running'); 981 assert.equal(p._childPlayers[0]._player.playState, 'finished'); 982 assert.equal(p._childPlayers[1]._player.playState, 'running'); 983 tick(204); 984 assert.equal(p.playState, 'finished'); 985 assert.equal(p._childPlayers[0]._player.playState, 'finished'); 986 assert.equal(p._childPlayers[1]._player.playState, 'finished'); 987 }); 988 989 test('pausing then seeking out of range then seeking into range works', function() { 990 var target = document.createElement('div'); 991 var anim = new Animation(target, [], {duration: 2000, fill: 'both'}); 992 var group = new AnimationGroup([anim], {fill: 'none'}); 993 var player = document.timeline.play(group); 994 995 player.pause(); 996 player.currentTime = 3000; 997 tick(100); 998 player.currentTime = 1000; 999 assert.equal(player._childPlayers.length, 1); 1000 assert.equal(player._childPlayers[0]._player.playState, 'paused'); 1001 assert.equal(player._childPlayers[0]._player.currentTime, 1000); 1002 1003 }); 1004 1005 test('reversing then seeking out of range then seeking into range works', function() { 1006 var target = document.createElement('div'); 1007 var anim = new Animation(target, [], {duration: 2000, fill: 'both'}); 1008 var group = new AnimationGroup([anim], {fill: 'none'}); 1009 var player = document.timeline.play(group); 1010 1011 player.currentTime = 1000; 1012 tick(100); 1013 player.reverse(); 1014 player.currentTime = 3000; 1015 tick(110); 1016 player.currentTime = 1000; 1017 assert.equal(player.playbackRate, -1); 1018 assert.equal(player._childPlayers.length, 1); 1019 assert.equal(player._childPlayers[0]._player.playState, 'running'); 1020 assert.equal(player._childPlayers[0]._player.currentTime, 1000); 1021 assert.equal(player._childPlayers[0]._player.playbackRate, -1); 1022 1023 }); 1024 1025 test('fill none groups with fill none children do not fill', function() { 1026 var anim = new Animation( 1027 this.target, 1028 [{marginLeft: '0px'}, {marginLeft: '100px'}], 1029 {duration: 500, fill: 'none'}); 1030 var group = new AnimationGroup([anim], {fill: 'none'}); 1031 var player = document.timeline.play(group); 1032 1033 tick(0); 1034 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 1035 tick(250); 1036 assert.equal(getComputedStyle(this.target).marginLeft, '50px'); 1037 tick(501); 1038 assert.equal(getComputedStyle(this.target).marginLeft, '0px'); 1039 tick(502); 1040 }); 1041}); 1042