polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
198 lines (187 loc) • 5.48 kB
text/typescript
import {TimelineBuilderProperty, AnimPropertyTargetValue} from './TimelineBuilderProperty';
import {PolyScene} from '../../engine/scene/PolyScene';
import {PropertyTarget} from './PropertyTarget';
import {AnimationPosition} from './Position';
import {AnimationUpdateCallback} from './UpdateCallback';
import gsap from 'gsap';
export enum Operation {
SET = 'set',
ADD = 'add',
SUBSTRACT = 'substract',
}
export const OPERATIONS: Operation[] = [Operation.SET, Operation.ADD, Operation.SUBSTRACT];
export interface AnimationRepeatParams {
count: number;
delay: number;
yoyo: boolean;
}
export class TimelineBuilder {
private _timeline_builders: TimelineBuilder[] = [];
private _parent: TimelineBuilder | undefined;
private _target: PropertyTarget | undefined;
private _duration: number = 1;
private _easing: string | undefined;
private _operation: Operation = Operation.SET;
private _repeat_params: AnimationRepeatParams | undefined;
private _delay: number = 0;
private _position: AnimationPosition | undefined;
private _property: TimelineBuilderProperty | undefined;
private _update_callback: AnimationUpdateCallback | undefined;
add_timeline_builder(timeline_builder: TimelineBuilder) {
this._timeline_builders.push(timeline_builder);
timeline_builder.setParent(this);
}
timeline_builders() {
return this._timeline_builders;
}
setParent(parent: TimelineBuilder) {
this._parent = parent;
}
parent() {
return this._parent;
}
set_target(target: PropertyTarget) {
this._target = target;
for (let builder of this._timeline_builders) {
builder.set_target(target);
}
}
target() {
return this._target;
}
set_duration(duration: number) {
if (duration >= 0) {
this._duration = duration;
for (let builder of this._timeline_builders) {
builder.set_duration(duration);
}
}
}
duration() {
return this._duration;
}
set_easing(easing: string) {
this._easing = easing;
for (let builder of this._timeline_builders) {
builder.set_easing(easing);
}
}
easing() {
return this._easing;
}
set_operation(operation: Operation) {
this._operation = operation;
for (let builder of this._timeline_builders) {
builder.set_operation(operation);
}
}
operation() {
return this._operation;
}
set_repeat_params(repeat_params: AnimationRepeatParams) {
this._repeat_params = repeat_params;
for (let builder of this._timeline_builders) {
builder.set_repeat_params(repeat_params);
}
}
repeat_params() {
return this._repeat_params;
}
set_delay(delay: number) {
this._delay = delay;
for (let builder of this._timeline_builders) {
builder.set_delay(delay);
}
}
delay() {
return this._delay;
}
setPosition(position: AnimationPosition | undefined) {
this._position = position;
// That should not be recursive here,
// otherwise the merge node will override timelines whose position may already been set
// for (let builder of this._timeline_builders) {
// builder.setPosition(position);
// }
}
position() {
return this._position;
}
set_update_callback(update_callback: AnimationUpdateCallback) {
this._update_callback = update_callback;
}
update_callback() {
return this._update_callback;
}
// merge(timeline_builder?: TimelineBuilder) {
// if (!timeline_builder) {
// return;
// }
// }
clone() {
const new_timeline_builder = new TimelineBuilder();
new_timeline_builder.set_duration(this._duration);
new_timeline_builder.set_operation(this._operation);
new_timeline_builder.set_delay(this._delay);
if (this._target) {
new_timeline_builder.set_target(this._target.clone());
}
if (this._easing) {
new_timeline_builder.set_easing(this._easing);
}
if (this._delay) {
new_timeline_builder.set_delay(this._delay);
}
if (this._update_callback) {
new_timeline_builder.set_update_callback(this._update_callback.clone());
}
if (this._repeat_params) {
new_timeline_builder.set_repeat_params({
count: this._repeat_params.count,
delay: this._repeat_params.delay,
yoyo: this._repeat_params.yoyo,
});
}
if (this._property) {
const name = this._property.name();
if (name) {
new_timeline_builder.setPropertyName(name);
}
const target_value = this._property.target_value();
if (target_value != null) {
new_timeline_builder.setPropertyValue(target_value);
}
}
if (this._position) {
new_timeline_builder.setPosition(this._position.clone());
}
for (let child_timeline_builder of this._timeline_builders) {
const new_child_timeline_builder = child_timeline_builder.clone();
new_timeline_builder.add_timeline_builder(new_child_timeline_builder);
}
return new_timeline_builder;
}
setPropertyName(name: string) {
this.property().setName(name);
}
property() {
return (this._property = this._property || new TimelineBuilderProperty());
}
propertyName() {
return this.property().name();
}
setPropertyValue(value: AnimPropertyTargetValue) {
this.property().set_target_value(value);
}
populate(timeline: gsap.core.Timeline, scene: PolyScene) {
for (let timeline_builder of this._timeline_builders) {
const sub_timeline = gsap.timeline();
timeline_builder.populate(sub_timeline, scene);
const position_param = timeline_builder.position()?.to_parameter() || undefined;
timeline.add(sub_timeline, position_param);
}
if (this._property && this._target) {
this._property.add_to_timeline(this, scene, timeline, this._target);
}
}
}