Getting Started

Getting Started with SpatialJS

Welcome to SpatialJS! This guide will help you get up and running with our powerful library for creating immersive 3D spatial interfaces using React, R3f, UIKit and Three.js.

What is SpatialJS?

SpatialJS is a cutting-edge library that allows you to easily create and manage 3D windows in a spatial environment. It's built on top of React, R3f, UIKit and Three.js, providing a familiar and intuitive API for web developers.

What should you know first?

  1. React (opens in a new tab)
  2. React Three Fiber (opens in a new tab)
  3. Three.js (opens in a new tab)
  4. UIKit (opens in a new tab)
React Three FiberPaul Henschel Twitter
React XRBela Bohlenderl Twitter
React Three UI KitBela Bohlender Twitter

Tutorials

This doc is based on the tutorials, so if you want full projects to look at, check out the tutorials. Checkout All the tutorials Specifically the Hello World tutorial is a great place to start.

Quick Start

Follow these steps to create your first SpatialJS application:

  1. Set up a basic React application
  2. Install SpatialJS and its dependencies
  3. Create your first Spatial Window
  4. Customize and interact with your spatial interface

Let's dive in and start building amazing 3D experiences with SpatialJS!

Table of Contents

  1. Installation
  2. Creating Your First Window
  3. Managing Single Windows
  4. Working with Multiple Windows

Installation

Start by setting up a base React Application

npm create vite@latest new—spatialjs-app -- --template react-ts
cd new—spatialjs-app

Next, install SpatialJS and its peer dependencies:

npm install @spatialjs/core react @react-three/fiber @react-three/uikit three @types/three

Creating Your First Window

To create your first window, import the WindowManager component from spatialjs/core and use it to render your window.

import React from 'react';
import { Canvas } from '@react-three/fiber';
import { WindowManager } from '@spatialjs/core';
function App() {
  return (
    <div style={{ width: "100vw", height: "100vh" }}>
      <Canvas gl={{ localClippingEnabled: true }}>
        <WindowManager />
      </Canvas>
    </div>
  );
}
export default App;

In this example, we're creating a single window with a title, position, and dimensions. The WindowManager component is responsible for managing all windows in the scene.

Use a React Component as a Window or Spatial Application

You can create and manage windows directly via props in JSX. Use React-three uikit for the UI elements in windows. Here's an example of how to create a window with more advanced properties:

import React from 'react';
import { Text, Container } from '@react-three/uikit';
function HelloWorld() {
  return (
    <Container>
      <Text>Hello, World!</Text>
    </Container>
  );
}
export default App;

This example demonstrates how to create a basic Hellow World Component

Create a Spatial Window of that component

Now we can create a Spatialjs Window out of the HelloWorld Component. Simply use the 'createWindow' function or the useWindowStore.addWindow to create a window. The createWindow function is easiest as it'll use the default store, and set the default values for you. It's best to do this inside the Apps first load from react useEffect.

useEffect(() => {
  createWindow(HelloWorld, {
    id: 'hello-world', // optional - if not provided, a unique id will be generated
    title: 'Hello, World!', // optional - if not provided, the component name will be used
    position: [0, 0, -5], // optional - if not provided, the window will be created at the center of the scene
  });
}, []);

The id is a unique id, so if you don't want multiple of the same window, specify an id.

Working with Multiple Windows

SpatialJS allows you to create and manage multiple windows in your 3D space. You can also use different tiling methods to organize your windows. Here's an example of how to work with multiple windows:

import React, { useState } from 'react';
import { Canvas } from '@react-three/fiber';
import { WindowManager, useWindowStore } from 'spatialjs';
function App() {
  const windowStore = useWindowStore();
 
  const handleHelloWorldWindow = () => {
    windowStore.addWindow( {
      id: 'hello-world',
      title: 'Hello, World!',
      position: [0, 0, -5],
      component: HelloWorld,
      width: 2,
      height: 1.5,
    });
  };
 
  const handleTileWindows = () => {
    windowStore.tileWindows('grid');
  }
  
  const { addWindow, tileWindows, resetWindowPositions } = useWindowStore(
    (state) => ({
      addWindow: state.addWindow,
      tileWindows: state.tileWindows,
      resetWindowPositions: state.resetWindowPositions,
    })
  );
 
  const addRandomWindow = () => {
    const id = Math.random().toString(36).substr(2, 9);
    const isImageWindow = Math.random() > 0.5;
    const width = Math.floor(Math.random() * (400 - 200 + 1) + 200);
    const height = Math.floor(Math.random() * (300 - 150 + 1) + 150);
 
    addWindow({
      id,
      title: isImageWindow ? `Image Window ${id}` : `Text Window ${id}`,
      position: new Vector3(Math.random() * 8 - 4, Math.random() * 8 - 4, -5),
      scale: new Vector3(1, 1, 1),
      component: isImageWindow ? ImageWindow : TextWindow,
      props: isImageWindow ? {} : { id },
      width,
      height,
      isMinimized: false,
      isFullscreen: false,
      isFocused: false,
    });
  };
 
  React.useEffect(() => {
    // Add 20 random windows
    for (let i = 0; i < 200; i++) {
      addRandomWindow();
    }
  }, []);
 
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <Canvas>
        <OrbitControls
          enableZoom={false}
          enablePan={false}
          rotateSpeed={0.5}
          minPolarAngle={Math.PI / 2}
          maxPolarAngle={Math.PI / 2}
        />
        <Background />
        <WindowManager />
        <ambientLight intensity={0.5} />
      </Canvas>
      <div style={{ position: 'absolute', top: 10, left: 10 }}>
          <button onClick={addRandomWindow}>Add Random Position Window</button>
          <button onClick={handleHelloWorldWindow}>Add Hello World</button>
          <button onClick={handleTileWindows}>Tile Windows</button>
        </div>
    </div>
  );
}
export default App;

Great Start

Now your off to a great start. You can see how to create single basic windows, how to add multiple windows, and some basic ways to manage those windows.

What's next?

  1. Customizing Windows - Advanced looks at using UIKit to customize windows
  2. Using the Window Store - Look at the API for the WindowStore and what you can do with that to manage windows, and customizing your experience.
  3. Interactions - How to customize your interactions for your Spatial Applications, Interactivity, Window Focus Management
  4. Advanced - Dive into more advanced topics
  5. Tutorials - Look over and go through out tutorials

The world is waiting for your SpatialJS Application. Go create the future you want to see in the world.