Quellcode durchsuchen

Add ThreeViewer.setRenderSize

master
Palash Bansal vor 2 Jahren
Ursprung
Commit
cb9c6d87e5
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden
2 geänderte Dateien mit 114 neuen und 7 gelöschten Zeilen
  1. 15
    4
      README.md
  2. 99
    3
      src/viewer/ThreeViewer.ts

+ 15
- 4
README.md Datei anzeigen

@@ -1162,10 +1162,13 @@ const viewer = new ThreeViewer({
// container: document.getElementById('mcontainer'),
// container: document.body,

// Set the render scale to render at device resolution
renderScale: window.devicePixelRatio,
// Set the render scale to render at device resolution and clamp to max 2.
renderScale: 'auto',
// or Set the render scale to render at device resolution
// renderScale: window.devicePixelRatio,
// modify the screen shader: See ScreenPass and ScreenPass.glsl for more details
screenShader: `diffuseColor = diffuseColor * 2.0;`,
// Add TonemapPlugin
tonemap: true,
// Use MSAA(anti-aliasing)
@@ -1390,8 +1393,14 @@ import {ThreeViewer} from 'threepipe'

const viewer = new ThreeViewer({...})

// Set size
// Set the final render size directly and fit in container based on mode.
viewer.setRenderSize({width: 800, height: 600}, 'cover')

// Set size of the canvas
viewer.setSize({width: 800, height: 600})
// Set the render scale
viewer.renderManager.renderScale = Math.min(window.devicePixelRatio, 2)


// Traverse scene objects
viewer.traverseSceneObjects((object) => {
@@ -1417,7 +1426,9 @@ viewer.dispose()

```

[`viewer.setSize`](https://threepipe.org/docs/classes/ThreeViewer.html#setSize) - Sets the size of the canvas and updates the renderer and the camera. If no width/height is passed, canvas is set to 100% of the container.
[`viewer.setRenderSize`](https://threepipe.org/docs/classes/ThreeViewer.html#setRenderSize) - Sets the rendering resolution and fits the canvas in container based on the mode. The modes are `cover`, `contain`, `fill`, `scale-down` and `none`. The canvas size and render scale is calculated automatically to match the render render.

[`viewer.setSize`](https://threepipe.org/docs/classes/ThreeViewer.html#setSize) - Sets the size of the canvas and updates the renderer and the camera. If no width/height is passed, canvas is set to 100% of the container.

[`viewer.traverseSceneObjects`](https://threepipe.org/docs/classes/ThreeViewer.html#traverseSceneObjects) - Loop through all the objects in the scene model root hierarchy and calls the callback function with each object.


+ 99
- 3
src/viewer/ThreeViewer.ts Datei anzeigen

@@ -20,7 +20,8 @@ import {
IObjectProcessor,
ITexture,
PerspectiveCamera2,
RootScene, TCameraControlsMode,
RootScene,
TCameraControlsMode,
} from '../core'
import {ViewerRenderManager} from './ViewerRenderManager'
import {
@@ -815,7 +816,11 @@ export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes

/**
* Set size of the canvas and update the renderer.
* If no width/height is passed, canvas is set to 100% of the container.
* If no size or width/height is passed, canvas is set to 100% of the container.
*
* See also {@link ThreeViewer.setRenderSize} to set the size of the render target by automatically calculating the renderScale and fitting in container.
*
* Note: Apps using this should ideally set `max-width: 100%` for the canvas in css.
* @param size
*/
setSize(size?: {width?: number, height?: number}) {
@@ -826,6 +831,98 @@ export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes
this.resize()
}

// todo make an example for this.
// todo make a constructor parameter for renderSize
// todo make getRenderSize or get renderSize
/**
* Set the render size of the viewer to fit in the container according to the specified mode, maintaining aspect ratio.
* Changes the renderScale accordingly.
* Note: the canvas needs to be centered in the container to work properly, this can be done with the following css on the container:
* ```css
* display: flex;
* justify-content: center;
* align-items: center;
* ```
* or in js:
* ```js
* viewer.container.style.display = 'flex';
* viewer.container.style.justifyContent = 'center';
* viewer.container.style.alignItems = 'center';
* ```
* Modes:
* 'contain': The canvas is scaled to fit within the container while maintaining its aspect ratio. The canvas will be fully visible, but there may be empty space around it.
* 'cover': The canvas is scaled to fill the entire container while maintaining its aspect ratio. Part of the canvas may be clipped to fit the container.
* 'fill': The canvas is stretched to completely fill the container, ignoring its aspect ratio.
* 'scale-down': The canvas is scaled down to fit within the container while maintaining its aspect ratio, but it won't be scaled up if it's smaller than the container.
* 'none': container size is ignored, but devicePixelRatio is used
* @param size - The size to set the render to. The canvas will render to this size.
* @param mode - 'contain', 'cover', 'fill', 'scale-down' or 'none'. Default is 'contain'.
* @param devicePixelRatio - typically set to `window.devicePixelRatio`, or `Math.min(1.5, window.devicePixelRatio)` for performance. Use this only when size is derived from dom elements.
* @param containerSize - (optional) The size of the container, if not passed, the bounding client rect of the container is used.
*/
setRenderSize(size: {width: number, height: number},
mode: 'contain' | 'cover' | 'fill' | 'scale-down' | 'none' = 'contain',
devicePixelRatio = 1,
containerSize?: {width: number, height: number}) {
// todo what about container resize?
const containerRect = containerSize || this.container.getBoundingClientRect()
const containerHeight = containerRect.height
const containerWidth = containerRect.width
const width = size.width
const height = size.height
const aspect = width / height
const containerAspect = containerWidth / containerHeight
const dpr = devicePixelRatio

let renderWidth, renderHeight

switch (mode) {
case 'contain':
if (containerAspect > aspect) {
renderWidth = containerHeight * aspect
renderHeight = containerHeight
} else {
renderWidth = containerWidth
renderHeight = containerWidth / aspect
}
break
case 'cover':
if (containerAspect > aspect) {
renderWidth = containerWidth
renderHeight = containerWidth / aspect
} else {
renderWidth = containerHeight * aspect
renderHeight = containerHeight
}
break
case 'fill':
renderWidth = containerWidth
renderHeight = containerHeight
break
case 'scale-down':
if (width < containerWidth && height < containerHeight) {
renderWidth = width
renderHeight = height
} else if (containerAspect > aspect) {
renderWidth = containerHeight * aspect
renderHeight = containerHeight
} else {
renderWidth = containerWidth
renderHeight = containerWidth / aspect
}
break
case 'none':
renderWidth = width
renderHeight = height
break
default:
throw new Error(`Invalid mode: ${mode}`)
}

this.setSize({width: renderWidth, height: renderHeight})
this.renderManager.renderScale = dpr * height / renderHeight
}

/**
* Traverse all objects in scene model root.
* @param callback
@@ -851,7 +948,6 @@ export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes
return imported
}


/**
* Serialize all the plugins and their settings to save or create presets. Used in {@link toJSON}.
* @param meta - The meta object.

Laden…
Abbrechen
Speichern