@threlte/core
Advanced tools
Comparing version 4.1.3 to 4.2.0
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: AudioProperties['visible']; | ||
userData?: AudioProperties['userData']; | ||
dispose?: AudioProperties['dispose']; | ||
autoplay?: AudioProperties['autoplay']; | ||
@@ -19,0 +21,0 @@ detune?: AudioProperties['detune']; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: AudioListenerProperties['visible']; | ||
userData?: AudioListenerProperties['userData']; | ||
dispose?: AudioListenerProperties['dispose']; | ||
id?: AudioListenerProperties['id']; | ||
@@ -19,0 +21,0 @@ masterVolume?: AudioListenerProperties['masterVolume']; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: PositionalAudioProperties['visible']; | ||
userData?: PositionalAudioProperties['userData']; | ||
dispose?: PositionalAudioProperties['dispose']; | ||
autoplay?: PositionalAudioProperties['autoplay']; | ||
@@ -19,0 +21,0 @@ detune?: PositionalAudioProperties['detune']; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: OrthographicCameraProperties['visible']; | ||
userData?: OrthographicCameraProperties['userData']; | ||
dispose?: OrthographicCameraProperties['dispose']; | ||
useCamera?: boolean | undefined; | ||
@@ -19,0 +21,0 @@ near?: OrthographicCameraProperties['near']; |
@@ -15,2 +15,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: PerspectiveCameraProperties['visible']; | ||
userData?: PerspectiveCameraProperties['userData']; | ||
dispose?: PerspectiveCameraProperties['dispose']; | ||
viewportAware?: boolean | undefined; | ||
@@ -17,0 +19,0 @@ inViewport?: boolean | undefined; |
@@ -19,2 +19,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
audioCtx?: import("./types/types").ThrelteAudioContext | undefined; | ||
disposalCtx?: import("./types/types").ThrelteDisposalContext | undefined; | ||
}; | ||
@@ -21,0 +22,0 @@ events: { |
# @threlte/core | ||
## 4.2.0 | ||
### Minor Changes | ||
- 834f333: Added a new property "userData" which is useful to debug, add custom properties and filter objects | ||
- a066d3b: Added automatic disposal of three.js objects. See documentation for more info. | ||
### Patch Changes | ||
- 458c49b: proper prop types on `<Object3DInstance>` | ||
## 4.1.3 | ||
@@ -4,0 +15,0 @@ |
@@ -31,2 +31,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
target?: OrbitControlsProperties['target']; | ||
dispose?: OrbitControlsProperties['dispose']; | ||
controls?: ThreeOrbitControls | undefined; | ||
@@ -33,0 +34,0 @@ }; |
@@ -19,2 +19,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
space?: TransformControlsProperties['space']; | ||
dispose?: TransformControlsProperties['dispose']; | ||
reset?: (() => any) | undefined; | ||
@@ -21,0 +22,0 @@ }; |
@@ -39,2 +39,3 @@ export { default as Canvas } from './Canvas.svelte'; | ||
export { default as ViewportAwareObject } from './internal/ViewportAwareObject.svelte'; | ||
export { default as DisposableObject } from './internal/DisposableObject.svelte'; | ||
export { useFrame } from './hooks/useFrame'; | ||
@@ -49,2 +50,2 @@ export { useThrelte } from './hooks/useThrelte'; | ||
export type { Position, Scale, Rotation, LookAt, ThrelteUseFrameOptions, ThrelteContext, ThrelteRootContext, ThrelteLayers, ThrelteUseLoader, ThreltePointerEvent, ThrelteInstance, Size } from './types/types'; | ||
export type { HierarchicalObjectProperties, InteractiveObjectProperties, LayerableObjectProperties, TransformableObjectProperties, ViewportAwareObjectProperties, Object3DInstanceProperties, MeshInstanceProperties, InstancedMeshProperties, InstanceProperties, LightInstanceProperties, CameraInstanceProperties, OrthographicCameraProperties, PerspectiveCameraProperties, OrbitControlsProperties, PassProperties, AmbientLightProperties, DirectionalLightProperties, HemisphereLightProperties, PointLightProperties, SpotLightProperties, FogProperties, FogExp2Properties, LayersProperties, GroupProperties, MeshProperties, Object3DProperties, AudioInstanceProperties, AudioListenerProperties, AudioProperties, Line2Properties, LineInstanceProperties, LineProperties, LineSegmentsProperties, PositionalAudioProperties, SceneGraphObjectProperties, TransformControlsProperties } from './types/components'; | ||
export type { HierarchicalObjectProperties, InteractiveObjectProperties, LayerableObjectProperties, TransformableObjectProperties, DisposableObjectProperties, ViewportAwareObjectProperties, Object3DInstanceProperties, MeshInstanceProperties, InstancedMeshProperties, InstanceProperties, LightInstanceProperties, CameraInstanceProperties, OrthographicCameraProperties, PerspectiveCameraProperties, OrbitControlsProperties, PassProperties, AmbientLightProperties, DirectionalLightProperties, HemisphereLightProperties, PointLightProperties, SpotLightProperties, FogProperties, FogExp2Properties, LayersProperties, GroupProperties, MeshProperties, Object3DProperties, AudioInstanceProperties, AudioListenerProperties, AudioProperties, Line2Properties, LineInstanceProperties, LineProperties, LineSegmentsProperties, PositionalAudioProperties, SceneGraphObjectProperties, TransformControlsProperties } from './types/components'; |
@@ -50,2 +50,3 @@ // canvas component | ||
export { default as ViewportAwareObject } from './internal/ViewportAwareObject.svelte'; | ||
export { default as DisposableObject } from './internal/DisposableObject.svelte'; | ||
// hooks | ||
@@ -52,0 +53,0 @@ export { useFrame } from './hooks/useFrame'; |
@@ -16,2 +16,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: boolean | undefined; | ||
userData?: Record<string, any> | undefined; | ||
dispose?: boolean | undefined; | ||
autoplay?: boolean | undefined; | ||
@@ -18,0 +20,0 @@ detune?: number | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: CameraInstanceProperties['visible']; | ||
userData?: CameraInstanceProperties['userData']; | ||
dispose?: CameraInstanceProperties['dispose']; | ||
useCamera?: boolean | undefined; | ||
@@ -19,0 +21,0 @@ }; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: LightInstanceProperties['visible']; | ||
userData?: LightInstanceProperties['userData']; | ||
dispose?: LightInstanceProperties['dispose']; | ||
color?: LightInstanceProperties['color']; | ||
@@ -19,0 +21,0 @@ intensity?: LightInstanceProperties['intensity']; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: LineInstanceProperties['visible']; | ||
userData?: LineInstanceProperties['userData']; | ||
dispose?: LineInstanceProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -19,0 +21,0 @@ ignorePointer?: boolean | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: MeshInstanceProperties['visible']; | ||
userData?: MeshInstanceProperties['userData']; | ||
dispose?: MeshInstanceProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -19,0 +21,0 @@ ignorePointer?: boolean | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: Object3DInstanceProperties['visible']; | ||
dispose?: Object3DInstanceProperties['dispose']; | ||
userData?: Object3DInstanceProperties['userData']; | ||
}; | ||
@@ -19,0 +21,0 @@ events: { |
import type { Writable } from 'svelte/store'; | ||
import type { Size, ThrelteAudioContext, ThrelteContext, ThrelteRenderContext, ThrelteRootContext } from '../types/types'; | ||
export declare const createContexts: (linear: boolean, flat: boolean, dpr: number, userSize: Writable<Size | undefined>, parentSize: Writable<Size>, debugFrameloop: boolean, frameloop: 'always' | 'demand' | 'never') => { | ||
import type { Size, ThrelteAudioContext, ThrelteContext, ThrelteDisposalContext, ThrelteRenderContext, ThrelteRootContext } from '../types/types'; | ||
export declare const createContexts: (linear: boolean, flat: boolean, dpr: number, userSize: Writable<Size | undefined>, parentSize: Writable<Size>, debugFrameloop: boolean, frameloop: 'always' | 'demand' | 'never', debugInfo: boolean) => { | ||
ctx: ThrelteContext; | ||
@@ -8,2 +8,3 @@ rootCtx: ThrelteRootContext; | ||
audioCtx: ThrelteAudioContext; | ||
disposalCtx: ThrelteDisposalContext; | ||
getCtx: () => ThrelteContext; | ||
@@ -13,2 +14,3 @@ getRootCtx: () => ThrelteRootContext; | ||
getAudioCtx: () => ThrelteAudioContext; | ||
getDisposalCtx: () => ThrelteDisposalContext; | ||
}; |
@@ -6,3 +6,3 @@ import { setContext } from 'svelte'; | ||
import { getDefaultCamera } from './defaultCamera'; | ||
export const createContexts = (linear, flat, dpr, userSize, parentSize, debugFrameloop, frameloop) => { | ||
export const createContexts = (linear, flat, dpr, userSize, parentSize, debugFrameloop, frameloop, debugInfo) => { | ||
const audioCtx = { | ||
@@ -36,2 +36,3 @@ audioListeners: new Map(), | ||
const renderCtx = { | ||
debugInfo, | ||
debugFrameloop, | ||
@@ -113,2 +114,30 @@ frameloop, | ||
}; | ||
const disposalCtx = { | ||
disposableObjects: new Set(), | ||
addDisposableObject: (object) => { | ||
if (!object) | ||
return; | ||
// Scenes can't be disposed | ||
if (object?.dispose && typeof object.dispose === 'function' && object.type !== 'Scene') { | ||
disposalCtx.disposableObjects.add(object); | ||
} | ||
// iterate over properties of obj | ||
Object.entries(object).forEach(([propKey, propValue]) => { | ||
// we don't want to dispose the parent | ||
if (propKey === 'parent' || propKey === 'children') | ||
return; | ||
// children don't need to be disposed as they manage their own disposal | ||
const value = propValue; | ||
if (value?.dispose) { | ||
disposalCtx.addDisposableObject(value); | ||
} | ||
}); | ||
}, | ||
dispose: () => { | ||
disposalCtx.disposableObjects.forEach((object) => { | ||
object.dispose?.(); | ||
}); | ||
disposalCtx.disposableObjects.clear(); | ||
} | ||
}; | ||
setContext('threlte', ctx); | ||
@@ -118,2 +147,3 @@ setContext('threlte-root', rootCtx); | ||
setContext('threlte-audio-context', audioCtx); | ||
setContext('threlte-disposal-context', disposalCtx); | ||
const getCtx = () => ctx; | ||
@@ -123,2 +153,3 @@ const getRootCtx = () => rootCtx; | ||
const getAudioCtx = () => audioCtx; | ||
const getDisposalCtx = () => disposalCtx; | ||
return { | ||
@@ -129,7 +160,9 @@ ctx, | ||
audioCtx, | ||
disposalCtx, | ||
getCtx, | ||
getRootCtx, | ||
getRenderCtx, | ||
getAudioCtx | ||
getAudioCtx, | ||
getDisposalCtx | ||
}; | ||
}; |
import { type Writable } from 'svelte/store'; | ||
import type { Object3D } from 'three'; | ||
/** | ||
* A store that only ever updates if the objects are actually different. | ||
* Accepts any object that has a property "uuid" (i.e. most Three.js objects). | ||
* | ||
* ### Example | ||
@@ -12,6 +13,11 @@ * | ||
* ``` | ||
* | ||
* @param object | ||
* @returns store | ||
*/ | ||
export declare function createObjectStore<T extends Object3D | undefined>(object: T): Writable<T>; | ||
export declare function createObjectStore<T extends Object3D>(object: T): Writable<T>; | ||
export declare function createObjectStore<T extends { | ||
uuid: string; | ||
} | undefined>(object: T, onChange?: (newObject: T, oldObject: T) => void): Writable<T>; | ||
export declare function createObjectStore<T extends { | ||
uuid: string; | ||
}>(object: T, onChange?: (newObject: T, oldObject: T) => void): Writable<T>; |
import { onDestroy } from 'svelte'; | ||
import { writable } from 'svelte/store'; | ||
export function createObjectStore(object) { | ||
export function createObjectStore(object, onChange) { | ||
const objectStore = writable(object); | ||
@@ -9,12 +9,21 @@ let unwrappedObject = object; | ||
const set = (newObject) => { | ||
if (!newObject || !unwrappedObject) | ||
return objectStore.set(newObject); | ||
if (newObject.uuid === unwrappedObject.uuid) | ||
if (newObject?.uuid === unwrappedObject?.uuid) | ||
return; | ||
const oldObject = unwrappedObject; | ||
objectStore.set(newObject); | ||
onChange?.(newObject, oldObject); | ||
}; | ||
const update = (callback) => { | ||
const newObject = callback(unwrappedObject); | ||
if (newObject?.uuid === unwrappedObject?.uuid) | ||
return; | ||
const oldObject = unwrappedObject; | ||
objectStore.set(newObject); | ||
onChange?.(newObject, oldObject); | ||
}; | ||
return { | ||
...objectStore, | ||
set | ||
set, | ||
update | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
import type { ThrelteContext, ThrelteRenderContext, ThrelteRootContext } from '../types/types'; | ||
export declare const useFrameloop: (ctx: ThrelteContext, rootCtx: ThrelteRootContext, renderCtx: ThrelteRenderContext) => void; | ||
import type { ThrelteContext, ThrelteDisposalContext, ThrelteRenderContext, ThrelteRootContext } from '../types/types'; | ||
export declare const useFrameloop: (ctx: ThrelteContext, rootCtx: ThrelteRootContext, renderCtx: ThrelteRenderContext, disposalCtx: ThrelteDisposalContext) => void; |
@@ -45,3 +45,3 @@ import { onDestroy } from 'svelte'; | ||
}; | ||
export const useFrameloop = (ctx, rootCtx, renderCtx) => { | ||
export const useFrameloop = (ctx, rootCtx, renderCtx, disposalCtx) => { | ||
let camera = get(ctx.camera); | ||
@@ -52,2 +52,3 @@ const unsubscribeCamera = ctx.camera.subscribe((c) => (camera = c)); | ||
useRaf(() => { | ||
disposalCtx.dispose(); | ||
const shouldRender = renderCtx.frameloop === 'always' || | ||
@@ -54,0 +55,0 @@ (renderCtx.frameloop === 'demand' && |
@@ -15,2 +15,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: AmbientLightProperties['visible']; | ||
userData?: AmbientLightProperties['userData']; | ||
dispose?: AmbientLightProperties['dispose']; | ||
viewportAware?: boolean | undefined; | ||
@@ -17,0 +19,0 @@ inViewport?: boolean | undefined; |
@@ -13,2 +13,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: DirectionalLightProperties['visible']; | ||
userData?: DirectionalLightProperties['userData']; | ||
dispose?: DirectionalLightProperties['dispose']; | ||
viewportAware?: boolean | undefined; | ||
@@ -15,0 +17,0 @@ inViewport?: boolean | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: HemisphereLightProperties['visible']; | ||
userData?: HemisphereLightProperties['userData']; | ||
dispose?: HemisphereLightProperties['dispose']; | ||
intensity?: HemisphereLightProperties['intensity']; | ||
@@ -19,0 +21,0 @@ skyColor?: HemisphereLightProperties['skyColor']; |
@@ -16,2 +16,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: PointLightProperties['visible']; | ||
userData?: PointLightProperties['userData']; | ||
dispose?: PointLightProperties['dispose']; | ||
intensity?: PointLightProperties['intensity']; | ||
@@ -18,0 +20,0 @@ color?: PointLightProperties['color']; |
@@ -15,2 +15,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: SpotLightProperties['visible']; | ||
userData?: SpotLightProperties['userData']; | ||
dispose?: SpotLightProperties['dispose']; | ||
color?: SpotLightProperties['color']; | ||
@@ -17,0 +19,0 @@ intensity?: SpotLightProperties['intensity']; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: GroupProperties['visible']; | ||
userData?: GroupProperties['userData']; | ||
dispose?: GroupProperties['dispose']; | ||
group?: ThreeGroup | undefined; | ||
@@ -19,0 +21,0 @@ }; |
@@ -25,2 +25,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: InstancedMeshProperties['visible']; | ||
userData?: InstancedMeshProperties['userData']; | ||
dispose?: InstancedMeshProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -27,0 +29,0 @@ ignorePointer?: boolean | undefined; |
@@ -16,2 +16,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: LineProperties['visible']; | ||
userData?: LineProperties['userData']; | ||
dispose?: LineProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -18,0 +20,0 @@ ignorePointer?: boolean | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: Line2Properties['visible']; | ||
userData?: Line2Properties['userData']; | ||
dispose?: Line2Properties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -19,0 +21,0 @@ ignorePointer?: boolean | undefined; |
@@ -16,2 +16,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: LineSegmentsProperties['visible']; | ||
userData?: LineSegmentsProperties['userData']; | ||
dispose?: LineSegmentsProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -18,0 +20,0 @@ ignorePointer?: boolean | undefined; |
@@ -16,2 +16,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: MeshProperties['visible']; | ||
userData?: MeshProperties['userData']; | ||
dispose?: MeshProperties['dispose']; | ||
interactive?: boolean | undefined; | ||
@@ -18,0 +20,0 @@ ignorePointer?: boolean | undefined; |
@@ -17,2 +17,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
visible?: Object3DProperties['visible']; | ||
userData?: Object3DProperties['userData']; | ||
dispose?: Object3DProperties['dispose']; | ||
object?: ThreeObject3D<import("three").Event> | undefined; | ||
@@ -19,0 +21,0 @@ }; |
@@ -12,2 +12,10 @@ import type { Audio, BufferGeometry, Camera, ColorRepresentation, Light, Line, Material, Mesh, Object3D, PositionalAudio, Vector3, Vector3Tuple } from 'three'; | ||
}; | ||
export declare type DisposableThreeObject = { | ||
dispose?: () => void; | ||
type?: string; | ||
} & Record<string, any>; | ||
export declare type DisposableObjectProperties = { | ||
object?: DisposableThreeObject; | ||
dispose?: boolean; | ||
}; | ||
export declare type SceneGraphObjectProperties = { | ||
@@ -39,3 +47,3 @@ object: Object3D; | ||
}; | ||
export declare type Object3DInstanceProperties = HierarchicalObjectProperties & LayerableObjectProperties & TransformableObjectProperties & ViewportAwareObjectProperties & { | ||
export declare type Object3DInstanceProperties = SceneGraphObjectProperties & LayerableObjectProperties & TransformableObjectProperties & ViewportAwareObjectProperties & DisposableObjectProperties & { | ||
castShadow?: boolean; | ||
@@ -46,2 +54,3 @@ receiveShadow?: boolean; | ||
visible?: boolean; | ||
userData?: Record<string, any>; | ||
}; | ||
@@ -74,2 +83,3 @@ export declare type MeshInstanceProperties = Omit<Object3DInstanceProperties, 'object'> & Omit<InteractiveObjectProperties, 'object'> & { | ||
export declare type OrbitControlsProperties = { | ||
dispose?: boolean; | ||
autoRotate?: boolean; | ||
@@ -115,2 +125,3 @@ autoRotateSpeed?: number; | ||
space?: 'world' | 'local' | undefined; | ||
dispose?: boolean; | ||
}; | ||
@@ -117,0 +128,0 @@ export declare type PassProperties = { |
@@ -5,2 +5,3 @@ import type { Readable, Writable } from 'svelte/store'; | ||
import type { EffectComposer, Pass } from 'three/examples/jsm/postprocessing/EffectComposer'; | ||
import type { DisposableThreeObject } from './components'; | ||
export declare type ThreltePointerEventMap = { | ||
@@ -66,2 +67,21 @@ click: ThreltePointerEvent; | ||
}; | ||
export declare type ThrelteDisposalContext = { | ||
/** | ||
* These objects will be disposed on the next frame. | ||
*/ | ||
disposableObjects: Set<DisposableThreeObject>; | ||
/** | ||
* Adds a disposable object and all its disposable properties | ||
* to disposalCtx.disposableObjects which will be disposed on | ||
* the next frame. | ||
* | ||
* @param object | ||
* @returns | ||
*/ | ||
addDisposableObject: (object?: DisposableThreeObject) => void; | ||
/** | ||
* Disposes all disposable objects and clears the Set | ||
*/ | ||
dispose: () => void; | ||
}; | ||
export declare type ThrelteAudioContext = { | ||
@@ -73,2 +93,3 @@ audioListeners: Map<string, AudioListener>; | ||
}; | ||
export declare type ThrelteDisposeContext = Writable<boolean>; | ||
export declare type ThrelteUseFrame = { | ||
@@ -75,0 +96,0 @@ stop: () => void; |
{ | ||
"name": "@threlte/core", | ||
"version": "4.1.3", | ||
"version": "4.2.0", | ||
"author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
215423
144
3084