mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-24 14:58:36 +08:00
web animation updates
This commit is contained in:
235
scripts/vendor/web-animations-js/src/web-animations-next-animation.js
vendored
Executable file
235
scripts/vendor/web-animations-js/src/web-animations-next-animation.js
vendored
Executable file
@ -0,0 +1,235 @@
|
||||
// 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.Animation = function(effect) {
|
||||
this.effect = effect;
|
||||
if (effect) {
|
||||
// FIXME: detach existing animation.
|
||||
effect.animation = this;
|
||||
}
|
||||
this._isGroup = false;
|
||||
this._animation = null;
|
||||
this._childAnimations = [];
|
||||
this._callback = null;
|
||||
this._rebuildUnderlyingAnimation();
|
||||
// Animations are constructed in the idle state.
|
||||
this._animation.cancel();
|
||||
};
|
||||
|
||||
// TODO: add an effect getter/setter
|
||||
scope.Animation.prototype = {
|
||||
_rebuildUnderlyingAnimation: function() {
|
||||
if (this._animation) {
|
||||
this._animation.cancel();
|
||||
this._animation = null;
|
||||
}
|
||||
|
||||
if (!this.effect || this.effect instanceof window.KeyframeEffect) {
|
||||
this._animation = scope.newUnderlyingAnimationForKeyframeEffect(this.effect);
|
||||
scope.bindAnimationForKeyframeEffect(this);
|
||||
}
|
||||
if (this.effect instanceof window.SequenceEffect || this.effect instanceof window.GroupEffect) {
|
||||
this._animation = scope.newUnderlyingAnimationForGroup(this.effect);
|
||||
scope.bindAnimationForGroup(this);
|
||||
}
|
||||
|
||||
// FIXME: move existing currentTime/startTime/playState to new animation
|
||||
},
|
||||
_updateChildren: function() {
|
||||
if (!this.effect || this.playState == 'idle')
|
||||
return;
|
||||
|
||||
var offset = this.effect._timing.delay;
|
||||
this._childAnimations.forEach(function(childAnimation) {
|
||||
this._arrangeChildren(childAnimation, offset);
|
||||
if (this.effect instanceof window.SequenceEffect)
|
||||
offset += scope.groupChildDuration(childAnimation.effect);
|
||||
}.bind(this));
|
||||
},
|
||||
_setExternalAnimation: function(animation) {
|
||||
if (!this.effect || !this._isGroup)
|
||||
return;
|
||||
for (var i = 0; i < this.effect.children.length; i++) {
|
||||
this.effect.children[i].animation = animation;
|
||||
this._childAnimations[i]._setExternalAnimation(animation);
|
||||
}
|
||||
},
|
||||
_constructChildren: function() {
|
||||
if (!this.effect || !this._isGroup)
|
||||
return;
|
||||
var offset = this.effect._timing.delay;
|
||||
this.effect.children.forEach(function(child) {
|
||||
var childAnimation = window.document.timeline.play(child);
|
||||
this._childAnimations.push(childAnimation);
|
||||
childAnimation.playbackRate = this.playbackRate;
|
||||
if (this.paused)
|
||||
childAnimation.pause();
|
||||
child.animation = this.effect.animation;
|
||||
|
||||
this._arrangeChildren(childAnimation, offset);
|
||||
|
||||
if (this.effect instanceof window.SequenceEffect)
|
||||
offset += scope.groupChildDuration(child);
|
||||
}.bind(this));
|
||||
},
|
||||
_arrangeChildren: function(childAnimation, offset) {
|
||||
if (this.startTime === null) {
|
||||
childAnimation.currentTime = this.currentTime - offset / this.playbackRate;
|
||||
childAnimation._startTime = null;
|
||||
} else if (childAnimation.startTime !== this.startTime + offset / this.playbackRate) {
|
||||
childAnimation.startTime = this.startTime + offset / this.playbackRate;
|
||||
}
|
||||
},
|
||||
get paused() {
|
||||
return this._animation.paused;
|
||||
},
|
||||
get playState() {
|
||||
return this._animation.playState;
|
||||
},
|
||||
get onfinish() {
|
||||
return this._onfinish;
|
||||
},
|
||||
set onfinish(v) {
|
||||
if (typeof v == 'function') {
|
||||
this._onfinish = v;
|
||||
this._animation.onfinish = (function(e) {
|
||||
e.target = this;
|
||||
v.call(this, e);
|
||||
}).bind(this);
|
||||
} else {
|
||||
this._animation.onfinish = v;
|
||||
this.onfinish = this._animation.onfinish;
|
||||
}
|
||||
},
|
||||
get currentTime() {
|
||||
return this._animation.currentTime;
|
||||
},
|
||||
set currentTime(v) {
|
||||
this._animation.currentTime = v;
|
||||
this._register();
|
||||
this._forEachChild(function(child, offset) {
|
||||
child.currentTime = v - offset;
|
||||
});
|
||||
},
|
||||
get startTime() {
|
||||
return this._animation.startTime;
|
||||
},
|
||||
set startTime(v) {
|
||||
this._animation.startTime = v;
|
||||
this._register();
|
||||
this._forEachChild(function(child, offset) {
|
||||
child.startTime = v + offset;
|
||||
});
|
||||
},
|
||||
get playbackRate() {
|
||||
return this._animation.playbackRate;
|
||||
},
|
||||
set playbackRate(value) {
|
||||
var oldCurrentTime = this.currentTime;
|
||||
this._animation.playbackRate = value;
|
||||
this._forEachChild(function(childAnimation) {
|
||||
childAnimation.playbackRate = value;
|
||||
});
|
||||
if (this.playState != 'paused' && this.playState != 'idle') {
|
||||
this.play();
|
||||
}
|
||||
if (oldCurrentTime !== null) {
|
||||
this.currentTime = oldCurrentTime;
|
||||
}
|
||||
},
|
||||
get finished() {
|
||||
return this._animation.finished;
|
||||
},
|
||||
get source() {
|
||||
shared.deprecated('Animation.source', '2015-03-23', 'Use Animation.effect instead.');
|
||||
return this.effect;
|
||||
},
|
||||
play: function() {
|
||||
this._animation.play();
|
||||
this._register();
|
||||
scope.awaitStartTime(this);
|
||||
this._forEachChild(function(child) {
|
||||
var time = child.currentTime;
|
||||
child.play();
|
||||
child.currentTime = time;
|
||||
});
|
||||
},
|
||||
pause: function() {
|
||||
this._animation.pause();
|
||||
this._register();
|
||||
this._forEachChild(function(child) {
|
||||
child.pause();
|
||||
});
|
||||
},
|
||||
finish: function() {
|
||||
this._animation.finish();
|
||||
this._register();
|
||||
// TODO: child animations??
|
||||
},
|
||||
cancel: function() {
|
||||
this._animation.cancel();
|
||||
this._register();
|
||||
this._removeChildren();
|
||||
},
|
||||
reverse: function() {
|
||||
var oldCurrentTime = this.currentTime;
|
||||
this._animation.reverse();
|
||||
this._forEachChild(function(childAnimation) {
|
||||
childAnimation.reverse();
|
||||
});
|
||||
if (oldCurrentTime !== null) {
|
||||
this.currentTime = oldCurrentTime;
|
||||
}
|
||||
},
|
||||
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._animation.addEventListener(type, wrapped);
|
||||
},
|
||||
removeEventListener: function(type, handler) {
|
||||
this._animation.removeEventListener(type, (handler && handler._wrapper) || handler);
|
||||
},
|
||||
_removeChildren: function() {
|
||||
while (this._childAnimations.length)
|
||||
this._childAnimations.pop().cancel();
|
||||
},
|
||||
_forEachChild: function(f) {
|
||||
var offset = 0;
|
||||
if (this.effect.children && this._childAnimations.length < this.effect.children.length)
|
||||
this._constructChildren();
|
||||
this._childAnimations.forEach(function(child) {
|
||||
f.call(this, child, offset);
|
||||
if (this.effect instanceof window.SequenceEffect)
|
||||
offset += child.effect.activeDuration;
|
||||
}.bind(this));
|
||||
|
||||
if (this._animation.playState == 'pending')
|
||||
return;
|
||||
var timing = this.effect._timing;
|
||||
var t = this._animation.currentTime;
|
||||
if (t !== null)
|
||||
t = shared.calculateTimeFraction(shared.calculateActiveDuration(timing), t, timing);
|
||||
if (t == null || isNaN(t))
|
||||
this._removeChildren();
|
||||
},
|
||||
};
|
||||
|
||||
})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);
|
Reference in New Issue
Block a user