-
-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: add shared state documentation #699
Open
whitespacecode
wants to merge
7
commits into
Tresjs:main
Choose a base branch
from
whitespacecode:patch-2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
80b87cb
docs: add shared state documentation
whitespacecode d3bf9a8
chore: stackBlitz embed update
whitespacecode c94d02e
chore: update shared-state.md
whitespacecode c9623ce
Merge branch 'main' into patch-2
alvarosabu 64f228c
Merge branch 'main' into patch-2
alvarosabu 05602e6
Update shared-state.md
whitespacecode 797fae2
Update shared-state.md
whitespacecode File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
--- | ||
title: Shared State | ||
description: How to use a reactive composable to share your objects across component files. | ||
author: whitespacecode | ||
thumbnail: /recipes/animations.png | ||
difficulty: 0 | ||
--- | ||
|
||
# Shared State in TresJS | ||
|
||
This guide will help you get started with shared state in TresJS by building a simple scene with a cube that can be shared across component files. | ||
|
||
<StackBlitzEmbed project-id="tresjs-minimal-reproduction-rycc4j" /> | ||
|
||
## Creating a State Composable | ||
|
||
First, we'll create a composable to store the objects. | ||
|
||
### Setting the object to the state | ||
Next, we'll assign an object to the state and include it in a subcomponent where we can access and use it. | ||
|
||
### Using the object in other components | ||
With the mesh assigned to the reactive state, it's available throughout your project. | ||
|
||
::: code-group | ||
|
||
```vue [App.vue] | ||
<script setup lang="ts"> | ||
import { BoxGeometry, Mesh, MeshNormalMaterial } from 'three'; | ||
|
||
import SubComponent from './SubComponent.vue'; | ||
import { useState } from '../composables/state'; | ||
|
||
const { mesh } = useState(); | ||
|
||
//assinging the object to the state | ||
mesh.value = new Mesh(new BoxGeometry(), new MeshNormalMaterial()); | ||
</script> | ||
|
||
<template> | ||
<TresPerspectiveCamera /> | ||
|
||
<SubComponent /> | ||
</template> | ||
``` | ||
|
||
```vue [Subcomponent.vue] | ||
<script setup lang="ts"> | ||
import { useState } from '../composables/state'; | ||
const { mesh } = useState(); | ||
|
||
</script> | ||
|
||
<template> | ||
<primitive v-if="mesh" :object="mesh" /> | ||
</template> | ||
``` | ||
|
||
```ts [composables/state.ts] | ||
import { reactive, toRefs } from "vue"; | ||
|
||
const state = reactive({ | ||
mesh: null, | ||
//you can add more objects here | ||
}) | ||
|
||
export function useState() { | ||
return { | ||
...toRefs(state) | ||
} | ||
} | ||
``` | ||
::: | ||
|
||
## Using TresMesh components | ||
|
||
You can also add TresMesh components to the reactive state. Here, we'll use a reference and assign it to the state when mounted. | ||
|
||
```vue | ||
<script setup lang="ts"> | ||
import { BoxGeometry, Mesh, MeshNormalMaterial } from 'three'; | ||
|
||
import SubComponent from './SubComponent.vue'; | ||
import { useState } from '../composables/state'; | ||
|
||
const { mesh } = useState(); | ||
|
||
//reference the object | ||
const exampleRef = ref(null); | ||
|
||
//assinging the object to the state when mounted | ||
onMounted(() => { | ||
mesh.value = exampleRef.value; | ||
}); | ||
</script> | ||
|
||
<template> | ||
<TresPerspectiveCamera /> | ||
|
||
<TresMesh ref="exampleRef" :position="[0, 0, 0]" cast-shadow> | ||
<TresBoxGeometry :args="[1.5, 1.5, 1.5]" /> | ||
<TresMeshToonMaterial color="#4F4F4F" /> | ||
</TresMesh> | ||
|
||
<SubComponent /> | ||
</template> | ||
``` | ||
|
||
## Using Pinia Store | ||
|
||
By using the same logic we can also use Pinia. | ||
By using pinia we also have full access to actions and getters. | ||
|
||
::: code-group | ||
|
||
```ts [model.ts] | ||
import { defineStore } from "pinia"; | ||
|
||
export const useModelStore = defineStore('model', { | ||
state: () => { | ||
return { | ||
exampleModel: null, | ||
} | ||
}, | ||
actions: {}, | ||
}); | ||
``` | ||
|
||
```vue [App.vue] | ||
<script setup lang="ts"> | ||
import { BoxGeometry, Mesh, MeshNormalMaterial } from 'three'; | ||
import { useModelStore } from '../stores/model'; | ||
|
||
const modelStore = useModelStore(); | ||
|
||
//reference the object | ||
const exampleRef = ref(null); | ||
|
||
//assinging the object to the state when mounted | ||
onMounted(() => { | ||
modelStore.exampleModel = exampleRef.value; | ||
}); | ||
</script> | ||
|
||
<template> | ||
<TresPerspectiveCamera /> | ||
|
||
<TresMesh ref="exampleRef" :position="[0, 0, 0]" cast-shadow> | ||
<TresBoxGeometry :args="[1.5, 1.5, 1.5]" /> | ||
<TresMeshToonMaterial color="#4F4F4F" /> | ||
</TresMesh> | ||
</template> | ||
``` | ||
|
||
::: | ||
|
||
With these steps, you can easily manage and share objects across different components in your Vue 3 project using a reactive composable. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @whitespacecode since the example doesn't rely on third party libs, can we replace this with a Tresjs repl playground https://play.tresjs.org/ ?
You can find an example on how here
tres/docs/cookbook/lights-shadows.md
Line 14 in 8d53bba
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @alvarosabu
I tried with the playground and i'm getting this error:
'get' on proxy: property 'modelViewMatrix' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<cr>' but got '#<cr>')
I tried a few things but i'm keep getting errors on the playground.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using play.tresjs