补间动画已实现。

This commit is contained in:
liteng 2018-09-24 21:45:07 +08:00
parent a1ade5aa61
commit 4e560cfdaa
5 changed files with 94 additions and 17 deletions

View File

@ -16,7 +16,7 @@ function Animation(options) {
this.name = options.name || `动画${ID--}`; // 动画名称
this.target = options.target || null; // 动画对象uuid
this.type = options.type || AnimationType.Tween; // 动画类型
this.startTime = options.startTime || 0; // 开始时间(秒)
this.beginTime = options.beginTime || 0; // 开始时间(秒)
this.endTime = options.endTime || 10; // 结束时间(秒)
// 补间动画

View File

@ -95,7 +95,7 @@ BasicAnimationComponent.prototype.render = function () {
text: '开始时间'
}, {
xtype: 'number',
id: 'startTime',
id: 'beginTime',
scope: this.id,
range: [0, Infinity],
onChange: this.onChange.bind(this)
@ -144,7 +144,7 @@ BasicAnimationComponent.prototype.updateUI = function (animation) {
var name = UI.get('name', this.id);
var target = UI.get('target', this.id);
var type = UI.get('type', this.id);
var startTime = UI.get('startTime', this.id);
var beginTime = UI.get('beginTime', this.id);
var endTime = UI.get('endTime', this.id);
name.setValue(this.animation.name);
@ -162,7 +162,7 @@ BasicAnimationComponent.prototype.updateUI = function (animation) {
}
type.setValue(this.animation.type);
startTime.setValue(this.animation.startTime);
beginTime.setValue(this.animation.beginTime);
endTime.setValue(this.animation.endTime);
};
@ -180,12 +180,12 @@ BasicAnimationComponent.prototype.onSetTarget = function () {
BasicAnimationComponent.prototype.onChange = function () {
var name = UI.get('name', this.id);
var type = UI.get('type', this.id);
var startTime = UI.get('startTime', this.id);
var beginTime = UI.get('beginTime', this.id);
var endTime = UI.get('endTime', this.id);
this.animation.name = name.getValue();
this.animation.type = type.getValue();
this.animation.startTime = startTime.getValue();
this.animation.beginTime = beginTime.getValue();
this.animation.endTime = endTime.getValue();
this.app.call('animationChanged', this, this.animation);

View File

@ -208,8 +208,8 @@ AnimationPanel.prototype.updateUI = function () {
item.className = 'item';
item.setAttribute('draggable', true);
item.setAttribute('droppable', false);
item.style.left = m.startTime * timeline.scale + 'px';
item.style.width = (m.endTime - m.startTime) * timeline.scale + 'px';
item.style.left = m.beginTime * timeline.scale + 'px';
item.style.width = (m.endTime - m.beginTime) * timeline.scale + 'px';
item.innerHTML = m.name;
item.addEventListener('dragstart', this.onDragStartAnimation.bind(this));
item.addEventListener('dragend', this.onDragEndAnimation.bind(this));
@ -357,7 +357,7 @@ AnimationPanel.prototype.onDblClick = function (event) {
event.stopPropagation();
var animation = new Animation({
startTime: event.offsetX / timeline.scale,
beginTime: event.offsetX / timeline.scale,
endTime: (event.offsetX + 80) / timeline.scale
});
@ -416,9 +416,9 @@ AnimationPanel.prototype.onDropGroup = function (event) {
group.remove(animation);
var timeline = UI.get('timeline', this.id);
var length = animation.endTime - animation.startTime;
animation.startTime = (event.offsetX - offsetX) / timeline.scale;
animation.endTime = animation.startTime + length;
var length = animation.endTime - animation.beginTime;
animation.beginTime = (event.offsetX - offsetX) / timeline.scale;
animation.endTime = animation.beginTime + length;
if (event.target.data instanceof Animation) { // 拖动到其他动画上
event.target.parentElement.data.add(animation);

View File

@ -232,7 +232,7 @@ SceneWindow.prototype.loadScene = function (data) {
name: m.name,
target: m.target,
type: m.type,
startTime: m.startTime,
beginTime: m.beginTime,
endTime: m.endTime,
// 补间动画

View File

@ -1,5 +1,6 @@
import UI from '../ui/UI';
import Converter from '../serialization/Converter';
import Ease from '../animation/Ease';
/**
* 播放器
@ -15,7 +16,8 @@ function Player(options) {
this.renderer = null;
this.scripts = null;
this.animation = null;
this.animationTime = 0;
this.maxAnimationTime = 0;
this.currentAnimationTime = 0;
this.audioListener = null;
@ -170,11 +172,11 @@ Player.prototype.initPlayer = function (obj) {
// 动画
this.animation = obj.animation;
this.animationTime = 0;
this.maxAnimationTime = 0;
this.animation.forEach(n => {
n.animations.forEach(m => {
if (m.endTime > this.animationTime) {
this.animationTime = m.endTime;
if (m.endTime > this.maxAnimationTime) {
this.maxAnimationTime = m.endTime;
}
});
});
@ -309,6 +311,9 @@ Player.prototype.initScene = function () {
// 动画
this.app.call(`resetAnimation`, this.id);
this.app.call(`startAnimation`, this.id);
this.app.on(`animationTime.${this.id}`, (time) => {
this.currentAnimationTime = time;
});
};
Player.prototype.destroyScene = function () {
@ -317,6 +322,11 @@ Player.prototype.destroyScene = function () {
n.stop();
}
});
this.app.on(`animationTime.${this.id}`, null);
this.app.call(`resetAnimation`, this.id);
this.currentAnimationTime = 0;
this.maxAnimationTime = 0;
};
/**
@ -325,6 +335,7 @@ Player.prototype.destroyScene = function () {
Player.prototype.animate = function () {
this.renderScene();
// 脚本事件
var deltaTime = this.clock.getDelta();
this.events.forEach(n => {
@ -333,9 +344,75 @@ Player.prototype.animate = function () {
}
});
// 动画
this.animation.forEach(n => {
n.animations.forEach(m => {
this.tweenObject(m); // 补间动画
});
});
// 超过最大动画时间,重置动画
if (this.currentAnimationTime > this.maxAnimationTime) {
this.app.call(`resetAnimation`, this.id);
this.app.call(`startAnimation`, this.id);
}
if (this.isPlaying) {
requestAnimationFrame(this.animate.bind(this));
}
};
/**
* 补间动画处理
* @param {*} animation
*/
Player.prototype.tweenObject = function (animation) {
var time = this.currentAnimationTime;
// 条件判断
if (animation.type !== 'Tween' || time < animation.beginTime || time > animation.endTime || animation.target == null) {
return;
}
// 获取对象
var target = this.scene.getObjectByProperty('uuid', animation.target);
if (target == null) {
console.warn(`Player: 场景中不存在uuid为${animation.target}的物体。`);
return;
}
// 获取插值函数
var ease = Ease[animation.ease];
if (ease == null) {
console.warn(`Player: 不存在名称为${animation.ease}的插值函数。`);
return;
}
var result = ease((time - animation.beginTime) / (animation.endTime - animation.beginTime));
var positionX = animation.beginPositionX + (animation.endPositionX - animation.beginPositionX) * result;
var positionY = animation.beginPositionY + (animation.endPositionY - animation.beginPositionY) * result;
var positionZ = animation.beginPositionZ + (animation.endPositionZ - animation.beginPositionZ) * result;
var rotationX = animation.beginRotationX + (animation.endRotationX - animation.beginRotationX) * result;
var rotationY = animation.beginRotationY + (animation.endRotationY - animation.beginRotationY) * result;
var rotationZ = animation.beginRotationZ + (animation.endRotationZ - animation.beginRotationZ) * result;
var scaleX = animation.beginScaleX + (animation.endScaleX - animation.beginScaleX) * result;
var scaleY = animation.beginScaleY + (animation.endScaleY - animation.beginScaleY) * result;
var scaleZ = animation.beginScaleZ + (animation.endScaleZ - animation.beginScaleZ) * result;
target.position.x = positionX;
target.position.y = positionY;
target.position.z = positionZ;
target.rotation.x = rotationX;
target.rotation.y = rotationY;
target.rotation.z = rotationZ;
target.scale.x = scaleX;
target.scale.y = scaleY;
target.scale.z = scaleZ;
};
export default Player;