| dist | dist | ||||
| lib | |||||
| docs | docs | ||||
| /index.html | /index.html | ||||
| examples/**/*.js | examples/**/*.js |
| .replaceAll(` from '../`, ` from '${rootPath+examplePath}`) | .replaceAll(` from '../`, ` from '${rootPath+examplePath}`) | ||||
| } | } | ||||
| setupCodePreview( | setupCodePreview( | ||||
| document.getElementById('canvas-container') || document.querySelector('.code-preview-container') || document.body, | |||||
| document.querySelector('.code-preview-container') || document.getElementById('canvas-container') || document.body, | |||||
| scripts, | scripts, | ||||
| scripts.map(s=>s.textContent ? 'js' : s.split('.').pop()), // title | scripts.map(s=>s.textContent ? 'js' : s.split('.').pop()), // title | ||||
| scripts.map(s=>(typeof s === 'string' && s.endsWith('.js')) ? s : (codePath+examplePath+window.location.pathname.split('/examples/').pop().replace('index.html', '')+(s.textContent ? 'index.html' : s))), // todo: github link | scripts.map(s=>(typeof s === 'string' && s.endsWith('.js')) ? s : (codePath+examplePath+window.location.pathname.split('/examples/').pop().replace('index.html', '')+(s.textContent ? 'index.html' : s))), // todo: github link |
| <li><a href="./camera-view-plugin/">Camera View (Animation) Plugin </a></li> | <li><a href="./camera-view-plugin/">Camera View (Animation) Plugin </a></li> | ||||
| <li><a href="./dropzone-plugin/">Dropzone (Drag & Drop) Plugin </a></li> | <li><a href="./dropzone-plugin/">Dropzone (Drag & Drop) Plugin </a></li> | ||||
| <li><a href="./fullscreen-plugin/">FullScreen Plugin </a></li> | <li><a href="./fullscreen-plugin/">FullScreen Plugin </a></li> | ||||
| <li><a href="./geometry-generator-plugin/">Geometry Generator Plugin </a></li> | |||||
| </ul> | </ul> | ||||
| <h2 class="category">Import</h2> | <h2 class="category">Import</h2> | ||||
| <ul> | <ul> |
| "rollup-plugin-license": "^3.0.1", | "rollup-plugin-license": "^3.0.1", | ||||
| "rollup-plugin-glsl": "^1.3.0", | "rollup-plugin-glsl": "^1.3.0", | ||||
| "rollup-plugin-postcss": "^4.0.2", | "rollup-plugin-postcss": "^4.0.2", | ||||
| "stats.js": "^0.17.0", | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2018/package.tgz", | "three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2018/package.tgz", | ||||
| "tslib": "^2.5.0", | "tslib": "^2.5.0", | ||||
| "typedoc": "^0.24.7", | "typedoc": "^0.24.7", | ||||
| "typescript": "^5.0.4", | "typescript": "^5.0.4", | ||||
| "typescript-plugin-css-modules": "^5.0.1", | "typescript-plugin-css-modules": "^5.0.1", | ||||
| "uiconfig.js": "^0.0.9", | |||||
| "@rollup/plugin-replace": "^5.0.2", | "@rollup/plugin-replace": "^5.0.2", | ||||
| "popmotion": "^11.0.5" | "popmotion": "^11.0.5" | ||||
| }, | }, | ||||
| "dependencies": { | "dependencies": { | ||||
| "stats.js": "^0.17.0", | |||||
| "uiconfig.js": "^0.0.9", | |||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1018/package.tgz", | "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1018/package.tgz", | ||||
| "@types/webxr": "^0.5.1", | "@types/webxr": "^0.5.1", | ||||
| "@types/wicg-file-system-access": "^2020.9.5", | "@types/wicg-file-system-access": "^2020.9.5", | ||||
| "ts-browser-helpers": "^0.8.0" | |||||
| "ts-browser-helpers": "^0.9.0" | |||||
| }, | }, | ||||
| "//": { | "//": { | ||||
| "dependencies": { | "dependencies": { |
| storage?: Cache | Storage | boolean | storage?: Cache | Storage | boolean | ||||
| } | } | ||||
| export type AddAssetOptions = AddObjectOptions & { | |||||
| export interface AddAssetOptions extends AddObjectOptions{ | |||||
| /** | /** | ||||
| * Automatically set any loaded HDR, EXR file as the scene environment map | * Automatically set any loaded HDR, EXR file as the scene environment map | ||||
| * @default true | * @default true |
| import {BaseEvent, EventDispatcher, LoadingManager, Object3D} from 'three' | import {BaseEvent, EventDispatcher, LoadingManager, Object3D} from 'three' | ||||
| import {AnyOptions, IDisposable} from 'ts-browser-helpers' | |||||
| import {IDisposable} from 'ts-browser-helpers' | |||||
| import {IAsset, IFile} from './IAsset' | import {IAsset, IFile} from './IAsset' | ||||
| import {ILoader} from './IImporter' | import {ILoader} from './IImporter' | ||||
| import {ICamera, IMaterial, IObject3D, ITexture} from '../core' | import {ICamera, IMaterial, IObject3D, ITexture} from '../core' | ||||
| __sourceBlob?: IFile | __sourceBlob?: IFile | ||||
| } | } | ||||
| export type ProcessRawOptions = { | |||||
| export interface ProcessRawOptions { | |||||
| /** | /** | ||||
| * default = true, toggle to control the processing of the raw objects in the proecssRaw method | * default = true, toggle to control the processing of the raw objects in the proecssRaw method | ||||
| */ | */ | ||||
| * @deprecated use processRaw instead | * @deprecated use processRaw instead | ||||
| */ | */ | ||||
| processImported?: boolean, // same as processRaw | processImported?: boolean, // same as processRaw | ||||
| } & AnyOptions | |||||
| [key: string]: any | |||||
| } | |||||
| export interface LoadFileOptions { | export interface LoadFileOptions { | ||||
| fileHandler?: any, // custom {@link ILoader} for the file | fileHandler?: any, // custom {@link ILoader} for the file | ||||
| rootPath?: string, // internal use | rootPath?: string, // internal use | ||||
| } | } | ||||
| export type ImportFilesOptions = ProcessRawOptions & LoadFileOptions & {allowedExtensions?: string[]} | |||||
| export interface ImportFilesOptions extends ProcessRawOptions, LoadFileOptions {allowedExtensions?: string[]} | |||||
| export type ImportAssetOptions = { | |||||
| export interface ImportAssetOptions extends ProcessRawOptions, LoadFileOptions { | |||||
| /** | /** | ||||
| * Default = false. If true, the asset will be imported again on subsequent calls, even if it is already imported. | * Default = false. If true, the asset will be imported again on subsequent calls, even if it is already imported. | ||||
| */ | */ | ||||
| * Pass a custom file to use for the import. This will be used in the importer, and nothing will be fetched from the path | * Pass a custom file to use for the import. This will be used in the importer, and nothing will be fetched from the path | ||||
| */ | */ | ||||
| importedFile?: IFile, | importedFile?: IFile, | ||||
| } & ProcessRawOptions & LoadFileOptions & AnyOptions | |||||
| } | |||||
| export type IAssetImporterEventTypes = 'onLoad' | 'onProgress' | 'onStop' | 'onError' | 'onStart' | 'loaderCreate' | 'importFile' | 'importFiles' | 'processRaw' | 'processRawStart' | export type IAssetImporterEventTypes = 'onLoad' | 'onProgress' | 'onStop' | 'onError' | 'onStart' | 'loaderCreate' | 'importFile' | 'importFiles' | 'processRaw' | 'processRawStart' | ||||
| export interface IAssetImporter extends EventDispatcher<BaseEvent, IAssetImporterEventTypes>, IDisposable { | export interface IAssetImporter extends EventDispatcher<BaseEvent, IAssetImporterEventTypes>, IDisposable { |
| */ | */ | ||||
| position: Vector3, | position: Vector3, | ||||
| // todo: make disable/enable functions with key like in FrameFadePlugin | |||||
| interactionsEnabled: boolean; | |||||
| readonly interactionsEnabled: boolean; | |||||
| setInteractions(enabled: boolean, by: string): void; | |||||
| /** | /** | ||||
| * Check whether user can interact with this camera. | * Check whether user can interact with this camera. | ||||
| * Interactions can be enabled/disabled in a variety of ways, | * Interactions can be enabled/disabled in a variety of ways, | ||||
| * like {@link interactionsEnabled}, {@link controlsMode}, {@link isMainCamera} property | |||||
| * like {@link setInteractions}, {@link controlsMode}, {@link isMainCamera} property | |||||
| */ | */ | ||||
| readonly canUserInteract: boolean; | readonly canUserInteract: boolean; | ||||
| import {BufferGeometry, Event, NormalBufferAttributes, NormalOrGLBufferAttributes} from 'three' | |||||
| import {BufferGeometry, Event, NormalBufferAttributes, NormalOrGLBufferAttributes, Vector3} from 'three' | |||||
| import {IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' | import {IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' | ||||
| import {AnyOptions} from 'ts-browser-helpers' | import {AnyOptions} from 'ts-browser-helpers' | ||||
| import {IObject3D} from './IObject' | import {IObject3D} from './IObject' | ||||
| refreshUi(): void; | refreshUi(): void; | ||||
| uiConfig?: UiObjectConfig | uiConfig?: UiObjectConfig | ||||
| appliedMeshes: Set<IObject3D> | appliedMeshes: Set<IObject3D> | ||||
| center(offset?: Vector3, keepWorldPosition?: boolean): this | |||||
| // Note: for userData: add _ in front of for private use, which is preserved while cloning but not serialisation, and __ for private use, which is not preserved while cloning and serialisation | // Note: for userData: add _ in front of for private use, which is preserved while cloning but not serialisation, and __ for private use, which is not preserved while cloning and serialisation | ||||
| userData: IGeometryUserData | userData: IGeometryUserData |
| autoScaleRadius?: number | autoScaleRadius?: number | ||||
| autoScaled?: boolean | autoScaled?: boolean | ||||
| geometriesCentered?: boolean | |||||
| /** | /** | ||||
| * should this object be taken into account when calculating bounding box, default true | * should this object be taken into account when calculating bounding box, default true | ||||
| parent: IObject3D | null | parent: IObject3D | null | ||||
| children: IObject3D[] | children: IObject3D[] | ||||
| // endregion | // endregion | ||||
| } | } |
| * @default false | * @default false | ||||
| */ | */ | ||||
| autoCenter?: boolean, | autoCenter?: boolean, | ||||
| /** | |||||
| * Automatically center the geometries(pivots) in the object hierarchy before adding. | |||||
| * @default false | |||||
| */ | |||||
| centerGeometries?: boolean, | |||||
| /** | |||||
| * This centers the geometry while keeping the world position, i.e the mesh(Object3D) positions will change. | |||||
| * {@link centerGeometries} must be true for this to work. | |||||
| * @default true | |||||
| */ | |||||
| centerGeometriesKeepPosition?: boolean, | |||||
| /** | /** | ||||
| * Add a license to the object | * Add a license to the object | ||||
| */ | */ | ||||
| autoScale?: boolean | autoScale?: boolean | ||||
| /** | /** | ||||
| * Radius to use for {@link autoScale} | * Radius to use for {@link autoScale} | ||||
| * {@link autoScale} must be true for this to work. | |||||
| * @default 2 | * @default 2 | ||||
| */ | */ | ||||
| autoScaleRadius?: number | autoScaleRadius?: number |
| // const ae = this._canvas.addEventListener | // const ae = this._canvas.addEventListener | ||||
| // todo: this breaks UI. | |||||
| // todo: this breaks tweakpane UI. | |||||
| // this._canvas.addEventListener = (type: string, listener: any, options1: any) => { // see https://github.com/mrdoob/three.js/pull/19782 | // this._canvas.addEventListener = (type: string, listener: any, options1: any) => { // see https://github.com/mrdoob/three.js/pull/19782 | ||||
| // ae(type, listener, type === 'wheel' && typeof options1 !== 'boolean' ? { | // ae(type, listener, type === 'wheel' && typeof options1 !== 'boolean' ? { | ||||
| // ...typeof options1 === 'object' ? options1 : {}, | // ...typeof options1 === 'object' ? options1 : {}, | ||||
| // @serialize('camOptions') //todo handle deserialization of this | // @serialize('camOptions') //todo handle deserialization of this | ||||
| // region interactionsEnabled | // region interactionsEnabled | ||||
| private _interactionsEnabled = true | |||||
| get canUserInteract() { | |||||
| return this._interactionsEnabled && this.isMainCamera && this.controlsMode !== '' | |||||
| } | |||||
| // private _interactionsEnabled = true | |||||
| // | |||||
| // get interactionsEnabled(): boolean { | |||||
| // return this._interactionsEnabled | |||||
| // } | |||||
| // | |||||
| // set interactionsEnabled(value: boolean) { | |||||
| // if (this._interactionsEnabled !== value) { | |||||
| // this._interactionsEnabled = value | |||||
| // this.refreshCameraControls(true) | |||||
| // } | |||||
| // } | |||||
| private _interactionsDisabledBy = new Set<string>() | |||||
| get interactionsEnabled(): boolean { | get interactionsEnabled(): boolean { | ||||
| return this._interactionsEnabled | |||||
| return this._interactionsDisabledBy.size === 0 | |||||
| } | } | ||||
| set interactionsEnabled(value: boolean) { | |||||
| if (this._interactionsEnabled !== value) { | |||||
| this._interactionsEnabled = value | |||||
| this.refreshCameraControls(true) | |||||
| setInteractions(enabled: boolean, by: string): void { | |||||
| const size = this._interactionsDisabledBy.size | |||||
| if (enabled) { | |||||
| this._interactionsDisabledBy.delete(by) | |||||
| } else { | |||||
| this._interactionsDisabledBy.add(by) | |||||
| } | } | ||||
| if (size !== this._interactionsDisabledBy.size) this.refreshCameraControls(true) | |||||
| } | |||||
| get canUserInteract() { | |||||
| return this.interactionsEnabled && this.isMainCamera && this.controlsMode !== '' | |||||
| } | } | ||||
| // endregion | // endregion |
| superDispose.call(this) | superDispose.call(this) | ||||
| }, | }, | ||||
| upgradeGeometry: upgradeGeometry, | upgradeGeometry: upgradeGeometry, | ||||
| center: (superCenter: BufferGeometry['center']): IGeometry['center'] => | |||||
| function(this: IGeometry, offset?: Vector3, keepWorldPosition = false): IGeometry { | |||||
| if (keepWorldPosition) { | |||||
| offset = offset ? offset.clone() : new Vector3() | |||||
| superCenter.call(this, offset) | |||||
| offset.negate() | |||||
| const meshes = this.appliedMeshes | |||||
| for (const m of meshes) { | |||||
| m.updateMatrix() | |||||
| m.position.copy(offset).applyMatrix4(m.matrix) | |||||
| m.setDirty() | |||||
| } | |||||
| } else { | |||||
| superCenter.call(this, offset) | |||||
| } | |||||
| this.setDirty() | |||||
| return this | |||||
| }, | |||||
| makeUiConfig: function(this: IGeometry): UiObjectConfig { | makeUiConfig: function(this: IGeometry): UiObjectConfig { | ||||
| if (this.uiConfig) return this.uiConfig | if (this.uiConfig) return this.uiConfig | ||||
| return { | return { | ||||
| label: 'Center Geometry', | label: 'Center Geometry', | ||||
| value: () => { | value: () => { | ||||
| this.center() | this.center() | ||||
| this.setDirty() | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| type: 'button', | type: 'button', | ||||
| label: 'Center Geometry (keep position)', | label: 'Center Geometry (keep position)', | ||||
| value: () => { | value: () => { | ||||
| const offset = new Vector3() | |||||
| this.center(offset) | |||||
| const meshes = this.appliedMeshes | |||||
| meshes.forEach(m=>{ | |||||
| m.position.sub(offset) | |||||
| m.setDirty && m.setDirty() | |||||
| }) | |||||
| this.center(undefined, true) | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| this.assetType = 'geometry' | this.assetType = 'geometry' | ||||
| this.dispose = iGeometryCommons.dispose(this.dispose) | this.dispose = iGeometryCommons.dispose(this.dispose) | ||||
| this.center = iGeometryCommons.center(this.center) | |||||
| if (!this.setDirty) this.setDirty = iGeometryCommons.setDirty | if (!this.setDirty) this.setDirty = iGeometryCommons.setDirty | ||||
| if (!this.refreshUi) this.refreshUi = iGeometryCommons.refreshUi | if (!this.refreshUi) this.refreshUi = iGeometryCommons.refreshUi |
| } | } | ||||
| /** | /** | ||||
| Load model root scene exported to GLTF format. Used internally by {@link ThreeViewer.addSceneObject}. | |||||
| * Load model root scene exported to GLTF format. Used internally by {@link ThreeViewer.addSceneObject}. | |||||
| * @param obj | * @param obj | ||||
| * @param options | * @param options | ||||
| */ | */ | ||||
| .map(c=>this.addObject(c, {...options, clearSceneObjects: false, disposeSceneObjects: false})) | .map(c=>this.addObject(c, {...options, clearSceneObjects: false, disposeSceneObjects: false})) | ||||
| } | } | ||||
| private _addObject3D(model: IObject3D|null, {autoCenter = false, autoScale = false, autoScaleRadius = 2., addToRoot = false, license}: AddObjectOptions = {}): void { | |||||
| private _addObject3D(model: IObject3D|null, {autoCenter = false, centerGeometries = false, centerGeometriesKeepPosition = true, autoScale = false, autoScaleRadius = 2., addToRoot = false, license}: AddObjectOptions = {}): void { | |||||
| const obj = model | const obj = model | ||||
| if (!obj) { | if (!obj) { | ||||
| console.error('Invalid object, cannot add to scene.') | console.error('Invalid object, cannot add to scene.') | ||||
| } else { | } else { | ||||
| obj.userData.autoScaled = true // mark as auto-scaled, so that autoScale is not called again when file is reloaded. | obj.userData.autoScaled = true // mark as auto-scaled, so that autoScale is not called again when file is reloaded. | ||||
| } | } | ||||
| if (centerGeometries && !obj.userData.geometriesCentered) { | |||||
| obj.traverse((o)=>{ | |||||
| if (o.geometry) o.geometry.center(undefined, centerGeometriesKeepPosition) | |||||
| }) | |||||
| obj.userData.geometriesCentered = true | |||||
| } else { | |||||
| obj.userData.geometriesCentered = true // mark as centered, so that geometry center is not called again when file is reloaded. | |||||
| } | |||||
| if (license) obj.userData.license = [obj.userData.license, license].filter(v=>v).join(', ') | if (license) obj.userData.license = [obj.userData.license, license].filter(v=>v).join(', ') | ||||
| private _v1 = new Vector3() | private _v1 = new Vector3() | ||||
| private _v2 = new Vector3() | private _v2 = new Vector3() | ||||
| /** | |||||
| * For Programmatically toggling autoNearFar. This property is not supposed to be in the UI or serialized. | |||||
| * Use camera.userData.autoNearFar for UI and serialization | |||||
| * This is used in PickingPlugin | |||||
| * autoNearFar will still be disabled if this is true and camera.userData.autoNearFar is false | |||||
| */ | |||||
| autoNearFarEnabled = true | |||||
| /** | /** | ||||
| * Refreshes the scene active camera near far values, based on the scene bounding box. | * Refreshes the scene active camera near far values, based on the scene bounding box. | ||||
| * This is called automatically every time the camera is updated. | * This is called automatically every time the camera is updated. | ||||
| refreshActiveCameraNearFar(): void { | refreshActiveCameraNearFar(): void { | ||||
| const camera = this.mainCamera as ICamera | const camera = this.mainCamera as ICamera | ||||
| if (!camera) return | if (!camera) return | ||||
| if (camera.userData.autoNearFar === false) { | |||||
| if (!this.autoNearFarEnabled || camera.userData.autoNearFar === false) { | |||||
| camera.near = camera.userData.minNearPlane ?? 0.5 | camera.near = camera.userData.minNearPlane ?? 0.5 | ||||
| camera.far = camera.userData.maxFarPlane ?? 1000 | camera.far = camera.userData.maxFarPlane ?? 1000 | ||||
| return | return |
| onAdded(viewer: ThreeViewer): void { | onAdded(viewer: ThreeViewer): void { | ||||
| super.onAdded(viewer) | super.onAdded(viewer) | ||||
| let interactionsDisabled = false // we need this because interactionsEnabled is also set in PickingPlugin | |||||
| // todo: move to PopmotionPlugin | // todo: move to PopmotionPlugin | ||||
| // todo: remove event listener | // todo: remove event listener | ||||
| viewer.addEventListener('preFrame', (_: any)=>{ | viewer.addEventListener('preFrame', (_: any)=>{ | ||||
| if (/* this.seekOnScroll || */ this._animating) { | |||||
| if (this._viewer!.scene.mainCamera.interactionsEnabled) { | |||||
| this._viewer!.scene.mainCamera.interactionsEnabled = false | |||||
| interactionsDisabled = true | |||||
| // console.log(interactionsDisabled) | |||||
| } | |||||
| } else if (interactionsDisabled) { | |||||
| this._viewer!.scene.mainCamera.interactionsEnabled = true | |||||
| interactionsDisabled = false | |||||
| // console.log(interactionsDisabled) | |||||
| } | |||||
| // console.log(ev.deltaTime) | // console.log(ev.deltaTime) | ||||
| // this._updaters.forEach(u=>{ | // this._updaters.forEach(u=>{ | ||||
| this._currentView = view | this._currentView = view | ||||
| this._animating = true | this._animating = true | ||||
| this._viewer?.scene.mainCamera.setInteractions(false, CameraViewPlugin.PluginType) // todo: also for seekOnScroll | |||||
| this.dispatchEvent({type: 'startViewChange', view}) | this.dispatchEvent({type: 'startViewChange', view}) | ||||
| const popmotion = this._viewer?.getPlugin(PopmotionPlugin) | const popmotion = this._viewer?.getPlugin(PopmotionPlugin) | ||||
| if (throwOnStop) throw e | if (throwOnStop) throw e | ||||
| }) | }) | ||||
| this._viewer?.scene.mainCamera.setInteractions(true, CameraViewPlugin.PluginType) | |||||
| this._animating = false | this._animating = false | ||||
| this._viewer?.setDirty() | this._viewer?.setDirty() |
| import {IPassID, IPipelinePass} from '../../postprocessing' | import {IPassID, IPipelinePass} from '../../postprocessing' | ||||
| import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' | import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' | ||||
| import {AnyFunction, serialize} from 'ts-browser-helpers' | |||||
| import {serialize, wrapThisFunction} from 'ts-browser-helpers' | |||||
| import {SerializationMetaType} from '../../utils' | import {SerializationMetaType} from '../../utils' | ||||
| import {uiConfig, uiToggle} from 'uiconfig.js' | import {uiConfig, uiToggle} from 'uiconfig.js' | ||||
| } | } | ||||
| } | } | ||||
| function wrapThisFunction<T extends AnyFunction, T2>(f1: ()=>void, f2?: T): T { | |||||
| return function(this: T2, ...args: Parameters<T>) { | |||||
| f1() | |||||
| return f2 && f2.call(this, ...args) | |||||
| } as T | |||||
| } |
| @serialize() autoImport = true | @serialize() autoImport = true | ||||
| /** | /** | ||||
| * Automatically add dropped and imported assets to the scene. | * Automatically add dropped and imported assets to the scene. | ||||
| Works only if {@link autoImport} is true. | |||||
| * Works only if {@link autoImport} is true. | |||||
| */ | */ | ||||
| @uiToggle() @serialize() autoAdd = true | @uiToggle() @serialize() autoAdd = true | ||||
| importConfig: true, | importConfig: true, | ||||
| autoScale: true, | autoScale: true, | ||||
| autoScaleRadius: 2, | autoScaleRadius: 2, | ||||
| centerGeometries: false, // in the whole hierarchy | |||||
| centerGeometriesKeepPosition: true, // this centers while keeping world position | |||||
| license: '', | license: '', | ||||
| clearSceneObjects: false, | clearSceneObjects: false, | ||||
| disposeSceneObjects: false, | disposeSceneObjects: false, |
| throttleUpdate = 60 // throttle to 60 updates per second (implemented in OrbitControls.js.update() method) | throttleUpdate = 60 // throttle to 60 updates per second (implemented in OrbitControls.js.update() method) | ||||
| // todo add to three-ts-types | |||||
| stopDamping!: () => void | |||||
| } | } |
| const scale = bbox.getBoundingSphere(new Sphere()).radius | const scale = bbox.getBoundingSphere(new Sphere()).radius | ||||
| this.scale.setScalar(scale * this.boundingScaleMultiplier) | this.scale.setScalar(scale * this.boundingScaleMultiplier) | ||||
| this.setVisible(true) | this.setVisible(true) | ||||
| } else { | } else { | ||||
| this.setVisible(false) | this.setVisible(false) | ||||
| } | } |
| export type {IEvent, IEventDispatcher} from 'ts-browser-helpers' | export type {IEvent, IEventDispatcher} from 'ts-browser-helpers' | ||||
| export type {ImageCanvasOptions} from 'ts-browser-helpers' | export type {ImageCanvasOptions} from 'ts-browser-helpers' | ||||
| export type {AnyFunction, AnyOptions, Class, IDisposable, IJSONSerializable, PartialPick, PartialRecord, StringKeyOf, Fof, ValOrFunc, ValOrArr, ValOrArrOp} from 'ts-browser-helpers' | |||||
| export type {AnyFunction, AnyOptions, Class, IDisposable, IJSONSerializable, PartialPick, PartialRecord, StringKeyOf, Fof, ValOrFunc, ValOrArr, ValOrFuncOp, ValOrArrOp} from 'ts-browser-helpers' | |||||
| export type {Serializer} from 'ts-browser-helpers' | export type {Serializer} from 'ts-browser-helpers' | ||||
| export {PointerDragHelper} from 'ts-browser-helpers' | export {PointerDragHelper} from 'ts-browser-helpers' | ||||
| export {Damper} from 'ts-browser-helpers' | export {Damper} from 'ts-browser-helpers' | ||||
| export {prettyScrollbar} from 'ts-browser-helpers' | export {prettyScrollbar} from 'ts-browser-helpers' | ||||
| export {blobToDataURL, downloadBlob, downloadFile, uploadFile, mobileAndTabletCheck} from 'ts-browser-helpers' | export {blobToDataURL, downloadBlob, downloadFile, uploadFile, mobileAndTabletCheck} from 'ts-browser-helpers' | ||||
| export {LinearToSRGB, SRGBToLinear, colorToDataUrl} from 'ts-browser-helpers' | export {LinearToSRGB, SRGBToLinear, colorToDataUrl} from 'ts-browser-helpers' | ||||
| export {onChange, onChange2, onChange3, serialize, serializable} from 'ts-browser-helpers' | |||||
| export {onChange, onChange2, onChange3, onChangeDispatchEvent, serialize, serializable} from 'ts-browser-helpers' | |||||
| export {aesGcmDecrypt, aesGcmEncrypt} from 'ts-browser-helpers' | export {aesGcmDecrypt, aesGcmEncrypt} from 'ts-browser-helpers' | ||||
| export {verifyPermission, writeFile, getFileHandle, getNewFileHandle, readFile} from 'ts-browser-helpers' | export {verifyPermission, writeFile, getFileHandle, getNewFileHandle, readFile} from 'ts-browser-helpers' | ||||
| export {embedUrlRefs, htmlToCanvas, htmlToPng, htmlToSvg} from 'ts-browser-helpers' | export {embedUrlRefs, htmlToCanvas, htmlToPng, htmlToSvg} from 'ts-browser-helpers' | ||||
| export {imageToCanvas, imageBitmapToBase64, imageUrlToImageData, imageDataToCanvas, isWebpExportSupported, canvasFlipY} from 'ts-browser-helpers' | export {imageToCanvas, imageBitmapToBase64, imageUrlToImageData, imageDataToCanvas, isWebpExportSupported, canvasFlipY} from 'ts-browser-helpers' | ||||
| export {absMax, clearBit, updateBit} from 'ts-browser-helpers' | export {absMax, clearBit, updateBit} from 'ts-browser-helpers' | ||||
| export {includesAll} from 'ts-browser-helpers' | |||||
| export {includesAll, wrapThisFunction, findLastIndex} from 'ts-browser-helpers' | |||||
| export {copyProps, getOrCall, getPropertyDescriptor, isPropertyWritable, safeSetProperty} from 'ts-browser-helpers' | export {copyProps, getOrCall, getPropertyDescriptor, isPropertyWritable, safeSetProperty} from 'ts-browser-helpers' | ||||
| export {deepAccessObject, getKeyByValue, objectHasOwn, objectMap2, objectMap} from 'ts-browser-helpers' | export {deepAccessObject, getKeyByValue, objectHasOwn, objectMap2, objectMap} from 'ts-browser-helpers' | ||||
| export {makeColorSvg, makeTextSvg, makeColorSvgCircle, svgToCanvas, svgToPng} from 'ts-browser-helpers' | export {makeColorSvg, makeTextSvg, makeColorSvgCircle, svgToCanvas, svgToPng} from 'ts-browser-helpers' |
| else this.fromJSON?.(state) | else this.fromJSON?.(state) | ||||
| } | } | ||||
| protected _viewerListeners: PartialRecord<IViewerEventTypes, (e: Event)=>void> = {} | |||||
| protected _viewerListeners: PartialRecord<IViewerEventTypes, (e: IViewerEvent)=>void> = {} | |||||
| protected _onViewerEvent = (e: IViewerEvent)=> { | protected _onViewerEvent = (e: IViewerEvent)=> { | ||||
| const et = e.eType | const et = e.eType | ||||
| et && this._viewerListeners[et]?.(e) | et && this._viewerListeners[et]?.(e) |
| import {Easing} from 'popmotion' | import {Easing} from 'popmotion' | ||||
| import {OrbitControls3} from '../three' | import {OrbitControls3} from '../three' | ||||
| export type IViewerEvent = BaseEvent & { | |||||
| export interface IViewerEvent extends BaseEvent, Partial<IAnimationLoopEvent> { | |||||
| type: '*'|'update'|'preRender'|'postRender'|'preFrame'|'postFrame'|'dispose'|'addPlugin'|'renderEnabled'|'renderDisabled' | type: '*'|'update'|'preRender'|'postRender'|'preFrame'|'postFrame'|'dispose'|'addPlugin'|'renderEnabled'|'renderDisabled' | ||||
| eType?: '*'|'update'|'preRender'|'postRender'|'preFrame'|'postFrame'|'dispose'|'addPlugin'|'renderEnabled'|'renderDisabled' | eType?: '*'|'update'|'preRender'|'postRender'|'preFrame'|'postFrame'|'dispose'|'addPlugin'|'renderEnabled'|'renderDisabled' | ||||
| [p: string]: any | [p: string]: any |