Browse Source

Merge branch 'main' into feature/2-docs-for-cientos

Alvaro 2 years ago
parent
commit
a9fc428619

+ 16 - 0
.github/ISSUE_TEMPLATE/bug.report.yml

@@ -0,0 +1,16 @@
+name: "\U0001F41E Bug report"
+description: Report an issue with TresJS ▲ ■ ● or any of it's packages
+labels: [pending triage]
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thanks for taking the time to fill out this bug report!
+- type: textarea
+    id: bug-description
+    attributes:
+      label: Describe the bug
+      description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
+      placeholder: I am doing ... What I expect is ... What actually happening is ...
+    validations:
+      required: true

+ 1 - 0
.github/ISSUE_TEMPLATE/config.yml

@@ -0,0 +1 @@
+blank_issues_enabled: false

+ 20 - 0
.github/ISSUE_TEMPLATE/feature-request-🪐.md

@@ -0,0 +1,20 @@
+---
+name: "Feature request \U0001FA90"
+about: Suggest an idea for this project
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of the problem. Please make the reason and use-cases as detailed as possible. If you intend to submit a PR for this issue, tell us in the description. Thanks!
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Suggested solution**
+In module [xy] we could provide following implementation....
+
+**Additional context**
+Add any other context or screenshots about the feature request here.

+ 36 - 0
.github/ISSUE_TEMPLATE/🐛-bug-report.md

