polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
125 lines (112 loc) • 3.66 kB
text/typescript
/**
* Starts and pauses animations
*
*
*/
import {TypedEventNode} from './_Base';
import {EventContext} from '../../scene/utils/events/_BaseEventsController';
import {EventConnectionPoint, EventConnectionPointType} from '../utils/io/connections/Event';
import {BaseNodeType} from '../_Base';
import {NodeContext} from '../../poly/NodeContext';
import {TimelineBuilder} from '../../../core/animation/TimelineBuilder';
import gsap from 'gsap';
enum AnimationEventInput {
START = 'start',
STOP = 'stop',
UPDATE = 'update',
}
export enum AnimationEventOutput {
START = 'start',
COMPLETE = 'completed',
}
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
class AnimationEventParamsConfig extends NodeParamsConfig {
/** @parm animation node */
animation = ParamConfig.NODE_PATH('/ANIM/OUT', {
nodeSelection: {context: NodeContext.ANIM},
dependentOnFoundNode: false,
});
/** @parm presses to play the animation */
play = ParamConfig.BUTTON(null, {
callback: (node: BaseNodeType) => {
AnimationEventNode.PARAM_CALLBACK_play(node as AnimationEventNode);
},
});
/** @parm presses to pause the animation */
pause = ParamConfig.BUTTON(null, {
callback: (node: BaseNodeType) => {
AnimationEventNode.PARAM_CALLBACK_pause(node as AnimationEventNode);
},
});
}
const ParamsConfig = new AnimationEventParamsConfig();
export class AnimationEventNode extends TypedEventNode<AnimationEventParamsConfig> {
params_config = ParamsConfig;
static type() {
return 'animation';
}
private _timeline_builder: TimelineBuilder | undefined;
private _timeline: gsap.core.Timeline | undefined;
initializeNode() {
this.io.inputs.setNamedInputConnectionPoints([
new EventConnectionPoint(AnimationEventInput.START, EventConnectionPointType.BASE, this._play.bind(this)),
new EventConnectionPoint(AnimationEventInput.STOP, EventConnectionPointType.BASE, this._pause.bind(this)),
]);
this.io.outputs.setNamedOutputConnectionPoints([
new EventConnectionPoint(AnimationEventOutput.START, EventConnectionPointType.BASE),
new EventConnectionPoint(AnimationEventOutput.COMPLETE, EventConnectionPointType.BASE),
]);
}
process_event(event_context: EventContext<Event>) {
// this.dispatch_event_to_output(OUTPUT_NAME, event_context);
}
static PARAM_CALLBACK_play(node: AnimationEventNode) {
node._play({});
}
static PARAM_CALLBACK_pause(node: AnimationEventNode) {
node._pause();
}
private async _play(event_context: EventContext<Event>) {
const param = this.p.animation;
if (param.isDirty()) {
await param.compute();
}
const node = param.value.ensure_node_context(NodeContext.ANIM);
if (!node) {
return;
}
const container = await node.requestContainer();
if (!container) {
return;
}
this._timeline_builder = container.coreContent();
if (!this._timeline_builder) {
return;
}
if (this._timeline) {
this._timeline.kill();
}
this._timeline = gsap.timeline();
this._timeline_builder.populate(this._timeline, this.scene());
this._timeline.vars.onStart = () => {
this.trigger_animation_started(event_context);
};
this._timeline.vars.onComplete = () => {
if (this._timeline) {
this._timeline.kill();
}
this.trigger_animation_completed(event_context);
};
}
private _pause() {
if (this._timeline) {
this._timeline.pause();
}
}
trigger_animation_started(event_context: EventContext<Event>) {
this.dispatch_event_to_output(AnimationEventOutput.START, event_context);
}
trigger_animation_completed(event_context: EventContext<Event>) {
this.dispatch_event_to_output(AnimationEventOutput.COMPLETE, event_context);
}
}