@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
217 lines (216 loc) • 8.03 kB
JavaScript
"use strict";
import { EventConnectionPoint, EventConnectionPointType } from "../utils/io/connections/Event";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { TypedEventNode } from "./_Base";
import { isBooleanTrue } from "../../../core/Type";
import ScrollTrigger from "gsap/ScrollTrigger";
import { gsap } from "../../../core/thirdParty/gsap/gsap";
import { ModuleName } from "../../poly/registers/modules/Common";
import { gsapLib } from "../../../core/thirdParty/gsap/gsapFactory";
gsap.registerPlugin(ScrollTrigger);
var ScrollTriggerNodeInput = /* @__PURE__ */ ((ScrollTriggerNodeInput2) => {
ScrollTriggerNodeInput2["CREATE"] = "create";
ScrollTriggerNodeInput2["DISPOSE"] = "dispose";
return ScrollTriggerNodeInput2;
})(ScrollTriggerNodeInput || {});
var ScrollTriggerNodeOutput = /* @__PURE__ */ ((ScrollTriggerNodeOutput2) => {
ScrollTriggerNodeOutput2["TOGGLE"] = "toggle";
ScrollTriggerNodeOutput2["ENTER"] = "enter";
ScrollTriggerNodeOutput2["LEAVE"] = "leave";
ScrollTriggerNodeOutput2["ENTER_BACK"] = "enterBack";
ScrollTriggerNodeOutput2["LEAVE_BACK"] = "leaveBack";
return ScrollTriggerNodeOutput2;
})(ScrollTriggerNodeOutput || {});
const defaultParamOptions = (options) => {
let visibleIf = options == null ? void 0 : options.visibleIf;
if (visibleIf) {
visibleIf.active = 1;
} else {
visibleIf = { active: 1 };
}
return {
visibleIf,
callback: (node) => {
ScrollTriggerEventNode.PARAM_CALLBACK_updateScrollTrigger(node);
}
};
};
const UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS = defaultParamOptions();
class ScrollTriggerParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param active */
this.active = ParamConfig.BOOLEAN(true, {
callback: (node) => {
ScrollTriggerEventNode.PARAM_CALLBACK_updateScrollTrigger(node);
}
});
/** @param selector of the element the scroll events are detected for */
this.element = ParamConfig.STRING("", UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param use viewport as scroller */
this.useViewport = ParamConfig.BOOLEAN(1, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param override the scroller */
this.scroller = ParamConfig.STRING("", defaultParamOptions({ visibleIf: { useViewport: 0 } }));
/** @param add markers for debugging */
this.markers = ParamConfig.BOOLEAN("!playerMode()", {
...UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS,
separatorAfter: true
});
/** @param define if progress should be updated */
this.tprogress = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param progress */
this.progress = ParamConfig.FLOAT(0, {
editable: false,
visibleIf: { tprogress: 1 }
});
/** @param define if the scroll is inside the element */
this.tinsideElement = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param 1 if the scroll is inside the element */
this.insideElement = ParamConfig.BOOLEAN(0, {
editable: false,
visibleIf: { tinsideElement: 1 }
});
/** @param sends a trigger when we leaving or entering the element */
this.onToggle = ParamConfig.BOOLEAN(1, {
...UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS,
separatorBefore: true
});
/** @param sends a trigger when entering the element */
this.onEnter = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param sends a trigger when leaving the element */
this.onLeave = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param sends a trigger when entering again the element */
this.onEnterBack = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
/** @param sends a trigger when leaving again the element */
this.onLeaveBack = ParamConfig.BOOLEAN(0, UPDATE_SCROLL_TRIGGER_PARAM_OPTIONS);
}
}
const ParamsConfig = new ScrollTriggerParamsConfig();
export class ScrollTriggerEventNode extends TypedEventNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this.gsap = gsapLib();
// give access to gsap to external scripts
this.ScrollTrigger = ScrollTrigger;
}
// give access to ScrollTrigger to external scripts
static type() {
return "scrollTrigger";
}
requiredModules() {
return [ModuleName.GSAP];
}
dispose() {
this._disposeScrollTrigger();
super.dispose();
}
initializeNode() {
this.io.inputs.setNamedInputConnectionPoints([
new EventConnectionPoint(
"create" /* CREATE */,
EventConnectionPointType.BASE,
this._onCreateTrigger.bind(this)
),
new EventConnectionPoint(
"dispose" /* DISPOSE */,
EventConnectionPointType.BASE,
this._onDisposeTrigger.bind(this)
)
]);
this.io.outputs.setNamedOutputConnectionPoints([
new EventConnectionPoint("toggle" /* TOGGLE */, EventConnectionPointType.BASE),
new EventConnectionPoint("enter" /* ENTER */, EventConnectionPointType.BASE),
new EventConnectionPoint("leave" /* LEAVE */, EventConnectionPointType.BASE),
new EventConnectionPoint("enterBack" /* ENTER_BACK */, EventConnectionPointType.BASE),
new EventConnectionPoint("leaveBack" /* LEAVE_BACK */, EventConnectionPointType.BASE)
]);
}
_onCreateTrigger(eventContext) {
this._disposeScrollTrigger();
if (!isBooleanTrue(this.pv.active)) {
return;
}
this.states.error.clear();
const element = this._querySelector(this.pv.element);
if (!element) {
return;
}
const _getScroller = () => {
if (isBooleanTrue(this.pv.useViewport)) {
return;
}
const scrollerElement = this._querySelector(this.pv.scroller);
if (!scrollerElement) {
return;
}
return scrollerElement;
};
const options = {
trigger: element,
scroller: _getScroller(),
markers: this.pv.markers,
id: this.path()
};
if (isBooleanTrue(this.pv.tinsideElement) || isBooleanTrue(this.pv.onToggle)) {
const updateInside = (scrollTrigger) => this.p.insideElement.set(scrollTrigger.isActive);
const dispatchOnToggle = (scrollTrigger) => this.dispatchEventToOutput("toggle" /* TOGGLE */, {});
const functions = [];
if (isBooleanTrue(this.pv.tinsideElement)) {
functions.push(updateInside);
}
if (isBooleanTrue(this.pv.onToggle)) {
functions.push(dispatchOnToggle);
}
options.onToggle = (scrollTrigger) => {
for (const func of functions) {
func(scrollTrigger);
}
};
}
if (isBooleanTrue(this.pv.onEnter)) {
options.onEnter = () => this.dispatchEventToOutput("enter" /* ENTER */, {});
}
if (isBooleanTrue(this.pv.onLeave)) {
options.onLeave = () => this.dispatchEventToOutput("leave" /* LEAVE */, {});
}
if (isBooleanTrue(this.pv.onEnterBack)) {
options.onEnterBack = () => this.dispatchEventToOutput("enterBack" /* ENTER_BACK */, {});
}
if (isBooleanTrue(this.pv.onLeaveBack)) {
options.onLeaveBack = () => this.dispatchEventToOutput("leaveBack" /* LEAVE_BACK */, {});
}
if (isBooleanTrue(this.pv.tprogress)) {
options.onUpdate = (scrollTrigger) => {
this.p.progress.set(scrollTrigger.progress);
};
}
this._scrollTrigger = ScrollTrigger.create(options);
}
_updateScrollTrigger() {
if (!this._scrollTrigger) {
return;
}
this._onCreateTrigger({});
}
_onDisposeTrigger(eventContext) {
this._disposeScrollTrigger();
}
_disposeScrollTrigger() {
if (!this._scrollTrigger) {
return;
}
this._scrollTrigger.kill();
}
_querySelector(selector) {
const element = document.querySelector(selector);
if (!element) {
this.states.error.set(`element with selector '${selector}' not found`);
return;
}
return element;
}
static PARAM_CALLBACK_updateScrollTrigger(node) {
node._updateScrollTrigger();
}
}