UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

162 lines (154 loc) 4.62 kB
/** * shows controls to play, reset and seek an animation setup * */ import {TypedAnimNode} from './_Base'; import {TimelineBuilder} from '../../../core/animation/TimelineBuilder'; import {BaseNodeType} from '../_Base'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {isBooleanTrue} from '../../../core/BooleanValue'; import {Poly} from '../../Poly'; import {GsapCoreTimeline, gsapLib, gsapTimeline} from '../../../core/thirdParty/gsap/gsapFactory'; import {AnimType} from '../../poly/registers/nodes/types/Anim'; class PlayAnimParamsConfig extends NodeParamsConfig { /** @param play the animations */ play = ParamConfig.BUTTON(null, { callback: (node: BaseNodeType) => { PlayAnimNode.PARAM_CALLBACK_play(node as PlayAnimNode); }, hidden: true, }); /** @param pause the animations */ pause = ParamConfig.BUTTON(null, { callback: (node: BaseNodeType) => { PlayAnimNode.PARAM_CALLBACK_pause(node as PlayAnimNode); }, hidden: true, }); /** @param reset the animations */ reset = ParamConfig.BUTTON(null, { callback: (node: BaseNodeType) => { PlayAnimNode.PARAM_CALLBACK_reset(node as PlayAnimNode); }, hidden: true, }); /** @param sets if the animations created can be stopped when a new animation in generated on the same property */ stoppable = ParamConfig.BOOLEAN(1); /** @param toggle to see debug infos printed in the console */ debug = ParamConfig.BOOLEAN(0); /** @param seek */ seek = ParamConfig.FLOAT(0, { range: [0, 1], rangeLocked: [true, true], cook: false, callback: (node: BaseNodeType) => { PlayAnimNode.PARAM_CALLBACK_seek(node as PlayAnimNode); }, }); } const ParamsConfig = new PlayAnimParamsConfig(); export class PlayAnimNode extends TypedAnimNode<PlayAnimParamsConfig> { override paramsConfig = ParamsConfig; public gsap = gsapLib(); // give access to gsap to external scripts static override type() { return AnimType.PLAY; } override initializeNode() { this.io.inputs.setCount(2); } override cook(inputContents: TimelineBuilder[]) { const timelineBuilder = inputContents[0] || new TimelineBuilder(); this.setTimelineBuilder(timelineBuilder); } // private _timelineBuilder: TimelineBuilder | undefined; private _timeline: GsapCoreTimeline | undefined; async timelineBuilder(inputIndex: number) { const inputNode = this.io.inputs.input(inputIndex); if (!inputNode) { return; } const container = await inputNode.compute(); if (!container) { return; } const timelineBuilder = container.coreContentCloned(); if (!timelineBuilder) { return; } timelineBuilder.setDebug(isBooleanTrue(this.pv.debug)); timelineBuilder.setStoppable(this.pv.stoppable); return timelineBuilder; } private async _playFromInput(inputIndex: number): Promise<void> { return new Promise(async (playResolve) => { let resolved = false; function resolveOnce() { if (!resolved) { resolved = true; playResolve(); } } const timelineBuilder = await this.timelineBuilder(inputIndex); if (!timelineBuilder) { return; } this._timeline = gsapTimeline({onComplete: resolveOnce}); if (!this._timeline) { return; } timelineBuilder.populate(this._timeline, {registerproperties: true}); }); } async play(): Promise<void> { if (isBooleanTrue(this.pv.debug)) { Poly.log(`play from '${this.path()}'`); } return await this._playFromInput(1); } async reset(): Promise<void> { if (isBooleanTrue(this.pv.debug)) { Poly.log(`reset from '${this.path()}'`); } return await this._playFromInput(0); } async pause() { if (this._timeline) { this._timeline.pause(); } } async seek() { const timelineBuilder0 = await this.timelineBuilder(0); const timelineBuilder1 = await this.timelineBuilder(1); if (!(timelineBuilder0 && timelineBuilder1)) { return; } // reset const timeline0 = gsapTimeline({paused: true}); if (!timeline0) { return; } timelineBuilder0.populate(timeline0, {registerproperties: false}); timeline0.seek(timeline0.duration()); timeline0.kill(); // seek const timeline1 = gsapTimeline({paused: true}); if (!timeline1) { return; } timelineBuilder1.populate(timeline1, {registerproperties: false}); timeline1.seek(this.pv.seek * timeline1.duration(), false); timeline1.kill(); } static PARAM_CALLBACK_play(node: PlayAnimNode) { node.play(); } static PARAM_CALLBACK_pause(node: PlayAnimNode) { node.pause(); } static PARAM_CALLBACK_reset(node: PlayAnimNode) { node.reset(); } static PARAM_CALLBACK_seek(node: PlayAnimNode) { node.seek(); } }