@@ -0,0 +1,36 @@
+---
+name: "\U0001F41B Bug report"
+about: Create a report to help us improve
+title: ''
+labels: pending-triage
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
+
+I am doing ... What I expect is ... What actually happening is
+
+**Reproduction**
+Please provide a link using this template on [Stackblitz](https://stackblitz.com/edit/tresjs-basic?file=README.md) 
+
+**Steps**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**System Info**
+Output of `npx envinfo --system --npmPackages '{vite,@tresjs/*, three, vue}' --binaries --browsers` 
+
+
+**Additional context**
+Add any other context about the problem here.

+ 43 - 0
CODE_OF_CONDUCT.md

@@ -0,0 +1,43 @@
+# Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others’ private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team by DM at [TresJS Discord](https://discord.gg/tfY9aSNT). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

+ 77 - 0
CONTRIBUTING.md

@@ -0,0 +1,77 @@
+![repository-banner.png](/public/github-banner.png)
+
+# Tres Contributing Guide
+
+Hi there!! If you are reading this guide, you are probably interested in contributing to Tres. You're awesome 🤩.
+
+No contribution is too small, whether it is a typo in the docs, a bug report or refactoring a piece of code, every contribution is welcome, just make sure to follow the guidelines below ✌️.
+
+Thanks from the heart 💚 for taking the time to help out. This guide will help you to get started with the project.
+
+## Setup
+
+Tresjs is a monorepo using [pnpm workspaces](https://pnpm.io/workspaces). Pnpm is a package manager that is faster than npm and yarn, and it also uses symlinks to avoid code duplication.
+
+Make sure you are using [Node.js](https://nodejs.org/en/) version 14 or higher.
+
+You can install pnpm using npm:
+
+```bash
+npm install -g pnpm
+```
+
+or using homebrew:
+
+If you have the package manager installed, you can install pnpm using the following command:
+
+```
+brew install pnpm
+```
+
+To develop Tres core or any of the packages, run `pnpm install` in the root of the project. This will install all the dependencies and link the packages together. There is also a `postinstall` script that will build all the packages.
+
+## Development
+
+TresJS is an ecosystem of packages, each one of them has its own purpose. The main package is `@tresjs/core` which is the core of the library. The other packages are plugins that extend the core functionality, like `@tresjs/cientos` which is a plugin that adds a bunch abstractions and composables to make it easier to create 3D scenes.
+
+### Core
+
+You can go to the `packages/tres` folder and run `pnpm dev` to start the dev server. This will start a vite server that will watch for changes in the code and rebuild the package.
+
+This is only a playground to test the core package, please keep the `App.vue` file as clean as possible.
+
+### Cientos
+
+You can go to the `packages/cientos` folder and run `pnpm build --watch` to build the package and watch for changes. That way you can test the changes in the playground on the `packages/tres` folder.
+
+### Docs
+
+The docs are built using [vitepress](https://vitepress.vuejs.org/).
+
+You can run `pnpm docs:dev` to start the dev server for the documentation. All the docs are located in the `docs` folder in markdown.
+
+If you are adding a new page, make sure to add it to the `docs/.vitepress/config.ts` file following the sidebar structure.
+
+### Testing
+
+Currently there are no tests in place, but we are working on it. If you want to contribute with tests, please open an issue first to discuss the best approach.
+
+## Pull Requests
+
+Before opening a pull request, make sure to run `pnpm lint` to make sure the code is following the code style.
+
+- Checkout a topic branch from the base branch `main` branch and merge back against that branch.
+- Please follow the [commit message conventions](https://www.conventionalcommits.org/en/v1.0.0-beta.4/) when committing your changes. This is important because the release notes will be automatically generated from these messages. Small scoped commits are always preferred, as it is easier to review them.
+- If adding new feature:
+  - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it. We would reject feature PRs that are not first opened as suggestions except for trivial changes.
+  - Create a `feature/{issue-number}-add-test-to-core` branch for this feature. Make the name meaningful.
+  - PR title must start with `feat(pkg): Descriptive title`. For example: `feat(core): added unit test to composables`.
+- If fixing a bug 🐛:
+
+  - Provide detailed description of the bug in the PR. Live demo preferred.
+  - Create a `fix/{issue-number}-fix-test-in-core` branch for this bug fix.
+  - If you are resolving a special issue, add `(fix #xxx[,#xxx])` (#xxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`.
+
+## Keep core small
+
+The core package should be as small as possible, it should only contain the core functionality of the library. If you are adding a new feature, please consider adding it as a plugin instead, for example, if you want to add support for [Effect Composer](https://threejs.org/examples/?q=compo#webgl_postprocessing_effectcomposer) you should create a new package called `@tresjs/postprocessing` and add it as a plugin. If it's a smaller scope you can always add it to `cientos` package.

+ 13 - 6
README.md

@@ -1,5 +1,12 @@
 ![repository-banner.png](/public/github-banner.png)
 
+<p align="center">
+  <a href="https://www.npmjs.com/package/@tresjs/core"><img src="https://img.shields.io/npm/v/@tresjs/core?color=%2382DBCA" alt="npm package"></a>
+  <a href="https://nodejs.org/en/about/releases/"><img src="https://img.shields.io/node/v/@tresjs/core.svg" alt="node compatibility"></a>
+  <a href="https://discord.gg/tfY9aSNT"><img src="https://img.shields.io/badge/chat-discord-purple?style=flat&logo=discord" alt="discord chat"></a>
+</p>
+<br/>
+
 # Tres
 
 > Declarative ThreeJS using Vue Components
@@ -13,14 +20,14 @@ Tres (Spanish word for "three", pronounced `/tres/` ) is a way of creating Three
 
 ## Packages
 
-| Package                     | Version (click for changelogs)                                                                                  |
-| --------------------------- | :-------------------------------------------------------------------------------------------------------------- |
-| [Tres](packages/tres)       | [![tres version](https://img.shields.io/npm/v/@tresjs/core.svg?label=%20)](packages/tres/CHANGELOG.md)          |
-| [Cientos](packages/cientos) | [![cientos version](https://img.shields.io/npm/v/@tresjs/cientos.svg?label=%20)](packages/cientos/CHANGELOG.md) |
+| Package                     | Version (click for changelogs)                                                                                               |
+| --------------------------- | :--------------------------------------------------------------------------------------------------------------------------- |
+| [Tres](packages/tres)       | [![tres version](https://img.shields.io/npm/v/@tresjs/core.svg?label=%20&color=%2382DBCA)](packages/tres/CHANGELOG.md)       |
+| [Cientos](packages/cientos) | [![tres version](https://img.shields.io/npm/v/@tresjs/cientos.svg?label=%20&color=%23f19b00)](packages/cientos/CHANGELOG.md) |
 
 ## Docs
 
-Checkout the [docs](https://tresjs-docs.netlify.app)
+Checkout the [docs](https://tresjs.org)
 
 ## Demos
 
@@ -28,7 +35,7 @@ Checkout the [docs](https://tresjs-docs.netlify.app)
 
 ## Contribution
 
-Soon
+We are open to contributions, please read the [contributing guide](/CONTRIBUTING.md) to get started.
 
 ## License
 

+ 32 - 5
docs/.vitepress/config.ts

@@ -1,5 +1,6 @@
 import { defineConfig } from 'vitepress'
 import { version } from '../../packages/tres/package.json'
+import { version as cientosVersion } from '../../packages/cientos/package.json'
 
 export default defineConfig({
   title: 'TresJS',
@@ -25,20 +26,31 @@ export default defineConfig({
             text: 'Instances, arguments and props',
             link: '/api/instances-arguments-and-props',
           },
+          {
+            text: 'Composables',
+            link: '/api/composables',
+          },
         ],
       },
       {
         text: 'Examples',
         items: [
           { text: 'Orbit Controls', link: '/examples/orbit-controls' },
-          { text: 'Basic Animation', link: '/examples/basic-animations' },
+          { text: 'Basic Animations', link: '/examples/basic-animations' },
           { text: 'Load Textures', link: '/examples/load-textures' },
           { text: 'Load Models', link: '/examples/load-models' },
         ],
       },
       {
         text: 'Advanced',
-        items: [{ text: 'Extending', link: '/advanced/extending' }],
+
+        items: [
+          { text: 'Extending', link: '/advanced/extending' },
+          {
+            text: 'Caveats',
+            link: '/advanced/caveats',
+          },
+        ],
       },
       {
         text: 'Cientos',
@@ -61,11 +73,26 @@ export default defineConfig({
       { text: 'API', link: '/api/' },
       { text: 'Config', link: '/config/' },
       {
-        text: `v${version}`,
+        text: 'Ecosystem',
+        activeMatch: `^/ecosystem/`,
         items: [
           {
-            text: 'Release Notes ',
-            link: 'https://github.com/Tresjs/tres/releases',
+            text: `Core v${version}`,
+            items: [
+              {
+                text: 'Release Notes ',
+                link: `https://github.com/Tresjs/tres/releases/tag/%40tresjs%2Fcore%40${version}`,
+              },
+            ],
+          },
+          {
+            text: `Cientos v${cientosVersion}`,
+            items: [
+              {
+                text: 'Release Notes ',
+                link: `https://github.com/Tresjs/tres/releases/tag/%40tresjs%2Fcientos%40${cientosVersion}`,
+              },
+            ],
           },
         ],
       },

+ 6 - 1
docs/.vitepress/theme/config.css

@@ -39,6 +39,11 @@
   --vp-button-sponsor-active-bg: transparent;
 }
 
-a {
+.VPSidebar .link.active span {
+  font-weight: bold;
+}
+
+.vp-doc a {
   text-decoration: dashed;
+  font-weight: bold;
 }

+ 6 - 2
docs/.vitepress/theme/index.ts

@@ -11,8 +11,12 @@ export default {
     DefaultTheme.enhanceApp(ctx)
     ctx.app.component('FirstScene', FirstScene)
     ctx.app.component('StackBlitzEmbed', StackBlitzEmbed)
-    ctx.app.use(Tres)
-
+    /*  ctx.app.use(Tres)
+     */
+    if (!import.meta.env.SSR) {
+      // ... server only logic
+      ctx.app.use(Tres)
+    }
     console.log(ctx)
   },
 }

+ 101 - 0
docs/advanced/caveats.md

@@ -0,0 +1,101 @@
+# Caveats 😱
+
+Our aim is to provide a simple way of using ThreeJS in VueJS with the best developer experience possible. However, there are some caveats that you should be aware of.
+
+## HMR and ThreeJS
+
+Hot module replacement (HMR) is a feature that allows you to update your code without reloading the page. This is a great feature that makes development much faster. **TresJS** uses [Vite](https://vitejs.dev/). However, is really tricky to make it work correctly with ThreeJS.
+
+Why? Because Tres builds the scene in a declarative way. This means that it creates the instance and add it to the scene when the component is mounted. The complexity comes to know when to remove the instance from the scene and when to add it again.
+
+Although a minimal disposal workflow is implemented, it is not perfect. This means that sometimes you will have to reload the page to see the changes correctly, specially when you are referencing an instances using [Template Refs](https://v3.vuejs.org/guide/component-template-refs.html)
+
+```vue
+<script setup lang="ts">
+const boxRef: Ref<TresInstance | null> = ref(null)
+
+onLoop(({ _delta, elapsed }) => {
+  if (boxRef.value) {
+    boxRef.value.rotation.y += 0.01
+    boxRef.value.rotation.z = elapsed * 0.2
+  }
+})
+</script>
+
+<template>
+  <TresMesh ref="boxRef" :scale="1" cast-shadow>
+    <TresBoxGeometry :args="[1, 1, 1]" />
+    <TresMeshStandardMaterial color="teal" />
+  </TresMesh>
+</template>
+```
+
+If you make a change on the `color` of the `TresMeshStandardMaterial` component, you will see that the change is applied but the rotation is not working anymore. This is because the instance is disposed and created again.
+
+:::tip
+So as **rule of thumb** you should reload the page whenever you don't see the changes you made.
+:::
+
+That being said we are working on a better solution for this 😁. If you have any idea how to solve this, please let us know.
+
+You can follow the discussion in [HMR Disposal Discussion](https://github.com/Tresjs/tres/issues/23)
+
+## Reactivity
+
+We all love reactivity 💚. It is one of the most powerful features of VueJS. However, we need to be mindful of it when using ThreeJS.
+
+Vue reactivity is based on [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). This allows Vue 3 to automatically track changes to data objects and update the corresponding DOM elements whenever the data changes.
+
+Since we are rendering an scene and updating it in every frame (60FPS), that means that we are updating the scene 60 times per second. If the object to be updated is reactive, Vue will try to update the that objectthat many times. This is not a good idea 😅 and will be detrimental for performance.
+
+Here is a benchmark of the difference between using a Proxy object and a plain object.
+
+<figure>
+  <img src="/proxy-benchmark.png" alt="Proxy vs Plain" style="width:100%">
+  <figcaption>Fig.1 - Executions per second Plan Object vs Proxy. </figcaption>
+</figure>
+
+Source: [Proxy vs Plain Object](https://www.measurethat.net/Benchmarks/Show/12503/0/object-vs-proxy-vs-proxy-setter)
+
+If you are forced to use reactivity, use [shallowRef](https://vuejs.org/api/reactivity-advanced.html#shallowref)
+
+Unlike `ref()`, the inner value of a shallow ref is stored and exposed as-is, and will not be made deeply reactive. Only the .value access is reactive. Source [VueJS Docs](https://vuejs.org/api/reactivity-advanced.html#shallowref)
+
+### Example
+
+❌ Incorrect
+
+```vue
+<script setup lang="ts">
+const position = reactive({ x: 0, y: 0, z: 0 })
+
+onLoop(({ _delta, elapsed }) => {
+  position.x = Math.sin(elapsed * 0.1) * 3
+})
+</script>
+<template>
+  <TresMesh :position="position" cast-shadow>
+    <TresBoxGeometry :args="[1, 1, 1]" />
+    <TresMeshStandardMaterial color="teal" />
+  </TresMesh>
+</template>
+```
+
+✅ Correct
+
+```vue
+<script setup lang="ts">
+const position = { x: 0, y: 0, z: 0 }
+const boxRef: ShallowRef<TresInstance | null> = shallowRef(null)
+
+onLoop(({ _delta, elapsed }) => {
+  boxRef.value.position.x = Math.sin(elapsed * 0.1) * 3
+})
+</script>
+<template>
+  <TresMesh ref="boxRef" :position="position" cast-shadow>
+    <TresBoxGeometry :args="[1, 1, 1]" />
+    <TresMeshStandardMaterial color="teal" />
+  </TresMesh>
+</template>
+```

+ 201 - 0
docs/api/composables.md

@@ -0,0 +1,201 @@
+# Composables
+
+Vue 3 [Composition API](https://vuejs.org/guide/extras/composition-api-faq.html#what-is-composition-api) allows you to create reusable logic that can be shared across components. It also allows you to create custom hooks that can be used in your components.
+
+**TresJS** takes huge advantage of this API to create a set of composable functions that can be used to create animations, interact with the scene and more. It also allows you to create more complex scenes that might not be possible using just the Vue Components (Textures, Loaders, etc.).
+
+The core of **TresJS** uses these composables internally, so you would be using the same API that the core uses. For instance, components that need to updated on the internal render loop use the `useRenderLoop` composable to register a callback that will be called every time the renderer updates the scene.
+
+## useRenderLoop
+
+The `useRenderLoop` composable is the core of **TresJS** animations. It allows you to register a callback that will be called on native refresh rate. This is the most important composable in **TresJS**.
+
+```ts
+const { onLoop, resume } = useRenderLoop()
+
+onLoop(({ delta, elapsed }) => {
+  // I will run at every frame ~ 60FPS (depending of your monitor)
+})
+```
+
+::: warning
+Be mindfull of the performance implications of using this composable. It will run at every frame, so if you have a lot of logic in your callback, it might impact the performance of your app. Specially if you are updating reactive states or references.
+:::
+
+The `onLoop` callback receives an object with the following properties based on the [THREE clock](https://threejs.org/docs/?q=clock#api/en/core/Clock):
+
+- `delta`: The delta time between the current and the last frame. This is the time in seconds since the last frame.
+- `elapsed`: The elapsed time since the start of the render loop.
+
+This composable is based on `useRafFn` from [vueuse](https://vueuse.org/core/useRafFn/). Thanks to [@wheatjs](https://github.com/orgs/Tresjs/people/wheatjs) for the amazing contribution.
+
+### Before and after render
+
+You can also register a callback that will be called before and after the renderer updates the scene. This is useful if you add a profiler to measure the FPS for example.
+
+```ts
+const { onBeforeLoop, onAfterLoop } = useRenderLoop()
+
+onBeforeLoop(({ delta, elapsed }) => {
+  // I will run before the renderer updates the scene
+  fps.begin()
+})
+
+onAfterLoop(({ delta, elapsed }) => {
+  // I will run after the renderer updates the scene
+  fps.end()
+})
+```
+
+### Pause and resume
+
+You can pause and resume the render loop using the exposed `pause` and `resume` methods.
+
+```ts
+const { pause, resume } = useRenderLoop()
+
+// Pause the render loop
+pause()
+
+// Resume the render loop
+resume()
+```
+
+Also you can get the active state of the render loop using the `isActive` property.
+
+```ts
+const { resume, isActive } = useRenderLoop()
+
+console.log(isActive) // false
+
+resume()
+
+console.log(isActive) // true
+```
+
+## useLoader
+
+The `useLoader` composable allows you to load assets using the [THREE.js loaders](https://threejs.org/docs/#manual/en/introduction/Loading-3D-models). It returns a promise with loaded asset.
+
+```ts
+import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
+
+const { scene } = await useLoader(THREE.GLTFLoader, 'path/to/asset.gltf')
+```
+
+Since the `useLoader` composable returns a promise, you can use it with `async/await` or `then/catch`. If you are using it on a component make sure you wrap it with a `Suspense` component. See [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) for more information.
+
+```vue
+<template>
+  <Suspense>
+    <TheComponentUsingLoader />
+  </Suspense>
+</template>
+```
+
+## useTexture
+
+The `useTexture` composable allows you to load textures using the [THREE.js texture loader](https://threejs.org/docs/#api/en/loaders/TextureLoader). It returns a promise with the loaded texture(s).
+
+```ts
+const texture = await useTexture(['path/to/texture.png'])
+```
+
+**useTexture** also accepts an object with the following properties:
+
+- `map`: a basic texture that is applied to the surface of an object
+- `displacementMap`: a texture that is used to add bumps or indentations to the object's surface
+- `normalMap`: a texture that is used to add surface detail to and variations in shading to the object
+- `roughnessMap`: a texture that is used to add roughness or a matte finish to the object's surface
+- `metalnessMap`: a texture that is used to add a metallic effect to the object's surface
+- `aoMap`: a texture that is used to add ambient occlusion (shading in areas where light is blocked by other objects) to the object.
+
+In that case it will return an object with the loaded textures.
+
+```ts
+const { map, displacementMap, normalMap, roughnessMap, metalnessMap, aoMap } = await useTexture({
+  map: 'path/to/albedo.png',
+  displacementMap: 'path/to/height.png',
+  normalMap: 'path/to/normal.png',
+  roughnessMap: 'path/to/roughness.png',
+  metalnessMap: 'path/to/metalness.png',
+  aoMap: 'path/to/ambien-occlusion.png',
+})
+```
+
+Then you can bind the textures to the material.
+
+```vue
+<template>
+  <TresMesh>
+    <TresMeshSphereGeometry />
+    <TresMeshStandardMaterial
+      :map="map"
+      :displacementMap="displacementMap"
+      :normalMap="normalMap"
+      :roughnessMap="roughnessMap"
+      :metalnessMap="metalnessMap"
+      :aoMap="aoMap"
+    />
+  </TresMesh>
+</template>
+```
+
+Similar to above composable, the `useTexture` composable returns a promise, you can use it with `async/await` or `then/catch`. If you are using it on a component make sure you wrap it with a `Suspense` component.
+
+# useCatalogue
+
+The `useCatalogue` composable allows you to extend the internal catalogue of components. It returns a function that you can use to register new components.
+
+This is specially useful if you want to use objects that are not part of ThreeJS core like[OrbitControls](https://threejs.org/docs/#examples/en/controls/OrbitControls) or third party functionality, like physics.
+
+```ts
+import { useCatalogue } from '@tresjs/core'
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
+
+const { extend } = useCatalogue()
+
+extend({ OrbitControls })
+```
+
+Then you can use the new component in your template. Notice that the new component is prefixed with `Tres` to avoid name collisions with native HTML elements, similar to the rest of the core components.
+
+```vue
+<template>
+  <TresCanvas shadows alpha>
+    <TresScene>
+      <TresOrbitControls v-if="state.renderer" :args="[state.camera, state.renderer?.domElement]" />
+    </TresScene>
+  </TresCanvas>
+</template>
+```
+
+# useTres <Badge type="warning" text="experimental" />
+
+This composable aims to provide access to the state model which contains the default renderer, camera, scene, and other useful properties. It is still experimental and it is not recommended to use it in production because is highly like subject to change.
+
+```ts
+const { state } = useTres()
+
+console.log(state.camera) // THREE.PerspectiveCamera
+console.log(state.renderer) // THREE.WebGLRenderer
+```
+
+Until this composable is stable, it is recommended to use the `provide/inject` API to acces the elements you need. These are the available keys:
+
+- `camera`: it returns the current active camera
+- `renderer`: it returns the current active renderer
+- `local-scene`: it returns the current active scene
+- `catalogue`: it returns the current catalogue of components
+- `extend` : it returns the `extend` function from the `useCatalogue` composable. Specially needed if you are a plugin author.
+- `aspect-ratio`: it returns the current aspect ratio of the canvas
+
+```ts
+import { provide, inject } from 'vue'
+
+const camera = inject<Ref<Camera>>('camera')
+const renderer = inject<Ref<WebGLRenderer>>('renderer')
+
+console.log(camera.value) // THREE.PerspectiveCamera
+console.log(renderer.value) // THREE.WebGLRenderer
+```

+ 1 - 1
docs/api/instances-arguments-and-props.md

@@ -21,7 +21,7 @@ With **Tres** you don't need to import anything, that's because **Tres** automat
 </template>
 ```
 
-This mean that you can the same [documentation](https://threejs.org/docs/) as you where using plain ThreeJS, but with the power of Vue.
+This means that you can use the same [documentation](https://threejs.org/docs/) as you would when using plain ThreeJS, but with the power of Vue.
 
 ## Declaring objects
 

+ 4 - 2
docs/examples/basic-animations.md

@@ -10,7 +10,7 @@ We will build a simple scene with a cube. We will then animate the cube to rotat
 
 The `useRenderLoop` composable is the core of TresJS animations. It allows you to register a callback that will be called every time the renderer updates the scene with the browser's refresh rate.
 
-To see a detailed explanation of how it works, please refer to the [useRenderLoop](/composables/use-render-loop) documentation.
+To see a detailed explanation of how it works, please refer to the [useRenderLoop](/api/composables#userenderloop) documentation.
 
 ```ts
 const { onLoop, resume } = useRenderLoop()
@@ -25,9 +25,11 @@ onLoop(({ _delta, elapsed }) => {
 
 To animate the cube, we need to get a reference to it. We can do it by passing a [Template Ref](https://vuejs.org/guide/essentials/template-refs.html) using `ref` prop to the `TresMesh` component. This will return the THREE instance.
 
+To improve the performance, we will use a [Shallow Ref](https://v3.vuejs.org/guide/reactivity-fundamentals.html#shallow-reactivity) to store the reference instead of a regular Ref. See why [here](../advanced/caveats.md#reactivity)
+
 ```vue
 <script setup lang="ts">
-const boxRef: Ref<TresInstance | null> = ref(null)
+const boxRef: ShallowRef<TresInstance | null> = shallowRef(null)
 </script>
 
 <template>

+ 1 - 3
docs/examples/load-models.md

@@ -14,7 +14,7 @@ There are several ways to load models on TresJS:
 
 The `useLoader` composable allows you to pass any type of Three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
 
-For a detailed explanation of how to use `useLoader`, check out the [useLoader](/composables/use-loader) documentation.
+For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#useloader) documentation.
 
 ```ts
 import { useLoader } from '@tresjs/core'
@@ -41,8 +41,6 @@ Notice in the example above that we are using the `Suspense` component to wrap t
 
 A more convenient way of loading models is using the `useGLTF` composable available from [@tresjs/cientos](https://github.com/Tresjs/tres/tree/main/packages/cientos) package.
 
-To learn more about `useGLTF`, check out the [useGLTF](/cientos/composables/use-gltf) documentation.
-
 ```ts
 import { useGLTF } from '@tresjs/cientos'
 

+ 3 - 3
docs/examples/load-textures.md

@@ -2,7 +2,7 @@
 
 > All textures used in this example are from [ambientcg](https://ambientcg.com/).
 
-3D textures are textures that contain multiple layers of image data, allowing them to represent volumetric data or simulate three-dimensional structures. They are often used in 3D graphics and visual effects to add realism and complexity to scenes and objects.
+Three-dimensional (3D) textures are images that contain multiple layers of data, allowing them to represent volume or simulate three-dimensional structures. These textures are commonly used in 3D graphics and visual effects to enhance the realism and complexity of scenes and objects.
 
 <StackBlitzEmbed projectId="tresjs-load-textures" />
 
@@ -12,7 +12,7 @@ There are two ways of loading 3D textures in TresJS:
 
 The `useLoader` composable allows you to pass any type of Three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
 
-For a detailed explanation of how to use `useLoader`, check out the [useLoader](/composables/use-loader) documentation.
+For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#use-loader) documentation.
 
 ```ts
 import { useLoader } from '@tresjs/core'
@@ -42,7 +42,7 @@ Notice in the example above that we are using the `Suspense` component to wrap t
 
 A more convenient way of loading textures is using the `useTexture` composable. It accepts both an array of URLs or a single object with the texture paths mapped.
 
-To learn more about `useTexture`, check out the [useTexture](/composables/use-texture) documentation.
+To learn more about `useTexture`, check out the [useTexture](/api/composables#use-texture) documentation.
 
 ```ts
 import { useTexture } from '@tresjs/core'

+ 3 - 3
docs/examples/orbit-controls.md

@@ -8,7 +8,7 @@ However, it is not part of the core of ThreeJS. So to use it you would need to i
 
 This creates a problem because **TresJS** automatically creates a catalog of the core of Three so you can use them as components.
 
-Fortunately, **TresJS** provides a way to extend the catalog of components. You can do it by using the `extend` method using the [useCatalogue](/composables/use-catalog) composable.
+Fortunately, **TresJS** provides a way to extend the catalog of components. You can do it by using the `extend` method using the [useCatalogue](/api/composables#usecatalog) composable.
 
 For more information about extending your TresJS catalog, refer to the [extending](/advanced/extending.md) section.
 
@@ -20,7 +20,7 @@ To use `OrbitControls` you need to import it from the `three/examples/jsm/contro
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
 ```
 
-Then you need to extend the catalogue of components using the `extend` method of the [useCatalogue](/composables/use-catalog) composable.
+Then you need to extend the catalogue of components using the `extend` method of the [useCatalogue](/api/composables#usecatalog) composable.
 
 ```js
 import { useCatalogue } from '@tresjs/core'
@@ -45,7 +45,7 @@ Now you can use the `TresOrbitControls` component in your scene.
 
 Since [OrbitControls](https://threejs.org/docs/index.html?q=orbit#examples/en/controls/OrbitControls) needs a reference to the camera and the renderer, you need to pass them as arguments.
 
-You can use the [useThree](/composables/use-three) composable to get the camera and the renderer.
+You can use the [useThree](/api/composables#usethree) composable to get the camera and the renderer.
 
 ```ts
 import { useThree } from '@tresjs/core'

+ 9 - 4
docs/guide/index.md

@@ -1,9 +1,8 @@
 # Introduction
 
-> Tres (Spanish word for "three", pronounced `/tres/` ) is a way of creating ThreeJS scenes with Vue components in a declarative way.
-
-<FirstScene style="aspect-ratio: 16/9; height: auto; margin: 2rem 0; border-radius: 8px; overflow:hidden;"/>
-
+<ClientOnly>
+    <FirstScene style="aspect-ratio: 16/9; height: auto; margin: 2rem 0; border-radius: 8px; overflow:hidden;"/>
+</ClientOnly>
 ```
 npm install three @tresjs/core -D
 ```
@@ -20,6 +19,12 @@ pnpm users
 pnpm add three @tresjs/core -D
 ```
 
+## Try it online
+
+You can fork this template example on [StackBlitz](https://stackblitz.com/edit/tresjs-basic?file=src/App.vue) and play with it 😋 without installing anything locally.
+
+<StackBlitzEmbed projectId="tresjs-basic" />
+
 ## Motivation
 
 [ThreeJS](https://threejs.org/) is a wonderfull library to create awesome **WebGL** 3D websites. Is also a constantly updated library that makes hard for wrapper mantainers like [TroisJS](https://troisjs.github.io/) to keep up with all the enhancements.

+ 2 - 2
docs/guide/your-first-scene.md

@@ -4,7 +4,7 @@ This guide will help you to create your first Tres scene. 🍩
 
 ## Setting up the experience Canvas
 
-Before we can create an Scene, we need somewhere to display it. Using plain [ThreeJS](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene) we would need yo create a `canvas` html element to mount the `WebglRenderer` and initialize the `scene`
+Before we can create an Scene, we need somewhere to display it. Using plain [ThreeJS](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene) we would need to create a `canvas` html element to mount the `WebglRenderer` and initialize the `scene`
 
 With **TresJS** you only need to add the default component `<TresCanvas />` to the template of your Vue component.
 
@@ -91,4 +91,4 @@ Notice that we don't need to import anything, thats because **TresJS** automatic
 
 <FirstScene />
 
-From that on you can start adding more objects to your scene, and start playing with the properties of the components to see how they affect the scene.
+From here onwards you can start adding more objects to your scene and start playing with the properties of the components to see how they affect the scene.

BIN
docs/public/proxy-benchmark.png


+ 5 - 0
netlify.toml

@@ -0,0 +1,5 @@
+[build.environment]
+  NODE_VERSION = "16"
+[build]
+  publish = "docs/.vitepress/dist"
+  command = "pnpm docs:build"

+ 5 - 1
package.json

@@ -3,6 +3,10 @@
   "description": "Declarative ThreeJS using Vue Components",
   "version": "1.0.0",
   "author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
+  "engines": {
+    "npm": ">=8.0.0 <9.0.0",
+    "node": ">=16.0.0 <17.0.0"
+  },
   "workspaces": [
     "apps/**",
     "packages/*"
@@ -48,7 +52,7 @@
     "@changesets/cli": "^2.25.2",
     "@stackblitz/sdk": "^1.8.1",
     "@tresjs/cientos": "workspace:^1.1.0",
-    "@tresjs/core": "workspace:^1.2.0",
+    "@tresjs/core": "workspace:^1.2.1",
     "@typescript-eslint/eslint-plugin": "^5.42.0",
     "@typescript-eslint/parser": "^5.42.0",
     "conventional-changelog-cli": "^2.2.2",

+ 2 - 2
packages/cientos/package.json

@@ -36,7 +36,7 @@
     "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue"
   },
   "peerDependencies": {
-    "@tresjs/core": "workspace:^1.2.0",
+    "@tresjs/core": "workspace:^1.2.1",
     "three": "latest",
     "vue": "^3.2.45"
   },
@@ -54,7 +54,7 @@
     "vite-plugin-dts": "^1.7.0"
   },
   "dependencies": {
-    "@tresjs/core": "workspace:^1.2.0",
+    "@tresjs/core": "workspace:^1.2.1",
     "three-stdlib": "^2.17.3"
   }
 }

+ 1 - 0
packages/cientos/vite.config.ts

@@ -39,6 +39,7 @@ export default defineConfig({
       name: 'trescientos',
       fileName: 'trescientos',
     },
+    copyPublicDir: false,
     watch: {
       include: [resolve(__dirname, 'src')],
     },

+ 6 - 0
packages/tres/CHANGELOG.md

@@ -1,3 +1,9 @@
+# 1.2.1 (2022-12-11)
+
+### Bug Fixes
+
+- added copyPublicDir: false to remove static assets on package ([7e8de9c](https://github.com/Tresjs/tres/commit/7e8de9c4b4e63107b79a81a8686ad97256a29017))
+
 # 1.2.0 (2022-12-08)
 
 ### Bug Fixes

+ 1 - 1
packages/tres/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@tresjs/core",
   "description": "Declarative ThreeJS using Vue Components",
-  "version": "1.2.0",
+  "version": "1.2.1",
   "type": "module",
   "author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
   "files": [

+ 3 - 1
packages/tres/vite.config.ts

@@ -50,15 +50,17 @@ export default defineConfig({
     watch: {
       include: [resolve(__dirname, 'src')],
     },
+    copyPublicDir: false,
     rollupOptions: {
       plugins: [
         analyze(),
-        /*  visualizer({
+        /*    visualizer({
           open: true,
           gzipSize: true,
           brotliSize: true,
         }), */
       ],
+
       external: ['vue', '@vueuse/core', 'three'],
       output: {
         exports: 'named',

+ 4 - 4
pnpm-lock.yaml

@@ -8,8 +8,8 @@ importers:
       '@changesets/changelog-github': ^0.4.7
       '@changesets/cli': ^2.25.2
       '@stackblitz/sdk': ^1.8.1
-      '@tresjs/cientos': workspace:^1.0.0
-      '@tresjs/core': workspace:^1.1.0
+      '@tresjs/cientos': workspace:^1.1.0
+      '@tresjs/core': workspace:^1.2.1
       '@typescript-eslint/eslint-plugin': ^5.42.0
       '@typescript-eslint/parser': ^5.42.0
       conventional-changelog-cli: ^2.2.2
@@ -40,7 +40,7 @@ importers:
 
   packages/cientos:
     specifiers:
-      '@tresjs/core': workspace:^1.1.0
+      '@tresjs/core': workspace:^1.2.1
       '@tweakpane/plugin-essentials': ^0.1.5
       '@vitejs/plugin-vue': ^3.2.0
       kolorist: ^1.6.0
@@ -73,7 +73,7 @@ importers:
     specifiers:
       '@alvarosabu/utils': ^2.2.0
       '@histoire/plugin-vue': 0.11.7
-      '@tresjs/cientos': workspace:^1.0.0
+      '@tresjs/cientos': workspace:^1.1.0
       '@types/three': ^0.146.0
       '@vitejs/plugin-vue': ^3.2.0
       '@vitest/coverage-c8': ^0.25.1