UNPKG

angular-three-theatre

Version:
697 lines (675 loc) 31.3 kB
import * as i0 from '@angular/core'; import { input, computed, effect, Component, ChangeDetectionStrategy, inject, DestroyRef, model, untracked, Directive, InjectionToken, booleanAttribute, TemplateRef, ViewContainerRef, linkedSignal, signal, viewChild, afterNextRender, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { getProject, val, onChange, types } from '@theatre/core'; import { omit, pick, injectStore, resolveRef, resolveInstanceKey, extend } from 'angular-three'; import { mergeInputs } from 'ngxtension/inject-inputs'; import * as THREE from 'three'; import { Group } from 'three'; import { NgtsTransformControls } from 'angular-three-soba/gizmos'; import Studio from '@theatre/studio'; class TheatreProject { constructor() { this.name = input('default-theatre-project'); this.config = input({}); this.project = computed(() => getProject(this.name(), this.config())); this.sheets = {}; effect(() => { const project = this.project(); project.ready.then(); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreProject, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.1", type: TheatreProject, isStandalone: true, selector: "theatre-project", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: ` <ng-content /> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreProject, decorators: [{ type: Component, args: [{ selector: 'theatre-project', template: ` <ng-content /> `, changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: () => [] }); class TheatreSheet { constructor() { this.name = input('default-theatre-sheet'); this.project = inject(TheatreProject); this.sheet = computed(() => { const name = this.name(); const existing = this.project.sheets[name] || []; if (existing[0]) { existing[1]++; return existing[0]; } const sheet = this.project.project().sheet(name); this.project.sheets[name] = [sheet, 1]; return sheet; }); inject(DestroyRef).onDestroy(() => { const existing = this.project.sheets[this.name()]; if (!existing) return; if (existing[1] >= 1) { existing[1]--; } if (existing[1] === 0) { delete this.project.sheets[this.name()]; } }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheet, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.1", type: TheatreSheet, isStandalone: true, selector: "theatre-sheet", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: ` <ng-content /> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheet, decorators: [{ type: Component, args: [{ selector: 'theatre-sheet', template: ` <ng-content /> `, changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: () => [] }); const defaultOptions = { rate: 1, autoplay: false, autopause: false, delay: 0, }; class TheatreSequence { constructor() { this.options = input(defaultOptions, { alias: 'sequence', transform: mergeInputs(defaultOptions) }); this.audioOptions = input(undefined, { alias: 'sequenceAudio' }); this.position = model(0); this.playing = model(false); this.length = model(0); this.playOptions = omit(this.options, ['autoplay', 'autopause', 'delay', 'autoreset']); this.autoplay = pick(this.options, 'autoplay'); this.autopause = pick(this.options, 'autopause'); this.autoreset = pick(this.options, 'autoreset'); this.delay = pick(this.options, 'delay'); this.project = inject(TheatreProject); this.sheet = inject(TheatreSheet, { host: true }); this.sequence = computed(() => this.sheet.sheet().sequence); effect((onCleanup) => { const autoplay = untracked(this.autoplay); if (!autoplay) return; const delay = untracked(this.delay); const id = setTimeout(() => { untracked(() => this.play()); }, delay); onCleanup(() => { clearTimeout(id); }); }); effect((onCleanup) => { const autopause = untracked(this.autopause); onCleanup(() => { if (autopause) { this.pause(); } }); }); effect((onCleanup) => { const autoreset = untracked(this.autoreset); if (autoreset === 'init' || autoreset === 'always') { untracked(() => this.reset()); } onCleanup(() => { if (autoreset === 'destroy' || autoreset === 'always') { untracked(() => this.reset()); } }); }); effect(() => { const [audioOptions, sequence] = [this.audioOptions(), untracked(this.sequence)]; if (audioOptions) sequence.attachAudio(audioOptions); }); effect(() => { const [playOptions, sequence] = [this.playOptions(), untracked(this.sequence)]; const isPlaying = val(sequence.pointer.playing); if (isPlaying) { this.pause(); this.play(playOptions); } }); effect((onCleanup) => { const sequence = this.sequence(); const cleanups = []; cleanups.push(onChange(sequence.pointer.position, (value) => this.position.set(value)), onChange(sequence.pointer.playing, (value) => this.playing.set(value)), onChange(sequence.pointer.length, (value) => this.length.set(value))); onCleanup(() => { cleanups.forEach((cleanup) => cleanup()); }); }); } pause() { const sequence = this.sequence(); sequence.pause(); } play(options = {}) { const sequence = this.sequence(); const project = this.project.project(); project.ready.then(() => { sequence.play({ ...this.playOptions(), ...options }); }); } reset() { const sequence = this.sequence(); const isPlaying = val(sequence.pointer.playing); sequence.position = 0; if (isPlaying) this.play(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSequence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.1", type: TheatreSequence, isStandalone: true, selector: "theatre-sheet[sequence]", inputs: { options: { classPropertyName: "options", publicName: "sequence", isSignal: true, isRequired: false, transformFunction: null }, audioOptions: { classPropertyName: "audioOptions", publicName: "sequenceAudio", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, playing: { classPropertyName: "playing", publicName: "playing", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { position: "positionChange", playing: "playingChange", length: "lengthChange" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSequence, decorators: [{ type: Directive, args: [{ selector: 'theatre-sheet[sequence]' }] }], ctorParameters: () => [] }); const THEATRE_STUDIO = new InjectionToken('Theatre Studio'); let TheatreSheetObject$1 = class TheatreSheetObject { constructor() { this.key = input.required({ alias: 'sheetObject' }); this.props = input({}); this.detach = input(false, { transform: booleanAttribute }); this.selected = model(false); this.templateRef = inject(TemplateRef); this.vcr = inject(ViewContainerRef); this.sheet = inject(TheatreSheet); this.studio = inject(THEATRE_STUDIO, { optional: true }); this.store = injectStore(); this.originalSheetObject = computed(() => { const sheet = this.sheet.sheet(); return sheet.object(this.key(), untracked(this.props), { reconfigure: true }); }); this.sheetObject = linkedSignal(this.originalSheetObject); this.values = linkedSignal(() => this.sheetObject().value); this.detached = false; this.aggregatedProps = {}; effect(() => { this.aggregatedProps = { ...this.aggregatedProps, ...this.props() }; }); effect((onCleanup) => { const sheetObject = this.sheetObject(); const cleanup = sheetObject.onValuesChange((newValues) => { this.values.set(newValues); this.store.snapshot.invalidate(); }); onCleanup(cleanup); }); effect((onCleanup) => { const studio = this.studio?.(); if (!studio) return; const sheetObject = this.sheetObject(); const cleanup = studio.onSelectionChange((selection) => { this.selected.set(selection.includes(sheetObject)); }); onCleanup(cleanup); }); effect((onCleanup) => { const view = this.vcr.createEmbeddedView(this.templateRef, { select: this.select.bind(this), deselect: this.deselect.bind(this), sheetObject: this.sheetObject.asReadonly(), values: this.values.asReadonly(), }); view.detectChanges(); onCleanup(() => { view.destroy(); }); }); inject(DestroyRef).onDestroy(() => { if (this.detach()) { this.detached = true; this.sheet.sheet().detachObject(this.key()); } }); } update() { if (this.detached) return; const [sheet, key] = [untracked(this.sheet.sheet), untracked(this.key)]; sheet.detachObject(key); this.sheetObject.set(sheet.object(key, this.aggregatedProps, { reconfigure: true })); } addProps(props) { this.aggregatedProps = { ...this.aggregatedProps, ...props }; this.update(); } removeProps(props) { const [detach, sheet, key] = [untracked(this.detach), untracked(this.sheet.sheet), untracked(this.key)]; // remove props from sheet object props.forEach((prop) => { delete this.aggregatedProps[prop]; }); // if there are no more props, detach sheet object if (Object.keys(this.aggregatedProps).length === 0) { // detach sheet object if (detach) { sheet.detachObject(key); } } else { // update sheet object (reconfigure) this.update(); } } select() { const studio = this.studio?.(); if (!studio) return; studio.setSelection([this.sheetObject()]); } deselect() { const studio = this.studio?.(); if (!studio) return; if (studio.selection.includes(this.sheetObject())) { studio.setSelection([]); } } static ngTemplateContextGuard(_, ctx) { return true; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObject, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.1", type: TheatreSheetObject, isStandalone: true, selector: "ng-template[sheetObject]", inputs: { key: { classPropertyName: "key", publicName: "sheetObject", isSignal: true, isRequired: true, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, detach: { classPropertyName: "detach", publicName: "detach", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, ngImport: i0 }); } }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObject$1, decorators: [{ type: Directive, args: [{ selector: 'ng-template[sheetObject]' }] }], ctorParameters: () => [] }); function createTransformer(transformer) { return transformer; } const _color = new THREE.Color(); const color = createTransformer({ transform(value) { value.getRGB(_color, THREE.SRGBColorSpace); return types.rgba({ r: _color.r, g: _color.g, b: _color.b, a: 1 }); }, apply(target, path, value) { target[path].setRGB(value.r, value.g, value.b, THREE.SRGBColorSpace); }, }); const degrees = createTransformer({ transform(target) { return types.number(target * THREE.MathUtils.RAD2DEG); }, apply(target, path, value) { target[path] = value * THREE.MathUtils.DEG2RAD; }, }); const euler = createTransformer({ transform(value) { return types.compound({ x: value.x * THREE.MathUtils.RAD2DEG, y: value.y * THREE.MathUtils.RAD2DEG, z: value.z * THREE.MathUtils.RAD2DEG, }); }, apply(target, path, value) { target[path].x = value.x * THREE.MathUtils.DEG2RAD; target[path].y = value.y * THREE.MathUtils.DEG2RAD; target[path].z = value.z * THREE.MathUtils.DEG2RAD; }, }); const generic = createTransformer({ transform(value) { if (typeof value === 'number') { return types.number(value === Infinity ? Number.MAX_VALUE : value); } else if (typeof value === 'string') { return types.string(value); } else if (typeof value === 'boolean') { return types.boolean(value); } return types.compound({ ...value }); }, apply(target, path, value) { if (target[path] !== null && typeof target[path] === 'object') { Object.assign(target[path], value); } else { target[path] = value; } }, }); const normalized = createTransformer({ transform(value) { return types.number(value, { range: [0, 1] }); }, apply(target, path, value) { target[path] = value; }, }); const side = createTransformer({ transform(value) { // TODO: fix this type return types.stringLiteral(value === THREE.FrontSide ? 'f' : value === THREE.BackSide ? 'b' : 'd', { f: 'Front', b: 'Back', d: 'Double' }, { as: 'switch' }); }, apply(target, path, value) { target[path] = value === 'f' ? THREE.FrontSide : value === 'b' ? THREE.BackSide : THREE.DoubleSide; }, }); function isFullOrEndingPattern(fullPropertyPath, pattern) { return fullPropertyPath.endsWith(`.${pattern}`) || fullPropertyPath === pattern; } function getDefaultTransformer(target, path, fullPropertyPath) { const property = target[path]; if (property.isEuler) return euler; if (property.isColor) return color; if (isFullOrEndingPattern(fullPropertyPath, 'rotation.x') || isFullOrEndingPattern(fullPropertyPath, 'rotation.y') || isFullOrEndingPattern(fullPropertyPath, 'rotation.z') || (target.isEuler && (fullPropertyPath === 'x' || fullPropertyPath === 'y' || fullPropertyPath === 'z'))) { return degrees; } if (isFullOrEndingPattern(fullPropertyPath, 'r')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'g')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'b')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'opacity')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'roughness')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'metalness')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'transmission')) return normalized; if (isFullOrEndingPattern(fullPropertyPath, 'side')) return side; return generic; } const updateProjectionMatrixKeys = ['fov', 'near', 'far', 'zoom', 'left', 'right', 'top', 'bottom', 'aspect']; class TheatreSheetObjectSync { constructor() { this.parent = input.required({ alias: 'sync', }); this.props = input([], { alias: 'syncProps' }); this.sheetObject = inject(TheatreSheetObject$1); this.studio = inject(THEATRE_STUDIO, { optional: true }); this.parentRef = computed(() => { const parent = this.parent(); if (typeof parent === 'function') return resolveRef(parent()); return resolveRef(parent); }); this.resolvedProps = computed(() => { const props = this.props(); return props.reduce((resolved, prop) => { if (typeof prop === 'string') { resolved.push([prop, { key: this.resolvePropertyPath(prop) }]); } else { if (typeof prop[1] === 'string') { resolved.push([prop[0], { key: prop[1] }]); } else { resolved.push(prop); } } return resolved; }, []); }); this.init = signal(false); this.propsMapping = {}; effect(() => { const parent = this.parentRef(); if (!parent) return; const propsToAdd = {}; const resolvedProps = this.resolvedProps(); resolvedProps.forEach(([propName, { key, label, transformer }]) => { const { root, targetKey, targetProp } = resolveInstanceKey(parent, propName); const rawValue = root[targetKey]; const valueTransformer = transformer ?? getDefaultTransformer(root, targetKey, propName); const value = valueTransformer.transform(rawValue); value.label = label ?? key; this.propsMapping[key] = { path: propName, transformer: valueTransformer }; propsToAdd[key] = value; }); this.sheetObject.addProps(propsToAdd); this.init.set(true); }); effect((onCleanup) => { const parent = this.parentRef(); if (!parent) return; const init = this.init(); if (!init) return; const sheetObject = this.sheetObject.sheetObject(); const cleanup = sheetObject.onValuesChange((newValues) => { Object.keys(newValues).forEach((key) => { // first, check if the prop is mapped in this component const propMapping = this.propsMapping[key]; if (!propMapping) return; // we're using the addedProps map to infer the target property name from the property name on values const { root, targetProp, targetKey } = resolveInstanceKey(parent, propMapping.path); // use a transformer to apply value const transformer = propMapping.transformer; transformer.apply(root, targetKey, newValues[key]); if (updateProjectionMatrixKeys.includes(targetKey)) { root.updateProjectionMatrix?.(); } }); }); onCleanup(cleanup); }); inject(DestroyRef).onDestroy(() => { this.sheetObject.removeProps(Object.keys(this.propsMapping)); }); } resolvePropertyPath(propPath) { return (propPath // make the label alphanumeric by first removing dots (fundamental feature for pierced props) .replace(/\./g, '-') // make the following characters uppercase .replace(/-([a-z])/g, (g) => g[1].toUpperCase()) // convert to safe alphanumeric characters without dashes .replace(/[^a-zA-Z0-9]/g, '')); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObjectSync, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.1", type: TheatreSheetObjectSync, isStandalone: true, selector: "[sync]", inputs: { parent: { classPropertyName: "parent", publicName: "sync", isSignal: true, isRequired: true, transformFunction: null }, props: { classPropertyName: "props", publicName: "syncProps", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObjectSync, decorators: [{ type: Directive, args: [{ selector: '[sync]' }] }], ctorParameters: () => [] }); class TheatreSheetObjectTransform { onMouseDown() { if (!this.studio) return; if (this.scrub) return; this.scrub = this.studio().scrub(); } onMouseUp() { if (!this.scrub) return; this.scrub.commit(); this.scrub = undefined; } onChange() { if (!this.scrub) return; this.scrub.capture((api) => { const sheetObject = this.sheetObject.sheetObject(); if (!sheetObject) return; const group = this.groupRef().nativeElement; const key = this.key(); const baseTarget = key ? sheetObject.props[key] : sheetObject.props; api.set(baseTarget['position'], { ...group.position }); api.set(baseTarget['rotation'], { x: group.rotation.x * THREE.MathUtils.RAD2DEG, y: group.rotation.y * THREE.MathUtils.RAD2DEG, z: group.rotation.z * THREE.MathUtils.RAD2DEG, }); api.set(baseTarget['scale'], { ...group.scale }); }); } constructor() { this.label = input(); this.key = input(); this.options = input({}); this.groupRef = viewChild.required('group'); this.sheetObject = inject(TheatreSheetObject$1); this.studio = inject(THEATRE_STUDIO, { optional: true }); this.selected = this.sheetObject.selected.asReadonly(); this.positionTransformer = computed(() => getDefaultTransformer(this.groupRef().nativeElement, 'position', 'position')); this.rotationTransformer = computed(() => getDefaultTransformer(this.groupRef().nativeElement, 'rotation', 'rotation')); this.scaleTransformer = computed(() => getDefaultTransformer(this.groupRef().nativeElement, 'scale', 'scale')); extend({ Group }); afterNextRender(() => { this.init(); }); effect((onCleanup) => { const [sheetObject, key, positionTransformer, rotationTransformer, scaleTransformer, group] = [ this.sheetObject.sheetObject(), untracked(this.key), untracked(this.positionTransformer), untracked(this.rotationTransformer), untracked(this.scaleTransformer), untracked(this.groupRef).nativeElement, ]; const cleanup = sheetObject.onValuesChange((newValues) => { let object = newValues; if (key) { if (!newValues[key]) return; object = newValues[key]; } else { if (!newValues['position'] || !newValues['rotation'] || !newValues['scale']) return; } // sanity check if (!object) return; positionTransformer.apply(group, 'position', object['position']); rotationTransformer.apply(group, 'rotation', object['rotation']); scaleTransformer.apply(group, 'scale', object['scale']); }); onCleanup(cleanup); }); inject(DestroyRef).onDestroy(() => { const key = this.key(); this.sheetObject.removeProps(key ? [key] : ['position', 'rotation', 'scale']); }); } init() { const [group, key, label, positionTransformer, rotationTransformer, scaleTransformer] = [ this.groupRef().nativeElement, this.key(), this.label(), this.positionTransformer(), this.rotationTransformer(), this.scaleTransformer(), ]; const position = positionTransformer.transform(group.position); const rotation = rotationTransformer.transform(group.rotation); const scale = scaleTransformer.transform(group.scale); if (key) { this.sheetObject.addProps({ [key]: types.compound({ position, rotation, scale }, { label: label ?? key }), }); } else { this.sheetObject.addProps({ position, rotation, scale }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObjectTransform, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", type: TheatreSheetObjectTransform, isStandalone: true, selector: "theatre-transform", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "groupRef", first: true, predicate: ["group"], descendants: true, isSignal: true }], ngImport: i0, template: ` @if (selected()) { <ngts-transform-controls [object]="$any(group)" [options]="options()" (mouseDown)="onMouseDown()" (mouseUp)="onMouseUp()" (change)="onChange()" /> } <ngt-group #group> <ng-content /> </ngt-group> `, isInline: true, dependencies: [{ kind: "component", type: NgtsTransformControls, selector: "ngts-transform-controls", inputs: ["object", "options"], outputs: ["change", "mouseDown", "mouseUp", "objectChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreSheetObjectTransform, decorators: [{ type: Component, args: [{ selector: 'theatre-transform', template: ` @if (selected()) { <ngts-transform-controls [object]="$any(group)" [options]="options()" (mouseDown)="onMouseDown()" (mouseUp)="onMouseUp()" (change)="onChange()" /> } <ngt-group #group> <ng-content /> </ngt-group> `, imports: [NgtsTransformControls], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: () => [] }); const TheatreSheetObject = [TheatreSheetObject$1, TheatreSheetObjectTransform, TheatreSheetObjectSync]; class TheatreStudio { constructor() { this.enabled = input(true, { alias: 'studio', transform: booleanAttribute }); this.Studio = signal(Studio); this.studio = this.Studio.asReadonly(); this.Studio().initialize(); effect((onCleanup) => { const [enabled, studio] = [this.enabled(), this.Studio()]; if (enabled) { studio.ui.restore(); } else { studio.ui.hide(); } onCleanup(() => { studio.ui.hide(); }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreStudio, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.1", type: TheatreStudio, isStandalone: true, selector: "theatre-project[studio]", inputs: { enabled: { classPropertyName: "enabled", publicName: "studio", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ { provide: THEATRE_STUDIO, useFactory: (studio) => studio.studio, deps: [TheatreStudio] }, ], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: TheatreStudio, decorators: [{ type: Directive, args: [{ selector: 'theatre-project[studio]', providers: [ { provide: THEATRE_STUDIO, useFactory: (studio) => studio.studio, deps: [TheatreStudio] }, ], }] }], ctorParameters: () => [] }); /** * Generated bundle index. Do not edit. */ export { TheatreProject, TheatreSequence, TheatreSheet, TheatreSheetObject, TheatreSheetObject$1 as TheatreSheetObjectImpl, TheatreSheetObjectSync, TheatreSheetObjectTransform, TheatreStudio }; //# sourceMappingURL=angular-three-theatre.mjs.map