UNPKG

@polygonjs/polygonjs

Version:

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

154 lines (153 loc) 4.53 kB
"use strict"; import { TypedAnimNode } from "./_Base"; import { TimelineBuilder } from "../../../core/animation/TimelineBuilder"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { isBooleanTrue } from "../../../core/BooleanValue"; import { Poly } from "../../Poly"; import { gsapLib, gsapTimeline } from "../../../core/thirdParty/gsap/gsapFactory"; import { AnimType } from "../../poly/registers/nodes/types/Anim"; class PlayAnimParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param play the animations */ this.play = ParamConfig.BUTTON(null, { callback: (node) => { PlayAnimNode.PARAM_CALLBACK_play(node); }, hidden: true }); /** @param pause the animations */ this.pause = ParamConfig.BUTTON(null, { callback: (node) => { PlayAnimNode.PARAM_CALLBACK_pause(node); }, hidden: true }); /** @param reset the animations */ this.reset = ParamConfig.BUTTON(null, { callback: (node) => { PlayAnimNode.PARAM_CALLBACK_reset(node); }, hidden: true }); /** @param sets if the animations created can be stopped when a new animation in generated on the same property */ this.stoppable = ParamConfig.BOOLEAN(1); /** @param toggle to see debug infos printed in the console */ this.debug = ParamConfig.BOOLEAN(0); /** @param seek */ this.seek = ParamConfig.FLOAT(0, { range: [0, 1], rangeLocked: [true, true], cook: false, callback: (node) => { PlayAnimNode.PARAM_CALLBACK_seek(node); } }); } } const ParamsConfig = new PlayAnimParamsConfig(); export class PlayAnimNode extends TypedAnimNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; this.gsap = gsapLib(); } // give access to gsap to external scripts static type() { return AnimType.PLAY; } initializeNode() { this.io.inputs.setCount(2); } cook(inputContents) { const timelineBuilder = inputContents[0] || new TimelineBuilder(); this.setTimelineBuilder(timelineBuilder); } async timelineBuilder(inputIndex) { 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; } async _playFromInput(inputIndex) { 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() { if (isBooleanTrue(this.pv.debug)) { Poly.log(`play from '${this.path()}'`); } return await this._playFromInput(1); } async reset() { 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; } const timeline0 = gsapTimeline({ paused: true }); if (!timeline0) { return; } timelineBuilder0.populate(timeline0, { registerproperties: false }); timeline0.seek(timeline0.duration()); timeline0.kill(); 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) { node.play(); } static PARAM_CALLBACK_pause(node) { node.pause(); } static PARAM_CALLBACK_reset(node) { node.reset(); } static PARAM_CALLBACK_seek(node) { node.seek(); } }