Просмотр исходного кода

Minor type fixes, add keepWorldPosition to IGeometry.center, make interactionsEnabled readonly, add setInteractions function in ICamera, update ts-browser-helpers

master
Palash Bansal 2 лет назад
Родитель
Сommit
4286cfa904
Аккаунт пользователя с таким Email не найден

+ 1
- 0
.gitignore Просмотреть файл

dist dist
lib
docs docs
/index.html /index.html
examples/**/*.js examples/**/*.js

+ 1
- 1
examples/examples-utils/simple-code-preview.mjs Просмотреть файл

.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

+ 1
- 0
examples/index.html Просмотреть файл

<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>

+ 3
- 3
package.json Просмотреть файл

"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": {

+ 1
- 1
src/assetmanager/AssetManager.ts Просмотреть файл

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

+ 8
- 6
src/assetmanager/IAssetImporter.ts Просмотреть файл

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 {

+ 3
- 3
src/core/ICamera.ts Просмотреть файл

*/ */
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;



+ 2
- 1
src/core/IGeometry.ts Просмотреть файл

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

+ 2
- 1
src/core/IObject.ts Просмотреть файл



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


} }

+ 12
- 0
src/core/IScene.ts Просмотреть файл

* @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

+ 27
- 10
src/core/camera/PerspectiveCamera2.ts Просмотреть файл





// 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

+ 20
- 8
src/core/geometry/iGeometryCommons.ts Просмотреть файл

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

+ 19
- 3
src/core/object/RootScene.ts Просмотреть файл

} }


/** /**
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

+ 4
- 14
src/plugins/animation/CameraViewPlugin.ts Просмотреть файл

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()

+ 1
- 8
src/plugins/base/PipelinePassPlugin.ts Просмотреть файл

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
}

+ 3
- 1
src/plugins/interaction/DropzonePlugin.ts Просмотреть файл

@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,

+ 2
- 0
src/three/controls/OrbitControls3.ts Просмотреть файл



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
} }

+ 0
- 1
src/three/utils/SelectionWidget.ts Просмотреть файл

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)
} }

+ 3
- 3
src/utils/browser-helpers.ts Просмотреть файл

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'

+ 1
- 1
src/viewer/AViewerPlugin.ts Просмотреть файл

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)

+ 1
- 1
src/viewer/ThreeViewer.ts Просмотреть файл

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

Загрузка…
Отмена
Сохранить