vanilla uikit
![Discord](https://img.shields.io/discord/740090768164651008?style=flat&colorA=000000&colorB=000000&label=discord&logo=discord&logoColor=000000)
![uikit banner](https://github.com/pmndrs/uikit/raw/HEAD/./docs/getting-started/banner.jpg)
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.
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. | ![render of the above code](https://github.com/pmndrs/uikit/raw/HEAD/./docs/getting-started/basic-example.gif) |
---|
import { PerspectiveCamera, Scene, WebGLRenderer } from 'three'
import { reversePainterSortStable, Container, Root } 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 Root(camera, renderer, {
flexDirection: "row",
padding: 10,
gap: 10,
width: 1000,
height: 500
})
scene.add(root)
const c1 = new Container({
flexGrow: 1,
backgroundOpacity: 0.5,
hover: { backgroundOpacity: 1 }
backgroundColor: "red"
})
root.add(c1)
const c2 = new Container({
flexGrow: 1,
backgroundOpacity: 0.5,
hover: { backgroundOpacity: 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 ...