babylon.quarks-editor 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/core/assetDragSession.d.ts +4 -0
- package/dist/core/assetDragSession.js +8 -0
- package/dist/core/assetTree.d.ts +39 -0
- package/dist/core/assetTree.js +112 -0
- package/dist/core/assets.d.ts +56 -0
- package/dist/core/assets.js +207 -0
- package/dist/core/binding.d.ts +5 -0
- package/dist/core/binding.js +7 -0
- package/dist/core/collision.d.ts +4 -5
- package/dist/core/collision.js +4 -5
- package/dist/core/defaultEffect.d.ts +4 -5
- package/dist/core/defaultEffect.js +5 -14
- package/dist/core/emitterShapeWireframe.d.ts +1 -0
- package/dist/core/emitterShapeWireframe.js +1 -0
- package/dist/core/galleryPlayback.d.ts +7 -7
- package/dist/core/galleryPlayback.js +2 -2
- package/dist/core/galleryScene.d.ts +8 -13
- package/dist/core/galleryScene.js +14 -42
- package/dist/core/gallerySelectionMarker.d.ts +1 -0
- package/dist/core/gallerySelectionMarker.js +1 -0
- package/dist/core/history.d.ts +12 -1
- package/dist/core/history.js +16 -3
- package/dist/core/indexedDbProjectStore.d.ts +35 -0
- package/dist/core/indexedDbProjectStore.js +299 -0
- package/dist/core/lineShaders.d.ts +2 -0
- package/dist/core/lineShaders.js +7 -0
- package/dist/core/pickAssetFiles.d.ts +6 -0
- package/dist/core/{pickGalleryFiles.js → pickAssetFiles.js} +13 -8
- package/dist/core/projectStore.d.ts +61 -0
- package/dist/core/projectStore.js +14 -0
- package/dist/core/sceneEntries.d.ts +35 -0
- package/dist/core/sceneEntries.js +62 -0
- package/dist/core/transport.d.ts +12 -0
- package/dist/core/transport.js +36 -0
- package/dist/core/viewportPicker.d.ts +4 -4
- package/dist/core/viewportPicker.js +3 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/react/AssetsPanel.d.ts +22 -0
- package/dist/react/AssetsPanel.js +252 -0
- package/dist/react/ChoiceDialog.d.ts +18 -0
- package/dist/react/ChoiceDialog.js +48 -0
- package/dist/react/ContextMenu.d.ts +16 -0
- package/dist/react/ContextMenu.js +70 -0
- package/dist/react/EditorWorkspace.d.ts +21 -0
- package/dist/react/EditorWorkspace.js +63 -0
- package/dist/react/EffectEditor.d.ts +1 -1
- package/dist/react/EffectEditor.js +7 -4
- package/dist/react/EffectEditorHost.d.ts +19 -2
- package/dist/react/EffectEditorHost.js +1385 -607
- package/dist/react/EffectTreeView.d.ts +17 -0
- package/dist/react/EffectTreeView.js +52 -0
- package/dist/react/ObjectModule.d.ts +4 -0
- package/dist/react/ObjectModule.js +7 -10
- package/dist/react/ProjectsPage.d.ts +9 -0
- package/dist/react/ProjectsPage.js +140 -0
- package/dist/react/ScenePanel.d.ts +26 -0
- package/dist/react/ScenePanel.js +134 -0
- package/dist/react/TimelinePanel.d.ts +8 -1
- package/dist/react/TimelinePanel.js +20 -41
- package/dist/react/TransportBar.d.ts +24 -0
- package/dist/react/TransportBar.js +43 -0
- package/dist/react/behaviorModules.js +5 -7
- package/dist/react/index.d.ts +16 -2
- package/dist/react/index.js +8 -1
- package/dist/react/inspectorHints.js +1 -2
- package/package.json +1 -1
- package/src/core/assetDragSession.ts +12 -0
- package/src/core/assetTree.ts +148 -0
- package/src/core/assets.ts +262 -0
- package/src/core/binding.ts +8 -0
- package/src/core/collision.ts +4 -5
- package/src/core/defaultEffect.ts +9 -22
- package/src/core/emitterShapeWireframe.ts +1 -0
- package/src/core/galleryPlayback.ts +9 -9
- package/src/core/galleryScene.ts +15 -59
- package/src/core/gallerySelectionMarker.ts +1 -0
- package/src/core/history.ts +24 -3
- package/src/core/indexedDbProjectStore.ts +357 -0
- package/src/core/lineShaders.ts +7 -0
- package/src/core/{pickGalleryFiles.ts → pickAssetFiles.ts} +13 -8
- package/src/core/projectStore.ts +81 -0
- package/src/core/sceneEntries.ts +96 -0
- package/src/core/transport.ts +53 -0
- package/src/core/viewportPicker.ts +5 -5
- package/src/index.ts +11 -0
- package/src/react/AssetsPanel.tsx +559 -0
- package/src/react/ChoiceDialog.tsx +93 -0
- package/src/react/ContextMenu.tsx +107 -0
- package/src/react/EditorWorkspace.tsx +95 -0
- package/src/react/EffectEditor.tsx +15 -4
- package/src/react/EffectEditorHost.tsx +1922 -813
- package/src/react/EffectTreeView.tsx +117 -0
- package/src/react/ObjectModule.tsx +17 -13
- package/src/react/ProjectsPage.tsx +306 -0
- package/src/react/ScenePanel.tsx +318 -0
- package/src/react/TimelinePanel.tsx +102 -103
- package/src/react/TransportBar.tsx +114 -0
- package/src/react/behaviorModules.tsx +7 -15
- package/src/react/index.ts +16 -2
- package/src/react/inspectorHints.ts +1 -2
- package/dist/core/galleryDragSession.d.ts +0 -4
- package/dist/core/galleryDragSession.js +0 -8
- package/dist/core/galleryTree.d.ts +0 -49
- package/dist/core/galleryTree.js +0 -141
- package/dist/core/loadEffectGallery.d.ts +0 -36
- package/dist/core/loadEffectGallery.js +0 -97
- package/dist/core/pickGalleryFiles.d.ts +0 -5
- package/dist/react/GalleryPanel.d.ts +0 -20
- package/dist/react/GalleryPanel.js +0 -253
- package/src/core/galleryDragSession.ts +0 -12
- package/src/core/galleryTree.ts +0 -190
- package/src/core/loadEffectGallery.ts +0 -150
- package/src/react/GalleryPanel.tsx +0 -561
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { theme } from './theme';
|
|
5
|
+
/** Right-click menu at the pointer; closes on outside click, Escape, scroll or window blur. */
|
|
6
|
+
export function ContextMenu(props) {
|
|
7
|
+
const { x, y, items, onClose } = props;
|
|
8
|
+
const ref = useRef(null);
|
|
9
|
+
const [position, setPosition] = useState({ left: x, top: y });
|
|
10
|
+
// Keep the menu on screen near the right/bottom edges.
|
|
11
|
+
useLayoutEffect(() => {
|
|
12
|
+
const el = ref.current;
|
|
13
|
+
if (!el)
|
|
14
|
+
return;
|
|
15
|
+
const { width, height } = el.getBoundingClientRect();
|
|
16
|
+
setPosition({
|
|
17
|
+
left: Math.max(4, Math.min(x, window.innerWidth - width - 4)),
|
|
18
|
+
top: Math.max(4, Math.min(y, window.innerHeight - height - 4)),
|
|
19
|
+
});
|
|
20
|
+
}, [x, y]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const onPointerDown = (e) => {
|
|
23
|
+
if (!ref.current?.contains(e.target))
|
|
24
|
+
onClose();
|
|
25
|
+
};
|
|
26
|
+
const onKey = (e) => {
|
|
27
|
+
if (e.key === 'Escape')
|
|
28
|
+
onClose();
|
|
29
|
+
};
|
|
30
|
+
window.addEventListener('pointerdown', onPointerDown, true);
|
|
31
|
+
window.addEventListener('keydown', onKey);
|
|
32
|
+
window.addEventListener('wheel', onClose, true);
|
|
33
|
+
window.addEventListener('blur', onClose);
|
|
34
|
+
return () => {
|
|
35
|
+
window.removeEventListener('pointerdown', onPointerDown, true);
|
|
36
|
+
window.removeEventListener('keydown', onKey);
|
|
37
|
+
window.removeEventListener('wheel', onClose, true);
|
|
38
|
+
window.removeEventListener('blur', onClose);
|
|
39
|
+
};
|
|
40
|
+
}, [onClose]);
|
|
41
|
+
return createPortal(_jsx("div", { ref: ref, role: "menu", onContextMenu: (e) => e.preventDefault(), style: {
|
|
42
|
+
position: 'fixed',
|
|
43
|
+
left: position.left,
|
|
44
|
+
top: position.top,
|
|
45
|
+
zIndex: 1000,
|
|
46
|
+
minWidth: 170,
|
|
47
|
+
padding: 4,
|
|
48
|
+
background: '#0c1226',
|
|
49
|
+
border: `1px solid ${theme.border}`,
|
|
50
|
+
borderRadius: 8,
|
|
51
|
+
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.45)',
|
|
52
|
+
fontFamily: theme.font,
|
|
53
|
+
}, children: items.map((item) => (_jsx("button", { type: "button", role: "menuitem", className: "qe-hover-bg", disabled: item.disabled, style: {
|
|
54
|
+
display: 'block',
|
|
55
|
+
width: '100%',
|
|
56
|
+
textAlign: 'left',
|
|
57
|
+
border: 'none',
|
|
58
|
+
borderRadius: 5,
|
|
59
|
+
background: 'transparent',
|
|
60
|
+
color: item.danger ? '#ff8a8a' : theme.text,
|
|
61
|
+
opacity: item.disabled ? 0.45 : 1,
|
|
62
|
+
padding: '6px 10px',
|
|
63
|
+
fontSize: 12.5,
|
|
64
|
+
cursor: item.disabled ? 'default' : 'pointer',
|
|
65
|
+
fontFamily: theme.font,
|
|
66
|
+
}, onClick: () => {
|
|
67
|
+
onClose();
|
|
68
|
+
item.onSelect();
|
|
69
|
+
}, children: item.label }, item.label))) }), document.body);
|
|
70
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ProjectStore } from '../core/projectStore';
|
|
3
|
+
import { type EffectEditorHostProps } from './EffectEditorHost';
|
|
4
|
+
export interface EditorWorkspaceProps extends Omit<EffectEditorHostProps, 'project' | 'onExitProject' | 'effectJson'> {
|
|
5
|
+
/** Where projects are kept; defaults to the browser's IndexedDB. */
|
|
6
|
+
store?: ProjectStore;
|
|
7
|
+
/** Project to open right away (e.g. from the url); the projects page is shown otherwise. */
|
|
8
|
+
projectId?: string | null;
|
|
9
|
+
/** Called when a project is opened or closed — e.g. to mirror it in the url. */
|
|
10
|
+
onProjectChange?: (projectId: string | null) => void;
|
|
11
|
+
}
|
|
12
|
+
/** Projects page → editor for the chosen project, with assets and scene saved in `store`. */
|
|
13
|
+
export declare function EditorWorkspace(props: EditorWorkspaceProps): React.ReactElement;
|
|
14
|
+
/** Imperative entry point, like QuarksEffectEditor.Show, for the project-based workspace. */
|
|
15
|
+
export declare const QuarksEditorWorkspace: {
|
|
16
|
+
Show(options: EditorWorkspaceProps & {
|
|
17
|
+
hostElement: HTMLElement;
|
|
18
|
+
}): {
|
|
19
|
+
dispose: () => void;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import { IndexedDbProjectStore } from '../core/indexedDbProjectStore';
|
|
5
|
+
import { EffectEditorHost } from './EffectEditorHost';
|
|
6
|
+
import { ProjectsPage } from './ProjectsPage';
|
|
7
|
+
import { theme } from './theme';
|
|
8
|
+
/** Projects page → editor for the chosen project, with assets and scene saved in `store`. */
|
|
9
|
+
export function EditorWorkspace(props) {
|
|
10
|
+
const { store: storeProp, projectId, onProjectChange, ...hostProps } = props;
|
|
11
|
+
const store = useMemo(() => storeProp ?? new IndexedDbProjectStore(), [storeProp]);
|
|
12
|
+
const [project, setProject] = useState(null);
|
|
13
|
+
const [resolving, setResolving] = useState(Boolean(projectId));
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!projectId) {
|
|
16
|
+
setResolving(false);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let cancelled = false;
|
|
20
|
+
void store.getProject(projectId).then((meta) => {
|
|
21
|
+
if (cancelled)
|
|
22
|
+
return;
|
|
23
|
+
setProject(meta);
|
|
24
|
+
setResolving(false);
|
|
25
|
+
if (!meta)
|
|
26
|
+
onProjectChange?.(null);
|
|
27
|
+
});
|
|
28
|
+
return () => {
|
|
29
|
+
cancelled = true;
|
|
30
|
+
};
|
|
31
|
+
// Only the initial project id is honoured; later navigation goes through onProjectChange.
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, [store]);
|
|
34
|
+
if (resolving) {
|
|
35
|
+
return (_jsx("div", { style: {
|
|
36
|
+
width: '100%',
|
|
37
|
+
height: '100%',
|
|
38
|
+
background: '#070b16',
|
|
39
|
+
color: theme.textDim,
|
|
40
|
+
fontFamily: theme.font,
|
|
41
|
+
padding: 24,
|
|
42
|
+
}, children: "Opening project\u2026" }));
|
|
43
|
+
}
|
|
44
|
+
if (!project) {
|
|
45
|
+
return (_jsx(ProjectsPage, { store: store, title: hostProps.title, onOpen: (meta) => {
|
|
46
|
+
setProject(meta);
|
|
47
|
+
onProjectChange?.(meta.id);
|
|
48
|
+
} }));
|
|
49
|
+
}
|
|
50
|
+
return (_jsx(EffectEditorHost, { ...hostProps, project: { store, id: project.id, name: project.name }, onExitProject: () => {
|
|
51
|
+
setProject(null);
|
|
52
|
+
onProjectChange?.(null);
|
|
53
|
+
} }, project.id));
|
|
54
|
+
}
|
|
55
|
+
/** Imperative entry point, like QuarksEffectEditor.Show, for the project-based workspace. */
|
|
56
|
+
export const QuarksEditorWorkspace = {
|
|
57
|
+
Show(options) {
|
|
58
|
+
const { hostElement, ...props } = options;
|
|
59
|
+
const root = createRoot(hostElement);
|
|
60
|
+
root.render(_jsx(EditorWorkspace, { ...props }));
|
|
61
|
+
return { dispose: () => root.unmount() };
|
|
62
|
+
},
|
|
63
|
+
};
|
|
@@ -22,4 +22,4 @@ export interface EffectEditorProps {
|
|
|
22
22
|
* Embed it anywhere React runs — the standalone examples page or a BabylonJS Editor plugin.
|
|
23
23
|
* Module order mirrors Unity's Particle System inspector.
|
|
24
24
|
*/
|
|
25
|
-
export declare
|
|
25
|
+
export declare const EffectEditor: React.NamedExoticComponent<EffectEditorProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useSyncExternalStore } from 'react';
|
|
2
|
+
import React, { useEffect, useSyncExternalStore } from 'react';
|
|
3
3
|
import { EffectBinding } from '../core/binding';
|
|
4
4
|
import { CollisionModule, ColorBySpeedModule, EmitDirectionModule, ForceOverLifeModule, GravityModule, InheritVelocityModule, LimitSpeedOverLifeModule, NoiseModule, OrbitOverLifeModule, RotationBySpeedModule, RotationOverLifeModule, SizeBySpeedModule, SpeedOverLifeModule, TextureSheetModule, TurbulenceModule, VelocityOverLifeModule, WidthOverTrailModule, } from './behaviorModules';
|
|
5
5
|
import { ColorOverLifeModule, EmissionModule, MainModule, RendererModule, ShapeModule, SizeOverLifeModule, } from './modules';
|
|
@@ -11,7 +11,7 @@ import { theme } from './theme';
|
|
|
11
11
|
* Embed it anywhere React runs — the standalone examples page or a BabylonJS Editor plugin.
|
|
12
12
|
* Module order mirrors Unity's Particle System inspector.
|
|
13
13
|
*/
|
|
14
|
-
export function EffectEditor(props) {
|
|
14
|
+
export const EffectEditor = React.memo(function EffectEditor(props) {
|
|
15
15
|
useSyncExternalStore((onStoreChange) => props.binding.subscribe(onStoreChange), () => props.binding.getRevision());
|
|
16
16
|
const allSystems = [props.binding.system, ...props.binding.subSystems];
|
|
17
17
|
// Selection survives re-renders but falls back to root if the system was removed/replaced.
|
|
@@ -26,7 +26,10 @@ export function EffectEditor(props) {
|
|
|
26
26
|
nested.onBeforeChange = () => props.binding.onBeforeChange?.();
|
|
27
27
|
return nested;
|
|
28
28
|
}, [props.binding, activeSystem]);
|
|
29
|
+
// A sub-system edit is a change of the whole effect: the host's undo buttons, timeline and
|
|
30
|
+
// wireframes all listen to the root binding.
|
|
31
|
+
useEffect(() => (binding === props.binding ? undefined : binding.subscribe(() => props.binding.markChanged())), [binding, props.binding]);
|
|
29
32
|
useSyncExternalStore((onStoreChange) => binding.subscribe(onStoreChange), () => binding.getRevision());
|
|
30
33
|
const gizmoTargetIsEmitter = allSystems.some((s) => s.emitter === props.gizmoTargetNode);
|
|
31
|
-
return (_jsxs("div", { style: { fontFamily: theme.font, color: theme.text }, children: [_jsx(ObjectModule, { node: props.gizmoTargetNode, label: props.gizmoTargetLabel }), !gizmoTargetIsEmitter && (_jsxs("div", { style: { fontSize: 11, color: theme.textDim, margin: '0 0 10px', lineHeight: 1.45 }, children: ["Modules below edit ", _jsx("strong", { children: activeSystem.emitter.name || 'particle system' }), ". Select its emitter in the timeline to move it with the gizmo."] })), _jsx(MainModule, { binding: binding }), _jsx(EmissionModule, { binding: binding }), _jsx(ShapeModule, { binding: binding }), _jsx(EmitDirectionModule, { binding: binding }), _jsx(VelocityOverLifeModule, { binding: binding }), _jsx(SpeedOverLifeModule, { binding: binding }), _jsx(LimitSpeedOverLifeModule, { binding: binding }), _jsx(InheritVelocityModule, { binding: binding }), _jsx(ForceOverLifeModule, { binding: binding }), _jsx(GravityModule, { binding: binding }), _jsx(OrbitOverLifeModule, { binding: binding }), _jsx(ColorOverLifeModule, { binding: binding }), _jsx(ColorBySpeedModule, { binding: binding }), _jsx(SizeOverLifeModule, { binding: binding }), _jsx(SizeBySpeedModule, { binding: binding }), _jsx(RotationOverLifeModule, { binding: binding }), _jsx(RotationBySpeedModule, { binding: binding }), _jsx(NoiseModule, { binding: binding }), _jsx(TurbulenceModule, { binding: binding }), _jsx(CollisionModule, { binding: binding }), _jsx(WidthOverTrailModule, { binding: binding }), _jsx(SubEmittersModule, { binding: binding, rootBinding: props.binding }), _jsx(TextureSheetModule, { binding: binding }), _jsx(RendererModule, { binding: binding, textureOptions: props.textureOptions, geometryOptions: props.geometryOptions, resolveTexture: props.resolveTexture, resolveGeometry: props.resolveGeometry })] }));
|
|
32
|
-
}
|
|
34
|
+
return (_jsxs("div", { style: { fontFamily: theme.font, color: theme.text }, children: [_jsx(ObjectModule, { node: props.gizmoTargetNode, label: props.gizmoTargetLabel, onBeforeChange: () => props.binding.onBeforeChange?.(), onChanged: () => props.binding.markChanged() }), !gizmoTargetIsEmitter && (_jsxs("div", { style: { fontSize: 11, color: theme.textDim, margin: '0 0 10px', lineHeight: 1.45 }, children: ["Modules below edit ", _jsx("strong", { children: activeSystem.emitter.name || 'particle system' }), ". Select its emitter in the timeline to move it with the gizmo."] })), _jsx(MainModule, { binding: binding }), _jsx(EmissionModule, { binding: binding }), _jsx(ShapeModule, { binding: binding }), _jsx(EmitDirectionModule, { binding: binding }), _jsx(VelocityOverLifeModule, { binding: binding }), _jsx(SpeedOverLifeModule, { binding: binding }), _jsx(LimitSpeedOverLifeModule, { binding: binding }), _jsx(InheritVelocityModule, { binding: binding }), _jsx(ForceOverLifeModule, { binding: binding }), _jsx(GravityModule, { binding: binding }), _jsx(OrbitOverLifeModule, { binding: binding }), _jsx(ColorOverLifeModule, { binding: binding }), _jsx(ColorBySpeedModule, { binding: binding }), _jsx(SizeOverLifeModule, { binding: binding }), _jsx(SizeBySpeedModule, { binding: binding }), _jsx(RotationOverLifeModule, { binding: binding }), _jsx(RotationBySpeedModule, { binding: binding }), _jsx(NoiseModule, { binding: binding }), _jsx(TurbulenceModule, { binding: binding }), _jsx(CollisionModule, { binding: binding }), _jsx(WidthOverTrailModule, { binding: binding }), _jsx(SubEmittersModule, { binding: binding, rootBinding: props.binding }), _jsx(TextureSheetModule, { binding: binding }), _jsx(RendererModule, { binding: binding, textureOptions: props.textureOptions, geometryOptions: props.geometryOptions, resolveTexture: props.resolveTexture, resolveGeometry: props.resolveGeometry })] }));
|
|
35
|
+
});
|
|
@@ -3,14 +3,18 @@ import { BatchedRenderer } from 'babylon.quarks';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { EffectBinding } from '../core/binding';
|
|
5
5
|
import { EffectHistory } from '../core/history';
|
|
6
|
+
import type { ProjectStore } from '../core/projectStore';
|
|
6
7
|
import type { GeometryData, GeometryOption, TextureOption } from './modules';
|
|
7
8
|
export interface EffectEditorHostHandle {
|
|
8
9
|
binding: EffectBinding;
|
|
9
10
|
history: EffectHistory;
|
|
10
11
|
scene: Scene;
|
|
11
12
|
renderer: BatchedRenderer;
|
|
13
|
+
/** Replaces the scene with this effect (it is also added to Assets). */
|
|
12
14
|
importJson: (json: unknown) => void;
|
|
13
|
-
/**
|
|
15
|
+
/** Imports effect files (and the texture/geometry files they reference) into Assets. */
|
|
16
|
+
importAssets: (files: FileList | File[]) => Promise<void>;
|
|
17
|
+
/** @deprecated Renamed to `importAssets`. */
|
|
14
18
|
importGallery: (files: FileList | File[]) => Promise<void>;
|
|
15
19
|
exportJson: () => string;
|
|
16
20
|
}
|
|
@@ -33,9 +37,22 @@ export interface EffectEditorHostProps {
|
|
|
33
37
|
href: string;
|
|
34
38
|
label: string;
|
|
35
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Project to edit: its assets load from and save to `store`, and the scene is saved with
|
|
42
|
+
* Save / Ctrl+S. Without it the editor works in memory only.
|
|
43
|
+
*/
|
|
44
|
+
project?: {
|
|
45
|
+
store: ProjectStore;
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
};
|
|
49
|
+
/** Shows a "← Projects" button; called once unsaved scene changes are dealt with. */
|
|
50
|
+
onExitProject?: () => void;
|
|
36
51
|
}
|
|
37
52
|
/**
|
|
38
|
-
* Self-contained effect editor: live Babylon preview
|
|
53
|
+
* Self-contained effect editor: live Babylon preview, a Scene list of the effects placed in it,
|
|
54
|
+
* an inspector, and a bottom dock with the timeline and the Assets browser. Assets are effect
|
|
55
|
+
* files; dragging one into the viewport instantiates an independent copy, as many times as needed.
|
|
39
56
|
* Designed for embedding — see QuarksEffectEditor.Show for the NME-style entry point.
|
|
40
57
|
*/
|
|
41
58
|
export declare function EffectEditorHost(props: EffectEditorHostProps): React.JSX.Element;
|