• Stars
    star
    441
  • Rank 98,861 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⚡️🐶 React bindings for zdog

npm install zdog react-zdog
# or
yarn add zdog react-zdog

npm npm

react-zdog is a declarative abstraction of zdog, a cute pseudo 3d-engine. Doing zdog in React allows you to break up your scene graph into declarative, re-usable components with clean, reactive semantics. Try a live demo here.

How it looks like

import ReactDOM from "react-dom";
import React from "react";
import { Illustration, Shape } from "react-zdog";

ReactDOM.render(
  <Illustration zoom={8}>
    <Shape stroke={20} color="lightblue" rotate={{ x: Math.PI }} />
  </Illustration>,
  document.getElementById("root")
);

Illustration

The Illustration object is your portal into zdog. It forwards unreserved properties to the internal Zdog.Illustration instance. The component auto adjusts to re-size changes and fills out the wrapping relative/absolute parent.

<Illustration element="svg" /> // Can be either 'svg' or 'canvas'
  • element: Sets the graphics rendering DOM Element. Can be either 'svg' or 'canvas'. Default is "svg"
  • frameloop: Determins the render loop behavior, Can be either 'always' or 'demand'. default is 'always'.
  • pointerEvents: enables pointer events on zdog elements if set to true. Default is False.
  • style: styles for main renderer dom elemeent container.
  • onDragStart: callback on illustration's on drag start event listener
  • onDragMove: callback on illustration's on drag move event listener
  • onDragEnd: callback on illustration's on drag end event listener

And all the other props you will pass will be attached to illustration object. So any other properties or methods that you wanna set on illustration can be passed as prop as it is.

Hooks

All hooks can only be used inside the Illustration element because they rely on context updates!

useRender(callback, dependencies=[])

If you're running effects that need to get updated every frame, useRender gives you access to the render-loop.

import { useRender } from "react-zdog";

function Spin({ children }) {
  const ref = useRef(undefined);
  useRender((t) => (ref.current.rotate.y += 0.01));
  return <Anchor ref={ref}>{children}</Anchor>;
}

useZdog()

Gives you access to the underlying state-model.

import { useZdog } from 'react-zdog'

