shimmer-js
v2.3.4
Published
Enhanced glitter for webGL purposes
Downloads
20
Readme
Shimmer
Shimmer extends Glitter
USE CASE
Shimmer is based on components. To be fully functionnal, it needs to have severals events setup.
import { engine, LoaderManager, GLTFLoader } from 'shimmer'
const assets = [
{
name: "texture",
url: "/textures/uv.jpg",
type: "texture"
},
{
name: "object",
url: "/models/object.glb",
type: "object"
}
]
LoaderManager.config = assets
GLTFLoader.draco = { path: '/draco/' }
GLTFLoader.ktx = { path: '/basis/', renderer: webGL.renderer.renderer }
// when client's window is accessible
engine.ready = true
// the canvas or canvas's wrapper element
engine.el = containerWebGL
// set engine's camera with the main experience cameras
engine.camera = webGL.camera
window.addEventListener('pointerdown', engine.pointerdown)
window.addEventListener('pointermove', engine.pointermove)
const obj = LoaderManager.load('test', true)
scene.add(obj)
obj.on('over', () => {
console.log('hover')
})Component's methods and a few utils, are based on internal mechanism defined thanks to those lines.
NB: utils are originally made to be used as standalones. The only utils that are connected to shimmer's mechanisms are for performance benefits.
FILES STRUCTURE
- cameras Defines THREE herited cameras
- component Defines shimmer Component and setup internal structure that supports Components Lifecycles and methods
- utils Defines shimmer utils. Utils are standalone helper functions.
- config Singleton of data used internally to store applications information
- emitter Singleton implementation of emitter used internally to deal with events (for lifecycle, hooks, etc etc)
API
Engine
import { engine } from 'shimmer'
// when window is accessible
engine.ready = trueA singleton that runs the application. Functions needs to be called to allow every features.
set property ready when object client's window is accessible.
Methods
pointerdown (event: Event)- event: user event Required. Needs to be called on pointerdown events
pointermove (event: Event)- event: user event Required. Needs to be called on pointermove events
set el (el: DOMElement)- el: canvas's container Required. Needs to be set before using shimmer
set camera (camera: THREE.Camera)- camera: Camera used on three application Required. Needs to be set before using shimmer
Component
import { Component } from 'shimmer'
const component = new Component({name: 'test'})Abstarct class that heriting from THREE.object3D. As a consequence, those gets all object3D attributes.
Lifecycle
onResize ()- when window is resized OR body height or width changes (cause of content added for instance)
onScroll ()- when scroll on window
onUpdate ({ delta, elpased })- delta: time elapsed since the last frame
- elpased: time elapsed since the beginning of the experience
Methods
getByName (name: String, isComponent: Boolean)- name: name of the object. Canc match a pattern with * e.g.: 'test*'
- isComponent (optionnal): if result should be transformed into a component. Default is true. Searches through an object and its children
on (event: String, callback: Function, ctx)- event: name of the event. Allowed are
hover,over,enter,outandclick. - callback: callback function to be called
- ctx: an object to listen event to, default is
thisAdd event Listener
- event: name of the event. Allowed are
off (event: String, callback: Function)- event: name of the event. Allowed are
hover,over,enter,outandclick. - callback: callback function to be called Remove event Listener
- event: name of the event. Allowed are
destroy ()To be called before removing the elements or when element is not used anymioreget boundingBox ()Return a dynamicaly calculated Box3 matching the current boundingBox of the objectget size ()Return a dynamicaly calculated Vector3 of the object's sizeget center ()Return a dynamicaly calculated Vector3 of the object's center
Utils
Clock
import { clock } from 'shimmer'
clock.on({delta, elapsed} => {
// code
})A timer function that goes thourgh all the application. Used internally by all components.
Chronometer
import { Chronometer } from 'shimmer'
const chrono = new Chronometer()
chrono.on(({elapsed}) => {
// console.log('plop', elapsed)
})
setTimeout(() => {
chrono.start()
}, 3000)A timer class depending on Clock
Used internally by all components.
Countdown
import { Countdown } from 'shimmer'
const countdown = new Countdown(3000)
countdown.start(() => {
// code
})A Countdown class depending on Clock
OrbitAuto
import { OrbitAuto } from 'shimmer'
const orbit = new OrbitAuto(camera, target, maxPolar, maxAzimuth, accelerometer)
orbit.active = true
orbit.update($device.pointer)camera: THREE.Camera Camera currently used in webGLtarget: Vector3 Point that the camera looks atmaxPolar: Float. Max polar value (horizontal)maxAzimuth: Float. Max azimuth value (vertical)accelerometer: Boolean. If set to true and accelerometer allowed, will automatically use device's accelerometer
An Orbit camera class that can uses accelerometer
authorizeAccelerometer
import { authorizeAccelerometer } from 'shimmer'
authorizeAccelerometer()Request device's permission to use accelerometer
Pointer
import { pointer } from 'shimmer'
const intersection = pointer.getIntersectPosition(myMesh)Get raycast intersection Vector3 between mouse position and mesh.
Is used internally by components for methods on.
Pointer is a singleton wich is constantly updated by Engine.
FitTo
import { FitTo } from 'shimmer'
const { position, look } = FitTo.fit(box, padding, { vector, angles }, fit)box: THREE.Box3. targets boxpadding: Float or Object. { top, right, bottom, left } defining padding relatively to objects' box facevector: THREE.Vector3. Director vector used to define the angle of view. Used if angles is not definedangles: Object {polar, azimuth}. defining angle of view of the camera. Ifvectororanglesare not defined, the default vector director will be defined by delta between the camera and the center of the boxfit: String setting the object fit. Can becoverorcontain. Default iscover.
Return a position and a target (lookAt) for the camera to frame a box. Allows a specific padding for each side if needed.
toScreenPosition
import { toScreenPosition } from 'shimmer'
const pos = toScreenPosition(position)position: THREE.Vector3 Position searched
Return the position of a 3D object on the 2D canvas.
positionPadding
import { positionPadding } from 'shimmer'
const {look, position} = positionPadding(target, director, dist, padding)target: THREE.Vector3. Point to look atdirector: THREE.Vector3. Vector director definied angle of viewdist: Float. Distance to have between the position and the point to look atpadding: Float. Value between -1 and 1 where -1 il full offset to left and 1 is full offset to rightlook: THREE.Vector3. Look to set at the camera (lookAt)position: THREE.Vector3. Position of the camera
Calcule the look and position of the camera with a specific padding left or right. Is used to position the camera accordingly to the UI, with the UI on a side of the screen and the target on the other side.
visibleViewport
import { visibleViewport } from 'shimmer'
const {height, width, box} = visibleViewport(target, position)target: THREE.Vector3 Position of where we want to get visible part of 3d spaceposition: Position of the camera. If not set, default camera's position is usedheight: Float height of the space seenwidth: Float width of the space seenbox: THREE.Box3 box of the space seen
Return the visible part of the 3d seen at a specific point
webglAvailable
import { webglAvailable } from 'shimmer'
const res = visibleViewport(webglAvailable)res: Boolean result value
Get if webGL is available on device
ToCanvas
import { ToCanvas } from 'shimmer'
const toCanvas = new ToCanvas({ image, video, width, height, muted = false, loop = true, fit })
toCanvas.promise.then(() => {
code
// if video
toCanvas.start()
})
toCanvas.canvasimage: String. URL of the source if imagevideo: String. URL of the source if video. If image is also defined, it will be used as poster before video is able to play.width: Int. Width of the generated canvas. If not defined, use source as valueheight: Int. Height of the generated canvas. If not defined, use source as valuemuted: Boolean. If source is video, set it to muted to allow autoplayloop: Boolean. If source is video, set it to loopfit: String. Allowed values are 'cover' or 'contained'. Default value is 'cover'
Generate a canvas with an image or a video sized as cover
Loader
import { Loader } from 'shimmer'
Loader.load(objectUrl)objectUrl: String of object's URL
Return a promise. Uses GLTFLoader and FBXLoader. Load FBX / GLTF / GLB. For Draco or KTX compression, GLTFLoader needs to have decoder set. See GLTFLoader.
FBXLoader
import { FBXLoader } from 'shimmer'
FBXLoader.load(objectUrl)objectUrl: String of object's URL
Return a promise. Load FBX.
GLTFLoader
import { GLTFLoader } from 'shimmer'
GLTFLoader.load(objectUrl)
GLTFLoader.draco = { path: '/draco/' }
GLTFLoader.ktx = { path: '/basis/', renderer: webGLRenderer }objectUrl: String of object's URLwebGLRenderer: The current WebGLRenderer
Return a promise. Load GLTF. For draco compression, draco property needs to be set width the decoder. For a KTX compression, ktx property needs to be set width the transcoder path and the webGL renderer.
OrbitControls
import { OrbitControls } from 'shimmer'
new OrbitControls(camera, element)camera: THREE.Camera. Camera currently used in webGLelement: DOM Element. Element to be used for mouse interactions
A complete copy of the THREE orbit camera with the only specificity to not prevent events propagation.
LoaderManager
import { LoaderManager } from 'shimmer'
const config = [
{
"name": "test",
"url": "/test.glb",
"type": "object",
"children": [
{
"name": "children",
"url": "/test.glb",
"type": "object"
}
]
},
{
"name": "test",
"url": "/test.jpg",
"type": "equirectangular"
}
]
LoaderManager.config = config
Each object in the config define an objet (or group) to load with severak properties
name: the key used to load the objecturl: Url of the file to load (for an hdr, of the folder to load)children: Subelements to load in the same timetype: the type of the element to load, can be of four types:hdr,equirectangular,textureorobject
LoaderManager.load('test', false, setupItem)load('test', asComponent, setupItem): Boolean result valuename: String. If empty, load all assets. If not empty, load mathing asset and its children.asComponent: Boolean. Available for typeobjectonly. If true, automatically build a component as a return. Else, return the result of the loading.setupItem: Callback function that receive as an argument each object of the 3d file loader. Available for typeobjectonly.
Cameras
Perspective Camera
import { PerspectiveCamera } from 'shimmer'
const camera = new PerspectiveCamera(50, 1, 1, 1000)Simple Threejs Perspective Camera that with a lookproperty as a Vector3.
Each time camera.look changes, camera.lookAt is called.
look: Vector3 indicating where the camera looks- Each time
camera.lookchanges,camera.lookAtis called.
- Each time
forceUpdateLook: Boolean set to false at each frame- if true, will force apply
camera.look
- if true, will force apply
computeLook(webGL.Scene): Function that recalculate the look directionnal vector of the camera- raycast from camera to an invisible sphere and apply the intersection to the look
Orthographic Camera
import { OrthographicCamera } from 'shimmer'
const camera = new OrthographicCamera()Same new properties as Perspective Camera.
rollup-starter-lib
This repo contains a bare-bones example of how to create a library using Rollup, including importing a module from node_modules and converting it from CommonJS.
We're creating a library called how-long-till-lunch, which usefully tells us how long we have to wait until lunch, using the ms package:
console.log('it will be lunchtime in ' + howLongTillLunch());Getting started
https://github.com/rollup/rollup-starter-lib
Clone this repository and install its dependencies:
git clone https://github.com/rollup/rollup-starter-lib
cd rollup-starter-lib
npm installnpm run build builds the library to dist, generating three files:
dist/how-long-till-lunch.cjs.jsA CommonJS bundle, suitable for use in Node.js, thatrequires the external dependency. This corresponds to the"main"field in package.jsondist/how-long-till-lunch.esm.jsan ES module bundle, suitable for use in other people's libraries and applications, thatimports the external dependency. This corresponds to the"module"field in package.jsondist/how-long-till-lunch.umd.jsa UMD build, suitable for use in any environment (including the browser, as a<script>tag), that includes the external dependency. This corresponds to the"browser"field in package.json
npm run dev builds the library, then keeps rebuilding it whenever the source files change using rollup-watch.
npm test builds the library, then tests it.
Variations
- babel — illustrates writing the source code in ES2015 and transpiling it for older environments with Babel
- buble — similar, but using Bublé which is a faster alternative with less configuration
- TypeScript — uses TypeScript for type-safe code and transpiling
License
MIT.
