@pmndrs/uikit
Version:
Build performant 3D user interfaces with Three.js and yoga.
88 lines (65 loc) • 3 kB
Markdown
<h1>pmndrs/uikit</h1>
[](https://npmjs.com/package/@pmndrs/uikit)
[](https://npmjs.com/package/@pmndrs/uikit)
[](https://twitter.com/pmndrs)
[](https://discord.gg/ZZjjNvJ)

Build performant 3D user interfaces for **Three.js** using **yoga** with support for nested scrolling, buttons, inputs, dropdowns, tabs, checkboxes, and more.
> Perfect for games, XR (VR/AR), and any web-based Spatial Computing App.
```bash
npm install three @pmndrs/uikit
```
### What does it look like ?
| A simple UI with 2 containers horizontally aligned, rendered in fullscreen. When the user hovers over a container, the container's opacity changes. |  |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
```jsx
import { PerspectiveCamera, Scene, WebGLRenderer } from 'three'
import { reversePainterSortStable, Container } from '@pmndrs/uikit'
const camera = new PerspectiveCamera(70, 1, 0.01, 100)
camera.position.z = 10
const scene = new Scene()
const canvas = document.getElementById('root') as HTMLCanvasElement
const renderer = new WebGLRenderer({ antialias: true, canvas })
const root = new Container({
flexDirection: "row",
padding: 10,
gap: 10,
width: 1000,
height: 500
})
scene.add(root)
const c1 = new Container({
flexGrow: 1,
opacity: 0.5,
hover: { opacity: 1 }
backgroundColor: "red"
})
root.add(c1)
const c2 = new Container({
flexGrow: 1,
opacity: 0.5,
hover: { opacity: 1 },
backgroundColor: "blue"
})
root.add(c2)
renderer.setAnimationLoop(animation)
renderer.localClippingEnabled = true
renderer.setTransparentSort(reversePainterSortStable)
function updateSize() {
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
}
updateSize()
window.addEventListener('resize', updateSize)
let prev: number | undefined
function animation(time: number) {
const delta = prev == null ? 0 : time - prev
prev = time
root.update(delta)
renderer.render(scene, camera)
}
```
## Events
Events such a hovering require an additional event system that dispatches pointerover, ... events into the scene. More on this later ...