function MyComponent() {
  const {
    illu,             // The parent Zdog.Illustration object
    scene,            // The Zdog.Anchor object that's being used as the default scene
    size,             // Current canvas size
  } = useZdog()

useInvalidate()

Gives you access to function that updates the one scene frame on each call. It is useful only if you're setting frameloop props on Illustration component as demand

function MyComponent() {
  const invalidate = useInvalidate()
  const boxRef = useRef()
  const rotate = () => {
    boxRef.current.rotate.x += 0.03;
    boxRef.current.rotate.y += 0.03; //this will update underlying javascript object
    invalidate() //But you need to call invalidate to render the changes on screen
  }

  return (
    <Box
      ref={boxRef}
      {/* ...other props */}
    />
  )}

Pointer Events

React-zdog supports the Click, Pointer Move, Pointer Enter and Pointer Leave events on Zdog elemets. To use pointer events just enable the pointer events by setting pointerEvents prop to true on Illustration component.

<Illustration pointerEvents={true} />

and use onClick, onPointerMove, onPointerEnter and OnPointerLeave on any zdog element.

const onClick = (e, ele) => {
  //runs when user clicks on box
};

const onPointerMove = (e, ele) => {
  //runs when user moves pointer over box
};

const onPointerEnter = (e, ele) => {
  //runs when user's pointer enters the box
};

const onPointerLeave = (e, ele) => {
  //runs when user's pointer leaves the box
};

return (
  <Box
    onClick={onClick}
    onPointerMove={onPointerMove}
    onPointerEnter={onPointerEnter}
    onPointerLeave={onPointerLeave}
  />
);
Note: zdog dosen't support pointer events out of the box, it is react-zdog specific feature which is added recently and was tested, but if you find some issue with events (and with any other thing) please open a issue and let us know.

Examples

Basic Example
import React, { useRef, useEffect } from 'react';
import { Illustration, useRender, useInvalidate, Box } from 'react-zdog';

// RotatingCube Component
const RotatingCube = () => {
const boxRef = useRef();

// Use the useRender hook to continuously update the rotation
useRender(() => {
if (boxRef.current) {
boxRef.current.rotate.x += 0.03;
boxRef.current.rotate.y += 0.03;
}
});

    return (
      <Box
        ref={boxRef}
        width={50}
        height={50}
        depth={50}
        color="#E44"
        leftFace="#4E4"
        rightFace="#44E"
        topFace="#EE4"
        bottomFace="#4EE"
      />
    );

};

// App Component
const App = () => {
return (
<Illustration zoom={4}>
<RotatingCube />
</Illustration>
);
};

export default App;
Pointer Events Example
import React, { useRef, useState } from 'react';
import { Illustration, useRender, Box } from 'react-zdog';

// InteractiveCube Component
const InteractiveCube = () => {
const [isClicked, setIsClicked] = useState(false);

const colorsBeforeClick = {
  main: "#E44",
  left: "#4E4",
  right: "#44E",
  top: "#EE4",
  bottom: "#4EE"
};

const colorsAfterClick = {
  main: "#FF5733",
  left: "#33FF57",
  right: "#3357FF",
  top: "#FF33A1",
  bottom: "#A133FF"
};

const currentColors = isClicked ? colorsAfterClick : colorsBeforeClick;

const handleBoxClick = () => {
  setIsClicked(!isClicked);
};


return (
  <Box
    width={50}
    height={50}
    depth={50}
    color={currentColors.main}
    leftFace={currentColors.left}
    rightFace={currentColors.right}
    topFace={currentColors.top}
    bottomFace={currentColors.bottom}
    onClick={handleBoxClick}
  />
);
};

// App Component
const App = () => {
return (
  <Illustration pointerEvents={true} zoom={4}>
    <InteractiveCube />
  </Illustration>
);
};

export default App;
On Demand rendering Example
import React, { useRef, useEffect } from "react";
import { Illustration, useInvalidate, Box } from "react-zdog";

// RotatingCube Component
const RotatingCube = () => {
  const boxRef = useRef();
  const invalidate = useInvalidate();

  useEffect(() => {
    const animate = () => {
      if (boxRef.current) {
        boxRef.current.rotate.x += 0.03;
        boxRef.current.rotate.y += 0.03;
        invalidate(); // Manually trigger a render
      }
    };

    const intervalId = setInterval(animate, 1000); // only renders the scene graph one a second instead of 60 times per second

    return () => intervalId && clearInterval(intervalId);
  }, [invalidate]);

  return (
    <Box
      ref={boxRef}
      width={50}
      height={50}
      depth={50}
      color="#E44"
      leftFace="#4E4"
      rightFace="#44E"
      topFace="#EE4"
      bottomFace="#4EE"
    />
  );
};

// App Component
const App = () => {
  return (
    <Illustration zoom={4} frameloop="demand">
      <RotatingCube />
    </Illustration>
  );
};

export default App;

Roadmap

  • Create more Examples
  • add More events support

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

More Repositories

1

zustand

🐻 Bear necessities for state management in React
TypeScript
45,348
star
2

react-spring

✌️ A spring physics based React animation library
TypeScript
27,857
star
3

react-three-fiber

🇨🇭 A React renderer for Three.js
TypeScript
26,202
star
4

jotai

👻 Primitive and flexible state management for React
TypeScript
18,007
star
5

use-gesture

👇Bread n butter utility for component-tied mouse/touch gestures in React and Vanilla Javascript.
TypeScript
8,861
star
6

valtio

💊 Valtio makes proxy-state simple for React and Vanilla
TypeScript
8,738
star
7

drei

🥉 useful helpers for react-three-fiber
JavaScript
8,042
star
8

leva

🌋 React-first components GUI
TypeScript
4,825
star
9

gltfjsx

🎮 Turns GLTFs into JSX components
JavaScript
4,251
star
10

use-cannon

👋💣 physics based hooks for @react-three/fiber
TypeScript
2,700
star
11

react-three-next

React Three Fiber, Threejs, Nextjs starter
JavaScript
2,370
star
12

postprocessing

A post processing library for three.js.
JavaScript
2,263
star
13

racing-game

🏎 Open source racing game developed by everyone willing
TypeScript
2,120
star
14

xr

🤳 VR/AR for react-three-fiber
TypeScript
2,051
star
15

uikit

🎨 user interfaces for react-three-fiber
TypeScript
2,048
star
16

react-three-flex

💪📦 Flexbox for react-three-fiber
TypeScript
1,640
star
17

suspend-react

🚥 Async/await for React components
TypeScript
1,358
star
18

react-postprocessing

📬 postprocessing for react-three-fiber
JavaScript
1,074
star
19

detect-gpu

Classifies GPUs based on their 3D rendering benchmark score allowing the developer to provide sensible default settings for graphically intensive applications.
TypeScript
1,017
star
20

react-three-rapier

🤺 Rapier physics in React
TypeScript
1,005
star
21

lamina

🍰 An extensible, layer based shader material for ThreeJS
TypeScript
1,005
star
22

its-fine

🐶🔥 A collection of escape hatches for React.
TypeScript
978
star
23

react-use-measure

🙌 Utility to measure view bounds
TypeScript
832
star
24

react-nil

⃝ A react null renderer
TypeScript
785
star
25

maath

🪶 Math helpers for the rest of us
TypeScript
783
star
26

threejs-journey

⚛️ Bruno Simons journey demos in React
TypeScript
718
star
27

three-stdlib

📚 Stand-alone library of threejs examples designed to run without transpilation in node & browser
JavaScript
651
star
28

react-three-editor

🔌 A one of a kind scene editor that writes changes back into your code
TypeScript
615
star
29

react-three-a11y

♿️ Accessibility tools for React Three Fiber
TypeScript
534
star
30

ecctrl

🕹️ A floating rigibody character controller
TypeScript
498
star
31

react-three-offscreen

📺 Offscreen worker canvas for react-three-fiber
TypeScript
443
star
32

drei-vanilla

🍦 drei-inspired helpers for threejs
TypeScript
436
star
33

use-asset

📦 A promise caching strategy for React Suspense
TypeScript
413
star
34

tunnel-rat

🐀 Non gratum anus rodentum
TypeScript
329
star
35

react-three-csg

🚧 Constructive solid geometry for React
TypeScript
264
star
36

react-three-lgl

🔆 A React abstraction for the LGL Raycaster
TypeScript
262
star
37

gltf-react-three

Convert GLTF files to React Three Fiber Components
JavaScript
258
star
38

market

📦 Download CC0 assets ready to use in your next 3D Project
JavaScript
250
star
39

component-material

🧩 Compose modular materials in React
TypeScript
160
star
40

env

💄 An app to create, edit, and preview HDR environment maps in the browser
TypeScript
151
star
41

react-ogl

🦴 A barebones react renderer for ogl.
TypeScript
150
star
42

use-p2

👋💣 2d physics hooks for @react-three/fiber
TypeScript
144
star
43

react-spring-examples

JavaScript
139
star
44

react-three-gpu-pathtracer

⚡️ A React abstraction for the popular three-gpu-pathtracer
TypeScript
132
star
45

react-three-lightmap

In-browser lightmap/AO baker for react-three-fiber and ThreeJS
TypeScript
127
star
46

cannon-es-debugger

Wireframe debugger for use with cannon-es https://github.com/react-spring/cannon-es
HTML
102
star
47

rafz

💍 One loop to frame them all.
TypeScript
96
star
48

docs

🖨️ mdx documentation generator for `pmndrs/*/docs` folders
TypeScript
91
star
49

assets

📦 Importable base64 encoded CC0 assets
Makefile
91
star
50

swc-jotai

Rust
88
star
51

react-three-jolt

⚡ Jolt physics in React
TypeScript
84
star
52

react-three-scissor

✂ Multiple scenes, one canvas! WebGL Scissoring implementation for React Three Fiber.
TypeScript
79
star
53

eslint-plugin-valtio

An eslint plugin for better valtio experience
JavaScript
74
star
54

react-three-babel

🛍 A Babel plugin that automatically builds the extend catalogue of known native Three.js elements
TypeScript
60
star
55

react-spring.io

✌️ A spring physics based React animation library
TypeScript
56
star
56

r3f-website

Website for React Three Fiber
JavaScript
27
star
57

directed

A flexible, minimal scheduler written in TypeScript
TypeScript
24
star
58

market-assets

JavaScript
19
star
59

react-three-8thwall

JavaScript
17
star
60

drei-assets

JavaScript
16
star
61

discord

🤖 Poimandres Discord Bot
TypeScript
10
star
62

branding

TypeScript
7
star
63

market-assets-do

JavaScript
5
star
64

envinfo

Easily collect useful information for bug reports
JavaScript
4
star
65

leva-wg

1
star