The Display
class is a cosy boilerplate for creating a three.js <canvas>
and dealing with the init, resize and frame event‑loop.
It makes it much easier to deal with browser resizes and the question of how the dimension of the canvas actually is and should be.
If you want the canvas to fill the whole window (aka 'fullscreen'), you don't need to
set extra css styles for it, all what you need is to give the canvas element a
resize_to attribute: <canvas resize-to="window">
The resize-to attribute also understands fullscreen
as an alternative to window
.
However, it is also possible to simply specify a document query selector, in which case the canvas element will always be as large as the element addressed by the selector.
But it also works completely without resize-to !
TODO time helpers, chronometer
TODO eventized class
<canvas id="twopoint5d" resize-to="window"></canvas>
const canvasElement = document.getElementById( "twopoint5d" );
const display = new Display( canvasElement );
let camera, scene, renderer;
display.on({
init ({ renderer, width, height }) {
camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
}
resize ({ width, height }) {
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
frame ({ renderer }) {
renderer.render( scene, camera );
}
})
display.start()
domElementOrRenderer : HTMLElement | WebGLRenderer - The constructor normally expects the canvas element as first parameter.
Alternatively, any other element can be used. In this case the canvas is automatically generated and placed below the specified element in the dom. In this case the size of the canvas depends on the size of the container. If for some reason the container does not have its own size, the canvas simply uses its default size.
You don't really need to worry about this, in most cases the canvas will behave exactly as you expect ✨
This behavior is shown in the example multiple displays.
TODO init: canvas vs. dom-el, vs webglrenderer
TODO css classes: display3__Display, display3__fullscreen, display3__Container
options : object - optional options object that can hold every valid argument from THREE.WebGLRenderer (except the canvas parameter, it will be simply ignored). In addition, there are also the following options:
option | type | description |
---|---|---|
resizeTo | (display: Display) => [width: number, height: number] |
optional callback - if specified, this function is called on each frame and the result is used to update the dimension of the canvas |
resizeToElement | HTMLElement |
normally the canvas or the container element is used for (re)sizing. with this you can explicitly set the reference element. can be very helpful if you create the canvas e.g. in a shadow-dom, but want to use the web-component element from the parent dom as reference for the size |
resizeToAttributeEl | HTMLElement |
the element where a resize-to attribute is listened for. this is by default the canvas itself |
styleSheetRoot | HTMLElement or ShadowRoot |
where to install the stylesheets. this is by default the document.head , but can of course also be a shadow-dom root |
The following parameters for the WebGLRenderer are set as default unless otherwise specified:
parameter | default |
---|---|
precision | highp |
preserveDrawingBuffer | false |
powerPreference | high-performance |
stencil | false |
alpha | true |
antialias | true |
.width : number - width of the canvas
.height : number - height of the canvas
.frameNo : number - the current frame number. starts at 0
.resizeToElement : HTMLElement | undefined - the element which is taken as reference for the dimension of the canvas
.resizeToCallback : (display: Display) => [width: number, height: number] | undefined - if specified, this function is called on each frame and the result is used to update the dimension of the canvas
.renderer : THREE.WebGLRenderer - the renderer instance
.now : number - The current time in seconds. starts at 0. 0 is the time at which the display is instantiated. time does not elapse until the display has been started with .start()
. at the beginning of an animation frame the time is updated. within a frame the time remains unchanged.
.deltaTime : number - The time that has elapsed since the previous frame and the current frame time. Note that the pause times are subtracted here - so it is the time elapsed during the active phases.
.pause : boolean - the pause status. readable but also settable. note a paused display freezes the time and will never emit a frame event. this is also the reason why the deltaTime
does not continue to tick. only again when the pause is ended.
.pixelRatio : number - the current device pixel ratio. is also read by the .resize() method.
.resize() - todo
.renderFrame(now?: number) - todo
.start(beforeStartCallback?: function) : Promise<Display> - todo
.stop() - todo
.dispose() - todo
.getEventArgs(): object - todo
All methods from @spearwolf/eventize are available
Alle events bekommen die argumente von getEventArgs()
init - todo
start - todo
resize - todo
frame - todo
restart - todo
pause - todo
dispose - todo
⚠️ NOTE(2022-03-15): all states and transitions from the diagram are implemented - except the element-is-inside-viewport check - the feature hasn't been built yet and actually hasn't been thought through to the end of whether it's needed at all.