blob: c170db7e4c8cc94e78d0e55b556285129d81957f [file] [log] [blame]
// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function(shared, scope, testing) {
scope.Player = function(source) {
this.source = source;
if (source) {
// FIXME: detach existing player.
source.player = this;
}
this._isGroup = false;
this._player = null;
this._childPlayers = [];
this._callback = null;
this._rebuildUnderlyingPlayer();
// Players are constructed in the idle state.
this._player.cancel();
};
// TODO: add a source getter/setter
scope.Player.prototype = {
_rebuildUnderlyingPlayer: function() {
if (this._player) {
this._player.cancel();
this._player = null;
}
if (!this.source || this.source instanceof window.Animation) {
this._player = scope.newUnderlyingPlayerForAnimation(this.source);
scope.bindPlayerForAnimation(this);
}
if (this.source instanceof window.AnimationSequence || this.source instanceof window.AnimationGroup) {
this._player = scope.newUnderlyingPlayerForGroup(this.source);
scope.bindPlayerForGroup(this);
}
// FIXME: move existing currentTime/startTime/playState to new player
},
get paused() {
return this._player.paused;
},
get playState() {
return this._player.playState;
},
get onfinish() {
return this._onfinish;
},
set onfinish(v) {
if (typeof v == 'function') {
this._onfinish = v;
this._player.onfinish = (function(e) {
e.target = this;
v.call(this, e);
}).bind(this);
} else {
this._player.onfinish = v;
this.onfinish = this._player.onfinish;
}
},
get currentTime() {
return this._player.currentTime;
},
set currentTime(v) {
this._player.currentTime = v;
this._register();
this._forEachChild(function(child, offset) {
child.currentTime = v - offset;
});
},
get startTime() {
return this._player.startTime;
},
set startTime(v) {
this._player.startTime = v;
this._register();
this._forEachChild(function(child, offset) {
child.startTime = v + offset;
});
},
get playbackRate() {
return this._player.playbackRate;
},
set playbackRate(value) {
this._player.playbackRate = value;
this._forEachChild(function(childPlayer) {
childPlayer.playbackRate = value;
});
},
get finished() {
return this._player.finished;
},
play: function() {
this._player.play();
this._register();
scope.awaitStartTime(this);
this._forEachChild(function(child) {
var time = child.currentTime;
child.play();
child.currentTime = time;
});
},
pause: function() {
this._player.pause();
this._register();
this._forEachChild(function(child) {
child.pause();
});
},
finish: function() {
this._player.finish();
this._register();
// TODO: child players??
},
cancel: function() {
this._player.cancel();
this._register();
this._removePlayers();
},
reverse: function() {
this._player.reverse();
scope.awaitStartTime(this);
this._register();
this._forEachChild(function(child, offset) {
child.reverse();
child.startTime = this.startTime + offset * this.playbackRate;
child.currentTime = this.currentTime + offset * this.playbackRate;
});
},
addEventListener: function(type, handler) {
var wrapped = handler;
if (typeof handler == 'function') {
wrapped = (function(e) {
e.target = this;
handler.call(this, e);
}).bind(this);
handler._wrapper = wrapped;
}
this._player.addEventListener(type, wrapped);
},
removeEventListener: function(type, handler) {
this._player.removeEventListener(type, (handler && handler._wrapper) || handler);
},
_removePlayers: function() {
while (this._childPlayers.length)
this._childPlayers.pop().cancel();
},
_forEachChild: function(f) {
var offset = 0;
this._childPlayers.forEach(function(child) {
f.call(this, child, offset);
if (this.source instanceof window.AnimationSequence)
offset += child.source.activeDuration;
}.bind(this));
},
};
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);