diff --git a/docs/.vitepress/config/de.ts b/docs/.vitepress/config/de.ts new file mode 100644 index 000000000..cb03dfcfd --- /dev/null +++ b/docs/.vitepress/config/de.ts @@ -0,0 +1,146 @@ +import type { DefaultTheme, LocaleSpecificConfig } from 'vitepress' + +export const deConfig: LocaleSpecificConfig = { + themeConfig: { + editLink: { + pattern: 'https://github.com/tresjs/tres/edit/main/packages/docs/:path', + text: 'Änderungen an dieser Seite vorschlagen', + }, + sidebar: [ + { + text: 'Anleitung', + items: [ + // Dies zeigt die Seite `/guide/index.md`. + { text: 'Einführung', link: '/de/guide/' }, + { text: 'Loslegen', link: '/de/guide/getting-started' }, + { text: 'Deine erste Szene', link: '/de/guide/your-first-scene' }, + { text: 'Nuxt', link: '/de/guide/nuxt' }, + { text: 'Fehlerbehebung', link: '/de/guide/troubleshooting' }, + { text: 'Migration von v1', link: '/de/guide/migration-guide' }, + ], + }, + { + text: 'API', + items: [ + { text: 'TresCanvas', link: '/de/api/tres-canvas' }, + { + text: 'Instanzen, Argumente und Props', + link: '/de/api/instances-arguments-and-props', + }, + { + text: 'Composables', + link: '/de/api/composables', + }, + { + text: 'Ereignisse', + link: '/de/api/events', + }, + ], + }, + + { + text: 'Fortgeschritten', + items: [ + { text: 'Erweitern', link: '/de/advanced/extending' }, + { text: 'Primitive', link: '/de/advanced/primitive' }, + { + text: 'Warnhinweise', + link: '/de/advanced/caveats', + }, + ], + }, + { + text: 'Debugging', + items: [ + { text: 'Entwicklungstools', link: '/de/debug/devtools' }, + ], + }, + { + text: 'Beispiele', + collapsed: true, + items: [ + { text: 'Orbit-Kontrollen', link: '/de/examples/orbit-controls' }, + { text: 'Grundlegende Animationen', link: '/de/examples/basic-animations' }, + { text: 'Gruppen', link: '/de/examples/groups' }, + { text: 'Texturen laden', link: '/de/examples/load-textures' }, + { text: 'Modelle laden', link: '/de/examples/load-models' }, + { text: 'Text laden', link: '/de/examples/text-3d' }, + { text: 'Lichter und Schatten', link: '/de/examples/lights-shadows' }, + { text: 'Shaders', link: '/de/examples/shaders' }, + ], + }, + { + text: 'Direktiven', + collapsed: true, + items: [ + { text: 'v-log', link: '/de/directives/v-log' }, + { text: 'v-light-helper', link: '/de/directives/v-light-helper' }, + { text: 'v-always-look-at', link: '/de/directives/v-always-look-at' }, + { text: 'v-distance-to', link: '/de/directives/v-distance-to' }, + ], + }, + { + text: 'Ökosystem', + items: [ + { + text: 'Cientos 💛', + link: 'https://cientos.tresjs.org/', + }, + { + text: 'Nuxt-Modul', + link: 'https://github.com/Tresjs/nuxt', + }, + { + text: 'TresLeches 🍰', + link: 'https://tresleches.tresjs.org/', + }, + { + text: 'Nachbearbeitung (Demnächst)', + }, + ], + }, + ], + nav: [ + { text: 'Anleitung', link: '/de/guide/' }, + { text: 'API', link: '/de/api/tres-canvas' }, + /* { text: 'API', link: '/de/api/' }, + { text: 'Konfiguration', link: '/de/config/' }, */ + { + text: 'Ressourcen', + items: [ + { text: 'Team', link: '/de/team' }, + { text: 'Versionen', link: 'https://github.com/Tresjs/tres/releases' }, + { + text: 'Spielplatz', + link: 'https://playground.tresjs.org/', + }, + { + text: 'Github', + link: 'https://github.com/Tresjs/tres/', + }, + { + text: 'Probleme', + link: 'https://github.com/Tresjs/tres/issues', + }, + { + text: 'Ökosystem', + items: [ + { + text: 'Hunderte 💛', + link: 'https://cientos.tresjs.org/', + }, + { + text: 'Nuxt-Modul', + link: 'https://github.com/Tresjs/nuxt', + }, + { + text: 'TresLeches 🍰', + link: 'https://tresleches.tresjs.org/', + }, + ], + }, + ], + }, + ], + }, +} \ No newline at end of file diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts index 0a55fb5c3..534f4c6fd 100644 --- a/docs/.vitepress/config/index.ts +++ b/docs/.vitepress/config/index.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vitepress' import { enConfig } from './en' import { esConfig } from './es' +import { deConfig } from './de' import { sharedConfig } from './shared' /* import { zhConfig } from './zh' */ @@ -11,6 +12,7 @@ export default defineConfig({ locales: { root: { label: 'English', lang: 'en-US', link: '/', ...enConfig }, es: { label: 'Español', lang: 'es-ES', link: '/es/', ...esConfig }, + de: { label: 'Deutsch', lang: 'de-DE', link: '/de/', ...deConfig }, /* zh: { label: '简体中文', lang: 'zh-CN', link: '/zh/', ...zhConfig }, */ }, }) \ No newline at end of file diff --git a/docs/de/advanced/caveats.md b/docs/de/advanced/caveats.md new file mode 100644 index 000000000..2b98fb78a --- /dev/null +++ b/docs/de/advanced/caveats.md @@ -0,0 +1,120 @@ +# Avisos 😱 + +Nuestro objetivo es proporcionar una forma sencilla de utilizar ThreeJS en VueJS con la mejor experiencia de desarrollo posible. Sin embargo, hay algunas advertencias de las que debes ser consciente. + +## ~~HMR y ThreeJS~~ + +:::info + +Esto se ha solucionado en **TresJS** v1.7.0 🎉. Ahora puedes utilizar HMR sin tener que recargar la página 🥹. + +::: + +La sustitución de módulos en caliente (HMR) es una característica que te permite actualizar tu código sin recargar la página. Esta es una gran característica que hace que el desarrollo sea mucho más rápido. **TresJS** utiliza [Vite](https://vitejs.dev/). Sin embargo, es realmente complicado hacer que funcione correctamente con ThreeJS. + +¿Por qué? Porque Tres construye la escena de forma declarativa. Esto significa que crea la instancia y la añade a la escena cuando se monta el componente. La complejidad radica en saber cuándo quitar la instancia de la escena y cuándo añadirla de nuevo. + +Aunque se ha implementado un flujo de eliminación mínimo, no es perfecto. Esto significa que a veces tendrás que recargar la página para ver los cambios correctamente, especialmente cuando estás haciendo referencia a instancias utilizando [Template Refs](https://v3.vuejs.org/guide/component-template-refs.html) + +```vue + + + +``` + +Si realizas un cambio en el `color` del componente `TresMeshStandardMaterial`, verás que el cambio se aplica pero la rotación ya no funciona. Esto se debe a que la instancia se elimina y se crea de nuevo. + +:::tip +Entonces, como **regla general**, debes recargar la página cuando no veas los cambios que has realizado. +::: + +Dicho esto, estamos trabajando en una mejor solución para esto 😁. Si tienes alguna idea de cómo resolverlo, por favor avísanos. + +Puedes seguir la discusión en [HMR Disposal Discussion](https://github.com/Tresjs/tres/issues/23) + +## Reactividad + +Todos amamos la reactividad 💚. Es una de las características más poderosas de VueJS. Sin embargo, debemos tener cuidado al usar ThreeJS. + +La reactividad de Vue se basa en [Proxy](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Proxy). Esto permite que Vue 3 rastree automáticamente los cambios en los objetos de datos y actualice los elementos DOM correspondientes cada vez que los datos cambien. + +Dado que estamos renderizando una escena y actualizándola en cada fotograma (60FPS), eso significa que estamos actualizando la escena 60 veces por segundo. Si el objeto a actualizar es reactivo, Vue intentará actualizar ese objeto tantas veces. Esto no es una buena idea 😅 y será perjudicial para el rendimiento. + +Aquí tienes una prueba de rendimiento de la diferencia entre usar un objeto Proxy y un objeto plano. + +
+ Proxy vs Plain +
Fig.1 - Ejecuciones por segundo Objeto Plano vs Proxy.
+
+ +Fuente: [Proxy vs Plain Object](https://www.measurethat.net/Benchmarks/Show/12503/0/object-vs-proxy-vs-proxy-setter) + +Si te ves obligado a usar reactividad, utiliza [shallowRef](https://vuejs.org/api/reactivity-advanced.html#shallowref) + +A diferencia de `ref()`, el valor interno de un shallow ref se almacena y se expone tal cual, y no se hace reactividad profunda. Solo el acceso a `.value` es reactivo. Fuente [VueJS Docs](https://vuejs.org/api/reactivity-advanced.html#shallowref) + +### Ejemplo + +❌ Incorrecto + +```vue + + + +``` + +✅ Correcto + +```vue + + + +``` diff --git a/docs/de/advanced/extending.md b/docs/de/advanced/extending.md new file mode 100644 index 000000000..014d83b4c --- /dev/null +++ b/docs/de/advanced/extending.md @@ -0,0 +1,44 @@ +# Extender 🔌 + +Tres ofrece la funcionalidad básica, pero es fácil agregar elementos de terceros y extenderlos en su catálogo interno. + +La mayoría de las experiencias en 3D utilizan `OrbitControls`, que no forma parte de la biblioteca principal. Puedes agregarlo a tu proyecto importándolo desde el módulo `three/addons/controls/OrbitControls`. + +```js +import { OrbitControls } from 'three/addons/controls/OrbitControls' +``` + +## Extender un elemento dinámicamente + +También puedes agregarlo dinámicamente en tus componentes: + +```vue {2,3,4,7,13,15} + + + +``` diff --git a/docs/de/advanced/primitive.md b/docs/de/advanced/primitive.md new file mode 100644 index 000000000..30039a93b --- /dev/null +++ b/docs/de/advanced/primitive.md @@ -0,0 +1,47 @@ +# Primitives + +El componente `` es un componente versátil de bajo nivel en TresJS que te permite utilizar directamente cualquier objeto de three.js dentro de tu aplicación Vue sin una abstracción. Actúa como un puente entre el sistema de reactividad de Vue y el grafo de escena de three.js. + +## Usage + +```html + + + +``` + +## Props + +`object`: Esta propiedad espera un objeto `Object3D` de three.js o cualquiera de sus clases derivadas. Es el objeto principal que el componente `` renderizará. En el ejemplo actualizado, se pasa un objeto `Mesh` con su correspondiente `Material` a esta propiedad. + +## Uso con Modelos + +El componente `` es especialmente útil para renderizar objetos complejos como modelos cargados desde fuentes externas. El siguiente ejemplo muestra cómo cargar un modelo desde un archivo GLTF y renderizarlo utilizando el componente ``. + +```html + + + + + + + +``` diff --git a/docs/de/api/composables.md b/docs/de/api/composables.md new file mode 100644 index 000000000..61f7d39be --- /dev/null +++ b/docs/de/api/composables.md @@ -0,0 +1,236 @@ +# Composables + +La API de Composición de Vue 3 [Composition API](https://vuejs.org/guide/extras/composition-api-faq.html#what-is-composition-api) te permite crear lógica reutilizable que se puede compartir entre componentes. También te permite crear hooks personalizados que se pueden utilizar en tus componentes. + +**TresJS** aprovecha al máximo esta API para crear un conjunto de funciones composables que se pueden utilizar para crear animaciones, interactuar con la escena y más. También te permite crear escenas más complejas que podrían no ser posibles utilizando solo los Componentes de Vue (Texturas, Cargadores, etc.). + +El núcleo de **TresJS** utiliza estos composables internamente, por lo que estarías utilizando la misma API que utiliza el núcleo. Por ejemplo, los componentes que necesitan actualizarse en el bucle de renderizado interno utilizan el composable `useRenderLoop` para registrar un callback que se llamará cada vez que el renderizador actualice la escena. + +## useRenderLoop + +El composable `useRenderLoop` es el núcleo de las animaciones en **TresJS**. Te permite registrar un callback que se llamará en la frecuencia de actualización nativa. Este es el composable más importante en **TresJS**. + +```ts +const { onLoop, resume } = useRenderLoop() + +onLoop(({ delta, elapsed, clock, dt }) => { + // I will run at every frame ~60FPS (depending of your monitor) +}) +``` + +::: warning +Ten en cuenta las implicaciones de rendimiento al usar este composable. Se ejecutará en cada fotograma, por lo que si tienes mucha lógica en tu callback, podría afectar el rendimiento de tu aplicación. Especialmente si estás actualizando estados o referencias reactivas. +::: + +El callback `onLoop` recibe un objeto con las siguientes propiedades basadas en el [reloj de THREE](https://threejs.org/docs/?q=clock#api/en/core/Clock): + +- `delta`: El tiempo transcurrido entre el fotograma actual y el último fotograma. Este es el tiempo en segundos desde el último fotograma. +- `elapsed`: El tiempo transcurrido desde el inicio del bucle de renderizado. + +Este composable se basa en `useRafFn` de [vueuse](https://vueuse.org/core/useRafFn/). Gracias a [@wheatjs](https://github.com/orgs/Tresjs/people/wheatjs) por la increíble contribución. + +### Antes y después de renderizar + +También puedes registrar un callback que se llamará antes y después de que el renderizador actualice la escena. Esto es útil si agregas un perfilador para medir los FPS, por ejemplo. + +```ts +const { onBeforeLoop, onAfterLoop } = useRenderLoop() + +onBeforeLoop(({ delta, elapsed }) => { + // Se ejecutara antes del renderizado de la escena + fps.begin() +}) + +onAfterLoop(({ delta, elapsed }) => { + // Se ejecutara después del renderizado de la escena + fps.end() +}) +``` + +### Pausar y reanudar + +Puedes pausar y reanudar el bucle de renderizado utilizando los métodos `pause` y `resume` expuestos. + +```ts +const { pause, resume } = useRenderLoop() + +// Pausa el bucle de renderizado +pause() + +// Reanuda el bucle de renderizado +resume() +``` + +También puedes obtener el estado activo del bucle de renderizado utilizando la propiedad `isActive`. + +```ts +const { resume, isActive } = useRenderLoop() + +console.log(isActive) // false + +resume() + +console.log(isActive) // true +``` + +## useLoader + +El composable `useLoader` te permite cargar recursos utilizando los [cargadores de THREE.js](https://threejs.org/docs/#manual/en/introduction/Loading-3D-models). Retorna una promesa con el recurso cargado. + +```ts +import { GLTFLoader } from 'three/addons/loaders/GLTFLoader' + +const { scene } = await useLoader(THREE.GLTFLoader, 'path/to/asset.gltf') +``` + +Dado que el composable `useLoader` devuelve una promesa, puedes usarlo con `async/await` o `then/catch`. Si lo estás utilizando en un componente, asegúrate de envolverlo con un componente `Suspense`. Consulta [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense) para obtener más información. + +```vue + +``` + +## useTexture + +El composable `useTexture` te permite cargar texturas utilizando el [cargador de texturas de THREE.js](https://threejs.org/docs/#api/en/loaders/TextureLoader). Retorna una promesa con la(s) textura(s) cargada(s). + +```ts +const texture = await useTexture(['path/to/texture.png']) +``` + +**useTexture** también acepta un objeto con las siguientes propiedades: + +- `map`: una textura básica que se aplica a la superficie de un objeto +- `displacementMap`: una textura que se utiliza para agregar protuberancias o indentaciones a la superficie del objeto +- `normalMap`: una textura que se utiliza para agregar detalles de superficie y variaciones en el sombreado al objeto +- `roughnessMap`: una textura que se utiliza para agregar rugosidad o un acabado mate a la superficie del objeto +- `metalnessMap`: una textura que se utiliza para agregar un efecto metálico a la superficie del objeto +- `aoMap`: una textura que se utiliza para agregar oclusión ambiental (sombreado en áreas donde la luz es bloqueada por otros objetos) al objeto. +- `alphaMap`: una textura que se utiliza para agregar transparencia (la parte negra se renderiza como transparente) al objeto. Es necesario establecer :transparent="true" en el material para usar este mapa. +- `matcap`: esta textura codifica el color y el sombreado del material. + +En ese caso, devolverá un objeto con las texturas cargadas. + +```ts +const { map, displacementMap, normalMap, roughnessMap, metalnessMap, aoMap, alphaMap, matcap } = 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', + alphaMap: 'path/to/alpha.png', + matcap: 'path/to/matcap.png', +}) +``` + +Luego puedes vincular las texturas al material. + +```vue + +``` + +Similar al composable anterior, el composable `useTexture` devuelve una promesa, puedes usarlo con `async/await` o `then/catch`. Si lo estás utilizando en un componente, asegúrate de envolverlo con un componente `Suspense`. + +## useSeek + +El composable `useSeek` proporciona utilidades para recorrer y navegar fácilmente a través de escenas y gráficos de objetos complejos de ThreeJS. Exporta 4 funciones que te permiten encontrar objetos secundarios basados en propiedades específicas. + +```ts +const { seek, seekByName, seekAll, seekAllByName } = useSeek() +``` + +La función `seek` acepta tres parámetros: + +- `parent`: Una escena ThreeJS u Object3D. +- `property`: La propiedad que se utilizará en la condición de búsqueda. +- `value`: El valor de la propiedad a coincidir. + +La función `seek` y `seekByName` recorren el objeto y devuelven el objeto hijo con la propiedad y valor especificados. Si no se encuentra ningún hijo con la propiedad y valor dados, devuelve null y registra una advertencia. + +```ts +const carRef = ref(null) + +watch(carRef, ({ model }) => { + if (model) { + const car = model.children[0] + + const body = seek(car, 'name', 'Octane_Octane_Body_0') + body.color.set(new Color('blue')) + } +}) +``` + +De manera similar, las funciones `seekAll` y `seekAllByName` devuelven un array de objetos secundarios cuya propiedad incluye el valor dado. Si no se encuentran coincidencias, devuelven un array vacío y se registra una advertencia. + +```ts +const character = ref(null) + +watch(character, ({ model }) => { + if (model) { + const bones = seekAll(character, type, 'Bone') + } +}) +``` + +## useTresContext +Este composable tiene como objetivo proporcionar acceso al modelo de estado que contiene múltiples propiedades útiles. + +```ts +const { camera, renderer, camera, cameras } = useTresContext() + +``` + +::: warning +`useTresContext` solo puede ser utilizado dentro de un `TresCanvas`, ya que `TresCanvas` actúa como el proveedor de los datos de contexto. Utiliza [el contexto expuesto por TresCanvas](tres-canvas#propiedades-públicas-expuestas) si necesitas acceder a él en componentes superiores a TresCanvas. +::: + +```vue + + + +``` + +```vue +// MyModel.vue + + +``` + +### Propiedades del contexto +| Propiedad | Descripción | +| --- | --- | +| **camera** | la cámara actualmente activa | +| **cameras** | las cámaras que existen en la escena | +| **controls** | los controles de tu escena | +| **deregisterCamera** | un método para cancelar el registro de una cámara. Esto solo es necesario si creas una cámara manualmente. Las cámaras en la plantilla se registran automáticamente. | +| **extend** | Extiende el catálogo de componentes. Ver [extending](/advanced/extending) | +| **raycaster** | el raycaster global utilizado para eventos de puntero | +| **registerCamera** | un método para registrar una cámara. Esto solo es necesario si creas una cámara manualmente. Las cámaras en la plantilla se registran automáticamente. | +| **renderer** | el [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) de tu escena | +| **scene** | la [escena](https://threejs.org/docs/?q=sce#api/en/scenes/Scene) | +| **setCameraActive** | un método para establecer una cámara activa | +| **sizes** | contiene el ancho, alto y relación de aspecto de tu lienzo | + diff --git a/docs/de/api/events.md b/docs/de/api/events.md new file mode 100644 index 000000000..8e979b663 --- /dev/null +++ b/docs/de/api/events.md @@ -0,0 +1,27 @@ +# Events + +**TresJS** los componentes emiten eventos de puntero cuando se interactúa con ellos. Esto es válido para los componentes que representan clases de three.js que derivan de [THREE.Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) (como mallas, grupos, ...). + + + +## Pointer Events + +```html + +``` + +| Event | se dispara cuando ... | Tipo(s) de parámetro del controlador de eventos | +| ------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| click   | ... los eventos pointerdown y pointerup se disparan en el mismo objeto uno tras otro | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/es/docs/Web/API/PointerEvent) | +| pointer-move | ... el puntero se mueve sobre el objeto | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/es/docs/Web/API/PointerEvent) | +| pointer-enter | ... el puntero entra en el objeto | [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16), [PointerEvent](https://developer.mozilla.org/es/docs/Web/API/PointerEvent) | +| pointer-leave | ... el puntero sale del objeto | [PointerEvent](https://developer.mozilla.org/es/docs/Web/API/PointerEvent) | + +La [Intersection](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/three/src/core/Raycaster.d.ts#L16) devuelta incluye el [Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) que desencadenó el evento. Puedes acceder a él a través de `intersection.object`. + +De forma predeterminada, los objetos posicionados delante de otros con controladores de eventos no evitan que se disparen esos eventos. Este comportamiento se puede lograr utilizando la propiedad `blocks-pointer-events`. diff --git a/docs/de/api/instances-arguments-and-props.md b/docs/de/api/instances-arguments-and-props.md new file mode 100644 index 000000000..7c5cc206d --- /dev/null +++ b/docs/de/api/instances-arguments-and-props.md @@ -0,0 +1,150 @@ +# Instancias + +La idea principal de **Tres** es un _catálogo autogenerado_ de todos los elementos de ThreeJS. Este catálogo se genera a partir del código fuente de ThreeJS, por lo que siempre está actualizado. + +Cuando usas ThreeJS, necesitas importar los elementos que deseas utilizar. Por ejemplo, si quieres usar una `PerspectiveCamera`, necesitas importarla desde el paquete `three`: + +```js +import { PerspectiveCamera } from 'three' + +const camera = new PerspectiveCamera(45, width / height, 1, 1000) +``` + +Con **Tres** no necesitas importar nada, esto se debe a que **Tres** genera automáticamente un **Componente Vue basado en el objeto Three que deseas usar en CamelCase con un prefijo Tres**. Por ejemplo, si quieres usar una `PerspectiveCamera`, puedes usar el componente ``. + +```vue + +``` + +Esto significa que puedes utilizar la misma [documentación](https://threejs.org/docs/) que usarías al utilizar ThreeJS básico, pero con el poder de Vue. + +## Declarando objetos + +Si seguimos este argumento, deberías poder definir una instancia de esta manera: ❌ + +```vue + +``` + +Pero con **Tres** esto no es necesario, puedes definir las propiedades de forma declarativa de la siguiente manera: ✅ + +```vue + +``` + +## Argumentos + +Algunos objetos de ThreeJS tienen argumentos, por ejemplo, el constructor `PerspectiveCamera` tiene los siguientes argumentos: + +- `fov` - Campo de visión vertical de la cámara. +- `aspect` - Relación de aspecto del frustum de la cámara. +- `near` - Plano cercano del frustum de la cámara. +- `far` - Plano lejano del frustum de la cámara. + +Para pasar estos argumentos al componente `TresPerspectiveCamera`, puedes usar la propiedad `args`: + +```vue + +``` + +Esto es lo mismo que hacer esto: + +```ts +const camera = new PerspectiveCamera(45, 1, 0.1, 1000) +``` + +## Propiedades + +También puedes pasar propiedades al componente, por ejemplo, el `TresAmbientLight` tiene una propiedad `intensity`, por lo que puedes pasarla al componente de la siguiente manera: + +```html + +``` + +### Establecer + +Todas las propiedades cuyo objeto subyacente tiene un método `.set()` tienen un atajo para recibir el valor como un array. Por ejemplo, el `TresPerspectiveCamera` tiene una propiedad `position`, que es un objeto `Vector3`, por lo que puedes pasarlo al componente de esta manera: + +```html + +``` + +Para especificar propiedades de transformación como posición, rotación y escala, hay una forma abreviada disponible que te permite indicar directamente el eje que deseas establecer dentro de las propiedades. Una forma abreviada similar también está disponible para la propiedad de color. + + +```html + + + +``` + +::: warning +Cuando estableces la propiedad de rotación en [three.js](https://threejs.org/docs/index.html#api/en/math/Euler), se utilizará el orden 'XYZ' de forma predeterminada. +Es importante tener en cuenta que al establecer la propiedad de rotación con la forma abreviada, el orden en el que estableces los ángulos importa. Para obtener más información sobre este tema, consulta [Ángulos de Euler](https://es.wikipedia.org/wiki/%C3%81ngulos_de_Euler) +::: + +```vue + + + + + +``` + +### Escalar + +Otro atajo que puedes usar es pasar un valor escalar a una propiedad que espera un objeto `Vector3`, usando el mismo valor para el resto del vector: + +```html + ✅ +``` + +```html + ✅ +``` + +### Colores + +Puedes pasar colores a los componentes usando la propiedad `color`, la cual acepta un string con el nombre del color o un valor hexadecimal: + +```html + ✅ +``` + +```html + ✅ +``` + +### Métodos + +Algunas propiedades subyacentes son en realidad métodos, el `TresPerspectiveCamera` tiene un método `lookAt` heredado de [Object3d](https://threejs.org/docs/#api/en/core/Object3D.lookAt), por lo que puedes pasarle las coordenadas al componente de esta manera: + +```html + +``` diff --git a/docs/de/api/tres-canvas.md b/docs/de/api/tres-canvas.md new file mode 100644 index 000000000..5502c0e62 --- /dev/null +++ b/docs/de/api/tres-canvas.md @@ -0,0 +1,105 @@ +# TresCanvas + +El componente `TresCanvas` es el componente principal de Tres. Es el que crea el `WebGLRenderer` de ThreeJS. + +```vue{2,5} + +``` + +## Tamaño del lienzo + +El componente `TresCanvas` utilizará el tamaño del elemento padre como tamaño del lienzo. Si deseas utilizar el tamaño de la ventana como tamaño del lienzo, puedes establecer la propiedad `window-size` en `true`. + +```vue + +``` + +Or you can use CSS to set your canvas size. + +```css +html, +body { + margin: 0; + padding: 0; + height: 100%; + width: 100%; +} +#canvas { + height: 100%; + width: 100%; +} +``` + +## Presets + +Tres viene con algunos presets para el componente `TresCanvas`. Puedes usarlos estableciendo la propiedad `preset`. + +### Realista + +El preset `realista` facilita la configuración del renderizador para escenas 3D más realistas. + +```vue + +``` + +It's equivalent to: + +```ts +renderer.shadows = true +renderer.physicallyCorrectLights = true +renderer.outputColorSpace = SRGBColorSpace +renderer.toneMapping = ACESFilmicToneMapping +renderer.toneMappingExposure = 3 +renderer.shadowMap.enabled = true +renderer.shadowMap.type = PCFSoftShadowMap +``` + +## Props + +| Prop | Descripción | Valor por defecto | +| ---- | ---- | --- | +| **alpha** | Controla el valor alfa predeterminado. Cuando se establece en true, el valor es 0. De lo contrario, es 1. | false | +| **antialias** | Indica si se debe realizar el antialiasing. | `true` | +| **camera** | Una cámara manual que se utilizará por el renderizador. | | +| **clearColor** | El color que el renderizador utilizará para borrar el lienzo. | `#000000` | +| **context** | Esto se puede usar para adjuntar el renderizador a un [RenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) existente. | | +| **depth** | Indica si el búfer de dibujo tiene un [búfer de profundidad](https://en.wikipedia.org/wiki/Z-buffering) de al menos 16 bits. | `true` | +| **disableRender** | Desactiva el renderizado en requestAnimationFrame, útil para PostProcessing. | `false` | +| **failIfMajorPerformanceCaveat** | Indica si la creación del renderizador fallará si se detecta un bajo rendimiento. Consulta la [especificación de WebGL](https://registry.khronos.org/webgl/specs/latest/1.0/#5.2) para más detalles. | `false` | +| **logarithmicDepthBuffer** | Indica si se debe utilizar un búfer de profundidad logarítmico. Puede ser necesario utilizar esto si se manejan diferencias enormes de escala en una sola escena. Ten en cuenta que esta configuración utiliza gl_FragDepth si está disponible, lo cual deshabilita la optimización [Early Fragment Test](https://www.khronos.org/opengl/wiki/Early_Fragment_Test) y puede causar una disminución en el rendimiento. | `false` | +| **outputColorSpace** | Define la codificación de salida. | `LinearEncoding` | +| **powerPreference** | Proporciona una sugerencia al agente de usuario que indica qué configuración de GPU es adecuada para este contexto WebGL. Puede ser "high-performance", "low-power" o "default". | `default` | +| **precision** | Precisión del shader. Puede ser "highp", "mediump" o "lowp". | "highp" si es compatible con el dispositivo | +| **premultipliedAlpha** | Indica si el renderizador asumirá que los colores tienen [alfa premultiplicado](https://en.wikipedia.org/wiki/Glossary_of_computer_graphics#premultiplied_alpha). | `true` | +| **preserveDrawingBuffer** | Indica si se deben preservar los búferes hasta que se borren o se sobrescriban manualmente. | `false` | +| **shadows** | Habilita las sombras en el renderizador. | `false` | +| **shadowMapType** | Establece el tipo de mapa de sombras. | `PCFSoftShadowMap` | +| **stencil** | Indica si el búfer de dibujo tiene un [búfer de stencil](https://en.wikipedia.org/wiki/Stencil_buffer) de al menos 8 bits. | `true` | +| **toneMapping** | Define la exposición de mapeo de tonos utilizada por el renderizador. | `NoToneMapping` | +| **toneMappingExposure** | Nivel de exposición del mapeo de tonos. | `1` | +| **useLegacyLights** | Indica si se debe utilizar el modo de iluminación heredado o no. | `true` | +| **windowSize** | Indica si se debe utilizar el tamaño de la ventana como el tamaño del lienzo o el elemento padre. | `false` | + +### Valores predeterminados + +Tres intenta ser lo menos opinado posible. Es por eso que no establece casi ningún valor predeterminado para el componente `TresCanvas`. Utiliza los valores predeterminados de [three.js](https://threejs.org/). La única excepción es la propiedad `antialias`, que se establece en `true` de forma predeterminada. + +## Propiedades públicas expuestas + +| Propiedad | Descripción | +| ---- | ---- | +| context | ver [useTresContext](composables#usetrescontext) | + diff --git a/docs/de/debug/devtools.md b/docs/de/debug/devtools.md new file mode 100644 index 000000000..135d01e7a --- /dev/null +++ b/docs/de/debug/devtools.md @@ -0,0 +1,26 @@ +# Herramientas de desarrollo + +Una de las cosas más difíciles a las que se enfrenta un desarrollador al crear experiencias 3D en el navegador es la depuración. El `canvas` del navegador es una caja negra y es difícil saber qué está sucediendo en su interior. La naturaleza imperativa de [ThreeJS](https://threejs.org/) hace que sea increíblemente difícil depurar, teniendo que depender de `console.log` para ver qué está sucediendo, o de terceros para ajustar y inspeccionar la escena. + +No me hagas empezar con la comprobación del rendimiento de tu escena. 😱 + +![desarrollador depurando 3D](/debug-3D.png) + +Uno de nuestros objetivos con TresJS es ofrecer **la mejor experiencia de desarrollo (DX, por sus siglas en inglés)** al trabajar con escenas 3D en el navegador. Gracias a la naturaleza declarativa del ecosistema y a la variedad de soluciones que ofrece el ecosistema de Vue, como Vue Devtools, Nuxt y Vite, podemos ofrecer mejores herramientas para que los desarrolladores depuren sus escenas. + +## Presentando las Herramientas de Desarrollo + +A partir de la versión , estamos introduciendo las Herramientas de Desarrollo de TresJS, una pestaña de inspector personalizada para las [Herramientas de Desarrollo de Chrome oficiales de Vue](https://devtools.vuejs.org/guide/installation.html) que te permite inspeccionar tus escenas y componentes de TresJS. + +![Herramientas de Desarrollo de TresJS](/vue-chrome-devtools.png) + +### Características + +- **Inspector de Escena**: Inspecciona la escena actual y sus componentes utilizando una vista en árbol similar al inspector de componentes de Vue Devtools. +- **Asignación de Memoria**: Muestra cuánta memoria está utilizando cada componente. +- **Inspector de Objetos**: Inspecciona las propiedades del objeto seleccionado en la escena, incluidos sus hijos. +- **Propiedades Editables**: Y sí, puedes editar las propiedades del objeto seleccionado y ver los cambios en tiempo real. + +![](/devtools-scene-inspector.png) + +¡Disfruta de las nuevas Herramientas de Desarrollo y dinos qué opinas! 🎉 diff --git a/docs/de/examples/basic-animations.md b/docs/de/examples/basic-animations.md new file mode 100644 index 000000000..3cb3efd57 --- /dev/null +++ b/docs/de/examples/basic-animations.md @@ -0,0 +1,89 @@ +# Basic Animations + +Esta guía te ayudará a comenzar con animaciones básicas en TresJS. + +Construiremos una escena simple con un cubo. Luego animaremos el cubo para que rote alrededor del eje Y y Z. + + + +## useRenderLoop + +El composable `useRenderLoop` es el núcleo de las animaciones en TresJS. Te permite registrar una función de devolución de llamada que se ejecutará cada vez que el renderizador actualice la escena con la frecuencia de actualización del navegador. + +Para obtener una explicación detallada de cómo funciona, consulta la documentación de [useRenderLoop](/api/composables#userenderloop). + +```ts +const { onLoop } = useRenderLoop() + +onLoop(({ delta, elapsed }) => { + // Se ejecutará en cada fotograma ~ 60FPS (dependiendo de tu monitor) +}) +``` + +## Obteniendo la referencia al cubo + +Para animar el cubo, necesitamos obtener una referencia a él. Podemos hacerlo pasando una [Referencia de Plantilla](https://vuejs.org/guide/essentials/template-refs.html) utilizando la propiedad `ref` en el componente `TresMesh`. Esto nos devolverá la instancia de THREE. + +Para mejorar el rendimiento, utilizaremos una [Referencia Superficial](https://v3.vuejs.org/guide/reactivity-fundamentals.html#shallow-reactivity) para almacenar la referencia en lugar de una referencia regular. Puedes ver por qué [aquí](../advanced/caveats.md#reactivity) + +```vue + + + +``` + +## Animando el cubo + +Ahora que tenemos una referencia al cubo, podemos animarlo. Utilizaremos la devolución de llamada `onLoop` para actualizar la rotación del cubo. + +```ts +onLoop(({ delta, elapsed }) => { + if (boxRef.value) { + boxRef.value.rotation.y += delta + boxRef.value.rotation.z = elapsed * 0.2 + } +}) +``` + +También puedes usar el `delta` del [reloj interno de THREE](https://threejs.org/docs/?q=clock#api/en/core/Clock) o el `elapsed` para animar el cubo. + +## ¿Pero por qué no usar la reactividad? + +Es posible que te preguntes por qué no estamos usando la reactividad para animar el cubo. La respuesta es simple: rendimiento. + +```vue +// Esto es una mala idea ❌ + +``` + +Podemos sentirnos tentados a usar la reactividad para animar el cubo. Pero sería una mala idea. +La razón es que [la reactividad de Vue se basa en Proxies](https://vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue) y no está diseñada para ser utilizada en un bucle de renderizado que se actualiza 60 o más veces por segundo. + +La página incrustada a continuación muestra la [prueba de rendimiento de un proxy frente a un objeto regular](https://measurethat.net/Benchmarks/Show/12503/0/object-vs-proxy-vs-proxy-setter). Como puedes ver, el proxy es 5 veces más lento que el objeto regular. + + + +Puedes leer más sobre esto en la sección de [Caveats](../advanced/caveats.md#reactivity). diff --git a/docs/de/examples/groups.md b/docs/de/examples/groups.md new file mode 100644 index 000000000..be698c22e --- /dev/null +++ b/docs/de/examples/groups.md @@ -0,0 +1,32 @@ +# Grupo + +Un `` es una instancia de la clase [THREE.Group](https://threejs.org/docs/#api/en/objects/Group) que es casi lo mismo que un [THREE.Object3D](https://threejs.org/docs/#api/en/objects/Object3D) pero te permite **agrupar varios objetos en la escena** para que puedan ser manipulados como una unidad única (transformación, rotación, etc). + +## Uso + +```vue{13,22} + + +``` diff --git a/docs/de/examples/lights-shadows.md b/docs/de/examples/lights-shadows.md new file mode 100644 index 000000000..120edd15b --- /dev/null +++ b/docs/de/examples/lights-shadows.md @@ -0,0 +1,175 @@ +# Luces y sombras + +Esta guía te ayudará a comenzar con luces y sombras simples en TresJS. + +Construiremos una escena simple con tres mallas y un plano, pero solo dos tendrán sombras. + + + +## Configurando la escena (opcional) + +Importamos todos los módulos que necesitamos, para mayor comodidad podemos usar orbit-controls de cientos, +[ver aquí para saber cómo](/examples/orbit-controls). + +Coloquemos cuatro objetos en nuestra escena, uno será el plano que recibirá sombras, dos de ellos proyectarán sombras y el último no proyectará ninguna sombra en absoluto. + +Voy a usar [MeshToonMaterial](https://threejs.org/docs/index.html?q=toon#api/en/materials/MeshToonMaterial). Simplemente porque podemos ver fácilmente el "sobreado suave". + +```vue + + + +``` + +## Luces (explicación) + +Como sabes, cada instancia en [ThreeJs](https://threejs.org/) está disponible en **TresJs**, por lo que todos los tipos de luces también están disponibles, solo necesitamos agregar el prefijo `Tres` para usarlos. + +Pero no todas las luces pueden generar sombras, esta definición proviene directamente de ThreeJs y tiene sentido. Por ejemplo, el propósito de una [ambientLight](https://threejs.org/docs/index.html?q=ambient#api/en/lights/AmbientLight) es iluminar todos los lados de tu escena, por lo que no tiene sentido que genere sombras. En cambio, una [DirectionalLight](https://threejs.org/docs/index.html?q=light#api/en/helpers/DirectionalLightHelper) que imita al sol puede y debe generar sombras. + +## Sombras (explicación) + +También existen muchos tipos de sombras, por ejemplo, la "sombra suave" se genera automáticamente cuando un objeto recibe más luz de un lado, pero en resumen, una "sombra predeterminada de ThreeJS" que se dirige hacia otra superficie debe ser proyectada por una malla y otra malla debe recibirla. Como vemos en nuestro ejemplo, el `Plano` está recibiendo una sombra pero no la está proyectando. Ten en cuenta que no todos los materiales pueden proyectar o recibir sombras. + +Internamente, ThreeJS genera automáticamente una nueva malla con un [ShadowMaterial](https://threejs.org/docs/index.html?q=shado#api/en/materials/ShadowMaterial) que se actualiza en cada fotograma, por eso si aplicas animaciones, la sombra también se anima, pero también es por eso que debes usar las sombras con cuidado, ya que pueden ralentizar el rendimiento. + +::: warning +El uso excesivo de sombras de esta manera puede afectar el rendimiento. Sin embargo, existen formas de mejorar el rendimiento. Para obtener más información, consulta [este video](https://youtu.be/WGNvVGrS0kY?si=q7XyL5eABKUh3gbS&t=1256) +::: + +## Habilitando las sombras + +Podemos dividir esto en tres pasos: + +### Activar las sombras en el renderizador + +```vue +//... + + +``` +### Configurar la luz para proyectar sombras + +Podemos simplemente agregar el booleano `cast-shadow`, Vue lo interpreta como una `prop` con valor `true`. + +_La luz ambiental no genera ningún tipo de sombra aquí_ + +```vue +//... + + +``` +### Establecer los objetos para proyectar o recibir sombras + +De manera similar al paso anterior, configuramos la malla que queremos que proyecte sombra (nuestra esfera) con la propiedad `cast-shadow`, y configuramos el objeto para recibir sombra (nuestro plano) con la propiedad `receive-shadow`. + +```vue +//... + + +``` + +Ahora tenemos todos los pasos necesarios para agregar sombras a nuestra escena, y si aplicamos lo que aprendimos en [animaciones básicas](/examples/basic-animations), y agregamos movimiento a nuestro cubo, verás que la sombra también se anima 🤩 + +```vue + + + +``` + +_Nota que intencionalmente no apliqué `cast-shadow` al `Cone` para que no proyecte ninguna sombra_ diff --git a/docs/de/examples/load-models.md b/docs/de/examples/load-models.md new file mode 100644 index 000000000..ada3bfdda --- /dev/null +++ b/docs/de/examples/load-models.md @@ -0,0 +1,140 @@ +# Cargar Modelos + +> Todos los modelos utilizados en esta guía son de [Alvaro Saburido](https://sketchfab.com/3d-models/aku-aku-7dfcb6edf10b4098bbb965c56fd3055c). + +Los modelos 3D están disponibles en cientos de formatos de archivo, cada uno con diferentes propósitos, características variadas y complejidad variable. + +Para esta guía, nos vamos a centrar en cargar modelos gLTF (GL Transmission Format), que son el formato más común para modelos 3D en la web. + + + +Hay varias formas de cargar modelos en TresJS: + +::: warning +Por favor, ten en cuenta que en los ejemplos anteriores utilizamos el await de nivel superior, asegúrate de envolverlo con un componente [Suspense](https://vuejs.org/guide/built-ins/suspense.html#suspense). Consulta Suspense para obtener más información. +::: + +## Usando `useLoader` + +El composable `useLoader` te permite pasar cualquier tipo de cargador de three.js y una URL para cargar el recurso. Devuelve una `Promise` con el recurso cargado. + +Para obtener una explicación detallada de cómo usar `useLoader`, consulta la documentación de [useLoader](/api/composables#useloader). + +```ts +import { useLoader } from '@tresjs/core' +import { GLTFLoader } from 'three/addons/loaders/GLTFLoader' + +const { scene } = await useLoader(GLTFLoader, '/models/AkuAku.gltf') +``` + +Luego puedes pasar la escena del modelo a un componente [`primitive`](/advanced/primitive) de TresJS para renderizarlo: + +```html{2} + + + +``` + +> El componente `` no es un componente independiente en el código fuente de Tres. En su lugar, es parte de la funcionalidad principal de Tres. Cuando usas ``, se traduce a una llamada a `createElement`, que crea el objeto three.js adecuado según la propiedad "object" proporcionada. + +Observa en el ejemplo anterior que estamos utilizando el componente `Suspense` para envolver el componente `TresCanvas`. Esto se debe a que `useLoader` devuelve una `Promise` y necesitamos esperar a que se resuelva antes de renderizar la escena. + +## Usando `useGLTF` + +Una forma más conveniente de cargar modelos es utilizando el composable `useGLTF` disponible en el paquete [@tresjs/cientos](https://github.com/Tresjs/tres/tree/main/packages/cientos). + +```ts +import { useGLTF } from '@tresjs/cientos' + +const { scene, nodes, animations, materials } = await useGLTF('/models/AkuAku.gltf') +``` + +Una ventaja de usar `useGLTF` es que puedes pasar una propiedad `draco` para habilitar la [compresión Draco](https://threejs.org/docs/index.html?q=drac#examples/en/loaders/DRACOLoader) para el modelo. Esto reducirá el tamaño del modelo y mejorará el rendimiento. + +```ts +import { useGLTF } from '@tresjs/cientos' + +const { scene, nodes, animations, materials } = await useGLTF('/models/AkuAku.gltf', { draco: true }) +``` + +Alternativamente, puedes seleccionar fácilmente objetos dentro del modelo utilizando la propiedad `nodes`. + +```vue + + + +``` + +## Usando `GLTFModel` + +El componente `GLTFModel` es un envoltorio alrededor de `useGLTF` que está disponible en el paquete [@tresjs/cientos](https://github.com/Tresjs/tres/tree/main/packages/cientos). + +```vue{2,9} + + +``` + +Este enfoque en particular es más sencillo pero te brinda menos control sobre el modelo. + +## useFBX + +El composable `useFBX` está disponible en el paquete [@tresjs/cientos](https://github.com/Tresjs/tres/tree/main/packages/cientos). + +```ts +import { useFBX } from '@tresjs/cientos' + +const model = await useFBX('/models/AkuAku.fbx') +``` + +Entonces, es tan sencillo como agregar la escena a tu escena: + +```html{2} + + + +``` + +## FBXModel + +El componente `FBXModel` es un envoltorio alrededor de `useFBX` que está disponible en el paquete [@tresjs/cientos](https://github.com/Tresjs/tres/tree/main/packages/cientos). Su uso es similar al de `GLTFModel`: + +```vue{2,9} + + +``` diff --git a/docs/de/examples/load-textures.md b/docs/de/examples/load-textures.md new file mode 100644 index 000000000..888e52936 --- /dev/null +++ b/docs/de/examples/load-textures.md @@ -0,0 +1,78 @@ +# Cargar Texturas + +> Todas las texturas utilizadas en este ejemplo son de [ambientcg](https://ambientcg.com/). + +Las texturas tridimensionales (3D) son imágenes que contienen múltiples capas de datos, lo que les permite representar volumen o simular estructuras tridimensionales. Estas texturas se utilizan comúnmente en gráficos 3D y efectos visuales para mejorar el realismo y la complejidad de escenas y objetos. + + + +Hay dos formas de cargar texturas 3D en TresJS: + +## Usando `useLoader` + +El composable `useLoader` te permite pasar cualquier tipo de cargador de three.js y una URL para cargar el recurso. Retorna una `Promise` con el recurso cargado. + +Para obtener una explicación detallada de cómo usar `useLoader`, consulta la documentación de [useLoader](/api/composables#use-loader). + +```ts +import { useLoader } from '@tresjs/core' +import { TextureLoader } from 'three' + +const texture = useLoader(TextureLoader, '/Rock035_2K_Color.jpg') +``` + +Luego puedes pasar la textura a un material: + +```html + + + + + + + + +``` + +Observa en el ejemplo anterior que estamos utilizando el componente `Suspense` para envolver el componente `TresCanvas`. Esto se debe a que `useLoader` devuelve una `Promise` y necesitamos esperar a que se resuelva antes de renderizar la escena. + +## Usando `useTexture` + +Una forma más conveniente de cargar texturas es utilizando el composable `useTexture`. Acepta tanto un array de URLs como un objeto único con los caminos de las texturas mapeadas. + +Para obtener más información sobre `useTexture`, consulta la documentación de [useTexture](/api/composables#use-texture). + +```ts +import { useTexture } from '@tresjs/core' + +const pbrTexture = await useTexture({ + map: '/textures/black-rock/Rock035_2K_Displacement.jpg', + displacementMap: '/textures/black-rock/Rock035_2K_Displacement.jpg', + roughnessMap: '/textures/black-rock/Rock035_2K_Roughness.jpg', + normalMap: '/textures/black-rock/Rock035_2K_NormalDX.jpg', + aoMap: '/textures/black-rock/Rock035_2K_AmbientOcclusion.jpg', + metalnessMap: '/textures/black-rock/myMetalnessTexture.jpg', + matcap: '/textures/black-rock/myMatcapTexture.jpg', + alphaMap: '/textures/black-rock/myAlphaMapTexture.jpg' +}) +``` +Similar to the previous example, we can pass all the textures to a material via props: + +Al igual que en el ejemplo anterior, podemos pasar todas las texturas a un material a través de props: + +```html + + + + + + + + +``` diff --git a/docs/de/examples/orbit-controls.md b/docs/de/examples/orbit-controls.md new file mode 100644 index 000000000..4c70e71ef --- /dev/null +++ b/docs/de/examples/orbit-controls.md @@ -0,0 +1,104 @@ +# OrbitControls + + + +[OrbitControls](https://threejs.org/docs/index.html?q=orbit#examples/en/controls/OrbitControls) es un controlador de cámara que te permite orbitar alrededor de un objetivo. Es una excelente manera de explorar tu escena. + +Sin embargo, no forma parte del núcleo de ThreeJS. Por lo tanto, para usarlo, necesitarías importarlo desde el módulo `three/addons/controls/OrbitControls`. + +Esto crea un problema porque **TresJS** crea automáticamente un catálogo del núcleo de Three para que puedas usarlos como componentes. + +Afortunadamente, **TresJS** proporciona una forma de ampliar el catálogo de componentes. Puedes hacerlo utilizando el método `extend` de la biblioteca principal. + +Para obtener más información sobre cómo ampliar tu catálogo de TresJS, consulta la sección de [extensión](/advanced/extending.md). + +## Uso de OrbitControls + +Para usar `OrbitControls`, debes importarlo desde el módulo `three/addons/controls/OrbitControls`. + +```js +import { OrbitControls } from 'three/addons/controls/OrbitControls' +``` + +Luego, necesitas ampliar el catálogo de componentes utilizando el método `extend`. + +```js +import { extend } from '@tresjs/core' +import { OrbitControls } from 'three/addons/controls/OrbitControls' + +extend({ OrbitControls }) +``` + +Ahora puedes usar el componente `TresOrbitControls` en tu escena. + +```vue + +``` + +Dado que [OrbitControls](https://threejs.org/docs/index.html?q=orbit#examples/en/controls/OrbitControls) necesita una referencia a la cámara y al renderizador, debes pasarlos como argumentos. + +Puedes usar el composable [useTres](/api/composables#usetres) para obtener la cámara y el renderizador. + + +```ts +import { useTres } from '@tresjs/core' + +const { state } = useTres() +``` + +Entonces, el código final sería algo como esto: + +```vue + + + +``` + +## OrbitControls de `cientos` + +Aquí es donde comienza la parte interesante. ✨ +El paquete `cientos` proporciona un componente llamado `` que es un envoltorio de los `OrbitControls` del módulo [`three-stdlib`](https://github.com/pmndrs/three-stdlib). + +¿Lo mejor? No necesitas ampliar el catálogo ni pasar ningún argumento. +Simplemente funciona. 💯 + +```vue + +``` diff --git a/docs/de/examples/shaders.md b/docs/de/examples/shaders.md new file mode 100644 index 000000000..d567ba128 --- /dev/null +++ b/docs/de/examples/shaders.md @@ -0,0 +1,174 @@ +# Shaders + +Esta guía te ayudará a comenzar con los shaders en TresJS. + +Construiremos una escena simple con un blob. Luego alo animaremos para distorsionarlo suavemente. + +::: warning +_Es necesario tener conocimientos básicos sobre cómo funcionan los shaders_ +::: + + + +## Configurando la escena (opcional) + +Importamos todos los módulos que necesitamos. Para mayor comodidad, podemos usar los orbit-controls de cientos. +[Consulta aquí para ver cómo](/examples/orbit-controls). + +Ahora, coloquemos nuestra cámara en la posición `[11,11,11]`. + +Por último, para ayudarnos con la ubicación, agreguemos un plano simple, rotado en el eje X, con una medida de `[10, 10]` unidades. + +```vue + + + +``` + +## ShaderMaterial + +Como sabes, cada instancia en [ThreeJs](https://threejs.org/) está disponible en **TresJs**, por lo que también podemos usar el `ShaderMaterial`, solo necesitamos agregar el prefijo `Tres` para utilizarlo. + +Para nuestro blob, podríamos usar una simple `SphereGeometry` agregando algunos `widthSegments` y `heightSegments` para crear un efecto suave, y colocar nuestro blob 4 unidades en el eje Y positivo. + +```vue + + + + +``` + +El `ShaderMaterial` acepta propiedades especiales, como `uniforms`, `vertexShader` y `fragmentShader`, por lo que podemos crearlo en nuestra sección de script y hacer la conexión con nuestra instancia. + +Para este ejemplo, nuestros uniforms se ven así: + +```ts +import { Vector2 } from 'three' + +//... +const uniforms = { + uTime: { value: 0 }, + uAmplitude: { value: new Vector2(0.1, 0.1) }, + uFrequency: { value: new Vector2(20, 5) }, +} +//.. +``` + +Nuestro fragment shader se ve así: + +```ts +//... +const fragmentShader = ` +precision mediump float; +varying vec2 vUv; + +void main() { + gl_FragColor = vec4(1.0, vUv.y, 0.5, 1.0); +} +` +//.. +``` + +Y finalmente nuestro `vertexShader`: + +```ts +const vertexShader = ` +uniform vec2 uAmplitude; +uniform vec2 uFrequency; +uniform float uTime; + +varying vec2 vUv; + +void main() { + vec4 modelPosition = modelMatrix * vec4(position, 1.0); + modelPosition.y += sin(modelPosition.x * uFrequency.x - uTime) * uAmplitude.x; + modelPosition.x += cos(modelPosition.y * uFrequency.y - uTime) * uAmplitude.y; + + vec4 viewPosition = viewMatrix * modelPosition; + gl_Position = projectionMatrix * viewPosition; + vUv = uv; +} +` +//.. +``` + +## Animando el blob + +Similar a lo que aprendimos en el ejemplo de [Animaciones básicas](/examples/basic-animations), comenzamos haciendo referencia a nuestro blob utilizando [Template Ref](https://vuejs.org/guide/essentials/template-refs.html) + +```vue + + + +``` +Una vez que hayamos hecho eso, podemos usar el callback `onLoop` para animar nuestro `uTime`. + + ```ts +import { TresCanvas, useRenderLoop } from '@tresjs/core' + + //... + const { onLoop } = useRenderLoop() + +onLoop(({ elapsed }) => { + if (blobRef.value) { + blobRef.value.material.uniforms.uTime.value = elapsed + } +}) + //... +``` + +Y eso es todo, tenemos nuestro shader básico funcionando sin problemas. + +## Usando GLSL vite-plugin (opcional) + +_Este paso es completamente opcional y está fuera del alcance del equipo de **TresJs**_ + +Definir nuestro shader en línea no siempre es la mejor idea, pero si estás utilizando [vite](https://vitejs.dev/), puedes colocar tus archivos `GLSL` en un archivo diferente utilizando el [vite-plugin-glsl](https://www.npmjs.com/package/vite-plugin-glsl) (consulta el enlace para obtener la documentación oficial). + +Y podrías tener una estructura similar a esta: + +``` +├── src/ +│ ├── myTresJsComponent.vue +│ ├── shaders/ +│ ├── vertexShader.glsl +│ ├── fragmentShader.glsl +``` \ No newline at end of file diff --git a/docs/de/examples/text-3d.md b/docs/de/examples/text-3d.md new file mode 100644 index 000000000..5c3c972ef --- /dev/null +++ b/docs/de/examples/text-3d.md @@ -0,0 +1,194 @@ +# Texto3D + +[TextGeometry](https://threejs.org/docs/index.html?q=text#examples/en/geometries/TextGeometry) es una de las formas en las que podemos agregar texto en 3D a nuestra escena. + + + +Sin embargo, no forma parte del núcleo de ThreeJS. Por lo tanto, para usarlo, tendrías que importarlo desde el módulo `three/addons/controls/TextGeometry`. + +Esto crea un problema porque **TresJS** crea automáticamente un catálogo del núcleo de Three para que puedas usarlos como componentes. + +Afortunadamente, **TresJS** proporciona una forma de ampliar el catálogo de componentes. Puedes hacerlo utilizando el método `extend` de la biblioteca principal. + +Para obtener más información sobre cómo ampliar tu catálogo de TresJS, consulta la sección de [extending](/advanced/extending.md). + +## Usando TextGeometry + +Para usar `TextGeometry`, debes importarlo desde el módulo `three/addons/geometries/TextGeometry`. + +```js +import { TextGeometry } from 'three/addons/geometries/TextGeometry' +``` + +Luego, debes ampliar el catálogo de componentes utilizando el método `extend`. + +```js +import { extend } from '@tresjs/core' +import { TextGeometry } from 'three/addons/geometries/TextGeometry' + +extend({ TextGeometry }) +``` + +[TextGeometry](https://threejs.org/docs/index.html?q=text#examples/en/geometries/TextGeometry) necesita solo un argumento requerido, la fuente. Puedes ver un ejemplo a continuación. + +```js +const fontPath = 'https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json' + +const loader = new FontLoader() + +const font = await new Promise((resolve, reject) => { + try { + loader.load(fontPath, (font) => { + resolve(font) + }) + } + catch (error) { + reject(console.error('cientos', error)) + } +}) +``` + +Ahora puedes usar el componente `TresTextGeometry` dentro de un TresMesh en tu escena. + +```vue + +``` + +luego, como en el ejemplo, puedes pasar un objeto con las configuraciones deseadas. + +```ts +const fontOptions = { + size: 0.5, + height: 0.2, + curveSegments: 5, + bevelEnabled: true, + bevelThickness: 0.05, + bevelSize: 0.02, + bevelOffset: 0, + bevelSegments: 4, +} +``` + +También podemos pasar una matcapTexture para agregar detalles finales, utilizando TresMeshNormalMaterial dentro de TresMesh. + +```ts +const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png']) + + + + + +``` + +Entonces, el código final sería algo como esto: + +```vue + + + +``` + +Sé que parece mucho trabajo, pero tengo buenas noticias, hay una forma mucho más sencilla. + +## TextGeometry de `cientos` + +El paquete `cientos` proporciona un componente llamado `` que es un envoltorio de `TextGeometry` del módulo [`three-stdlib`](https://github.com/pmndrs/three-stdlib). + +¿Lo mejor? No necesitas extender el catálogo, solo pasa el argumento de la fuente. +Simplemente funciona. 💯 (si no se proporciona un texto, el texto será TresJS) + +```vue + +``` + +Podemos pasar las opciones como props + +```html + +``` + +en caso de que no se proporcionen las opciones, los valores predeterminados son: + +```js +size: 0.5, +height: 0.2, +curveSegments: 5, +bevelEnabled: true, +bevelThickness: 0.05, +bevelSize: 0.02, +bevelOffset: 0, +bevelSegments: 4, +``` + +De forma predeterminada, el texto en ThreeJS comienza en la posición inicial de la malla, por lo que si es [0,0,0], el texto comenzará allí, pero podemos centrarlo simplemente pasando la bandera "center". + +```vue + +``` diff --git a/docs/de/guide/getting-started.md b/docs/de/guide/getting-started.md new file mode 100644 index 000000000..8ee401022 --- /dev/null +++ b/docs/de/guide/getting-started.md @@ -0,0 +1,93 @@ +# Instalación + +Aprende cómo instalar TresJS + +::: code-group + +```bash [pnpm] +pnpm add three @tresjs/core +``` + +```bash [npm] +npm install three @tresjs/core +``` + +```bash [yarn] +yarn add three @tresjs/core +``` + +::: + +> Mejor usar con Vue 3.x y Composition API + +## Typescript + +TresJS está escrito en Typescript y está completamente tipado. Si estás utilizando Typescript, obtendrás todos los beneficios de los tipos. Solo asegúrate de instalar los tipos para three. + +::: code-group + +```bash [npm] +npm install @types/three -D +``` + +```bash [yarn] +yarn add @types/three -D +``` + +```bash [pnpm] +pnpm add @types/three -D +``` + +::: + +## Empezando + +Puedes instalar TresJS como cualquier otro complemento de Vue + +```ts +import { createApp } from 'vue' +import Tres from '@tresjs/core' +import App from './App.vue' + +export const app = createApp(App) + +app.use(Tres) +app.mount('#app') +``` + +O puedes usarlo directamente en tu componente + +```vue + + + +``` + +::: tip +Esto es recomendado por razones de rendimiento y tamaño del paquete, el tree-shaking funcionará mejor y solo importarás los componentes que uses. +::: + +## Vite + +Dado que la versión 2 es un renderizador personalizado, necesitamos informar al `vue-compiler` de tu aplicación que los componentes de Tres están permitidos para ser incluidos y evitar la advertencia `[Vue warn]: Failed to resolve component`. + +Solo necesitas agregar esto a tu archivo `vite.config.ts` dentro del plugin de Vue: + +```ts +import { templateCompilerOptions } from '@tresjs/core' + +export default defineConfig({ + plugins: [ + vue({ + // Other config + ...templateCompilerOptions + }), + ] +}) +``` \ No newline at end of file diff --git a/docs/de/guide/index.md b/docs/de/guide/index.md new file mode 100644 index 000000000..4cd6759ec --- /dev/null +++ b/docs/de/guide/index.md @@ -0,0 +1,114 @@ +# Introduccion + + +
+ +
+
+ +::: code-group + +```bash [npm] +npm install @tresjs/core three +``` + +```bash [yarn] +yarn add @tresjs/core three +``` + +```bash [pnpm] +pnpm add @tresjs/core three +``` + +::: + +## Typescript + +TresJS está escrito en Typescript y está completamente tipado. Si estás utilizando Typescript, obtendrás todos los beneficios de los tipos. Solo asegúrate de instalar los tipos para three. + +::: code-group + +```bash [npm] +npm install @types/three -D +``` + +```bash [yarn] +yarn add @types/three -D +``` + +```bash [pnpm] +pnpm add @types/three -D +``` + +::: + +## Vite + +Si estás utilizando Vite, debes agregar lo siguiente a tu `vite.config.ts`: + +```ts +import { templateCompilerOptions } from '@tresjs/core' + +export default defineConfig({ + plugins: [ + vue({ + // Other config + ...templateCompilerOptions + }), + ], +}), +``` + +Esto es necesario para que el compilador de plantillas funcione con el renderizador personalizado y no lance advertencias en la consola. Para obtener más información, consulta [aquí](/guide/troubleshooting.html). + +## Pruébalo en línea + +### Sandbox + +Puedes probar TresJS en línea utilizando el [sandbox](https://play.tresjs.org/) oficial. ¡Échale un vistazo: + + + +### StackBlitz + +Tenemos un nuevo inicio de [StackBlitz](https://stackblitz.com/) para probar TresJS en línea. ¡Échale un vistazo: + +![](/stackblitz-starter.png) + + + +## Playground + +También tenemos un playground donde puedes probar TresJS en línea. Échale un vistazo [aquí](https://playground.tresjs.org/). + +![](/playground.png) + +## Motivación + +[ThreeJS](https://threejs.org/) es una maravillosa biblioteca para crear increíbles sitios web 3D con WebGL. También es una biblioteca constantemente actualizada que dificulta a los mantenedores de envoltorios como [TroisJS](https://troisjs.github.io/) mantenerse al día con todas las mejoras. + +El ecosistema de React tiene una solución impresionante de **renderizado personalizado** llamada [React-three-fiber](https://docs.pmnd.rs/react-three-fiber) que te permite construir tus escenas de forma declarativa con componentes reutilizables y autocontenidos que reaccionan al estado. + +En mi búsqueda de algo similar en el ecosistema de VueJS, encontré esta increíble biblioteca llamada [Lunchbox](https://github.com/breakfast-studio/lunchboxjs) que funciona con el mismo concepto que R3F, proporciona un [renderizador personalizado de Vue3](https://vuejs.org/api/custom-renderer.html). También estoy contribuyendo para mejorar esta biblioteca y que sea tan madura y rica en características como R3F. + +El único problema es que mezclar compiladores y renderizadores en Vue 3 es algo en lo que la comunidad de Vue todavía está trabajando. Puedes ver más información [aquí](https://github.com/vuejs/vue-loader/pull/1645). + +```ts +// Example Vite setup +import { createApp } from 'vue' +import { createApp as createLunchboxApp } from 'lunchboxjs' +import App from './App.vue' +import LunchboxApp from './LunchboxApp.vue' + +// html app +const app = createApp(App) +app.mount('#app') + +// lunchbox app +const lunchboxApp = createLunchboxApp(LunchboxApp) +// assuming there's an element with ID `lunchbox` in your HTML app +lunchboxApp.mount('#lunchbox') +``` + +Así que me inspiré en ambas bibliotecas para crear un renderizador personalizado de Vue para ThreeJS. Eso es **TresJS v2**. + diff --git a/docs/de/guide/migration-guide.md b/docs/de/guide/migration-guide.md new file mode 100644 index 000000000..3b49c674f --- /dev/null +++ b/docs/de/guide/migration-guide.md @@ -0,0 +1,226 @@ +# Guía de Migración + +Esta guía tiene como objetivo ayudarte a migrar de la versión 1 a las versiones más recientes de TresJS 🤩✨. + +::: code-group + +```bash [pnpm] +pnpm update @tresjs/core +``` + +```bash [npm] +npm update @tresjs/core +``` + +```bash [yarn] +yarn upgrade @tresjs/core +``` + +::: + +## Novedades + +### Vue Custom Renderer + +**TresJS** es ahora un [Vue Custom Renderer](https://vuejs.org/api/custom-renderer.html#createrenderer) 🎉 que se encuentra dentro de un componente envolvente `TresCanvas` que se encarga de crear el `WebGLRenderer` y la `Scene` por ti, y crear una **nueva instancia de la aplicación Vue** para renderizar la escena. + +### Soporte de TypeScript e Intellisense 🦾 + +![TresJS Intellisense](/v2-intellisense.gif) + +Esta fue probablemente la característica más **solicitada para TresJS**. Ahora los componentes de Tres funcionan con Volar y proporcionan intellisense de tipos. + +**TresJS** ahora genera declaraciones de tipos en tiempo de compilación para todos los componentes basados en el catálogo de ThreeJS. Esto significa que puedes usar todos los componentes de ThreeJS y obtener intellisense de tipos para ellos. + +### El plugin de Tres es opcional 👍 + +El `TresPlugin` ahora es opcional. Puedes usar TresJS sin él importando los componentes directamente desde `tresjs/core`: + +```vue + + + +``` + +::: info +Esto es recomendado por razones de rendimiento y tamaño del paquete, el tree-shaking funcionará mejor y solo importarás los componentes que uses. +::: + +### TresScene ya no es necesario + +The `` component is now deprecated since the scene is now created by the ``. + +In the beginning, I thought that it would be a good idea to have a separate component for the scene in terms of verbosity and keep it as similar to plain ThreeJS, but it turned out that it was not really useful. + +You can now create a scene like this: + +```vue + +``` + +Para migrar tu código, simplemente puedes eliminar el componente `` y mover los hijos al componente ``. + +### `useCatalog` ahora está obsoleto + +La función `useCatalog` ahora está obsoleta. Ahora puedes importar el catálogo directamente desde `@tresjs/core`. + +Puedes leer más al respecto aquí: [Extending](/advanced/extending.md) + +Cambia esto: + +```ts {2,5,7} +import { useCatalog } from '@tresjs/core' +import { TextGeometry } from 'three/addons/geometries/TextGeometry' + +const { extend } = useCatalog() + +extend({ TextGeometry }) +``` + +Por esto: + +```ts {2,6} +// Correcto ✅ +import { extend } from '@tresjs/core' +import { TextGeometry } from 'three/addons/geometries/TextGeometry' + +extend({ TextGeometry }) +``` + +### El valor de referencia del modelo `getModel` ahora está obsoleto + +La función `getModel` ahora está obsoleta. Ahora puedes usar directamente la propiedad `model`. + +Cambia esto: + +```vue {7,9-12} +// Incorrecto ❌ + + + +``` + +To this: + +```vue {7,9-12} +// Correcto ✅ + + + +``` + +### Las cámaras deben estar antes de cualquier control 🎥 + +El componente `TresOrbitControls` debe estar después de la cámara en el árbol. Esto se debe a que los controles necesitan conocer la cámara para funcionar. + +Cambia esto: + +```vue {3,5} +// Incorrecto ❌ + +``` + +Por esto: + +```vue {3,5} +// Correcto ✅ + +``` + +## UseTres ahora es useTresContext + +Para la versión 3, reestructuramos toda la lógica de estado para que sea más flexible y fácil de usar para los autores de complementos y paquetes del ecosistema. En lugar de usar una tienda como en la versión 2, ahora usamos un proveedor de contexto basado en `provide/inject`. + +La función `useTres` ahora es un alias de la función `useTresContext` para evitar romper demos y experimentos existentes, pero considera usar `useTresContext` a partir de ahora. + +En lugar de obtener un objeto reactivo grande, ahora obtendrás directamente las referencias `scene` y `renderer`, entre otras propiedades. + +Cambia esto: + +```ts {2} +// Incorrecto ❌ +import { useTres } from '@tresjs/core' + +const { state, setState } = useTres() + +console.log(state.scene) +``` + +Por esto: + +```ts {2} +// Correcto ✅ +import { useTresContext } from '@tresjs/core' + +const { scene, renderer } = useTresContext() + +console.log(scene.value) +``` + +Para obtener información más detallada sobre el nuevo sistema de proveedor de contexto, puedes leer la sección [API DOCS](/api/composables.md). diff --git a/docs/de/guide/nuxt.md b/docs/de/guide/nuxt.md new file mode 100644 index 000000000..9f43193ff --- /dev/null +++ b/docs/de/guide/nuxt.md @@ -0,0 +1,58 @@ +# Nuxt module `@tresjs/nuxt` + +![TresJS Nuxt Module](/nuxt-stones.png) + +npm package + +¡Aquí está el módulo oficial de Nuxt para TresJS! 🎉. + +El repositorio está [aquí](https://github.com/Tresjs/nuxt) + +## Instalación + +::: code-group + +```bash [pnpm] +pnpm add three @tresjs/nuxt +``` + +```bash [npm] +npm install three @tresjs/nuxt +``` + +```bash [yarn] +yarn add three @tresjs/nuxt +``` + +::: + +## Características + +- 🤓 Importación automática de componentes y composables del [ecosistema de TresJS](https://github.com/orgs/Tresjs/repositories) +- `TresCanvas` esta disponible solo en el cliente, no es necesario agregar `.client` al nombre del componente o `` +- Configura automáticamente el compilador de Vue para admitir componentes de TresJS, consulta [por qué](/guide/troubleshooting.html#failed-resolve-component-trescomponent-%F0%9F%A4%94)? +- Toda la magia de DX que viene con Nuxt ✨ + +## Uso + +Agrega `@tresjs/nuxt` a la sección `modules` de `nuxt.config.ts` + +```js +export default defineNuxtConfig({ + modules: ['@tresjs/nuxt'], +}) +``` + +¡Eso es todo! Ahora puedes usar `@tresjs/nuxt` en tu aplicación Nuxt ✨ + +Si deseas utilizar cualquier paquete del ecosistema de TresJS, puedes instalar los paquetes que desees utilizar y serán importados automáticamente por el módulo 🧙🏼‍♂️. + +| Package | Version | +| --------------------------- | :------------------------------------------------------------------------------------------------- | +| [Cientos](https://github.com/Tresjs/cientos) | ![cientos version](https://img.shields.io/npm/v/@tresjs/cientos/latest.svg?label=%20&color=%23f19b00) | +| [Post-processing](https://github.com/Tresjs/post-processing) | ![post-processing version](https://img.shields.io/npm/v/@tresjs/post-processing/latest.svg?label=%20&color=ff69b4) | + +```bash +# Usando pnpm +pnpm add @tresjs/cientos @tresjs/post-processing +``` \ No newline at end of file diff --git a/docs/de/guide/troubleshooting.md b/docs/de/guide/troubleshooting.md new file mode 100644 index 000000000..49faec867 --- /dev/null +++ b/docs/de/guide/troubleshooting.md @@ -0,0 +1,88 @@ +# La divertida guía de problemas comunes y cómo solucionarlos + +![Solución de problemas](https://media.giphy.com/media/LHZyixOnHwDDy/giphy.gif) + +Bienvenido a la guía de solución de problemas de **TresJS v2**. ¡Donde 3D significa _"Dificultades Deslumbrantemente Deliciosas"_! Sabemos que el 3D puede ser tan complejo como una bola de lana enredada 🧶 o tan impredecible como un gato en un teclado 🐈 ⌨️, ¡pero no temas! + +Esta guía está destinada a ayudarte a resolver los problemas más comunes que puedes encontrar al usar TresJS v2. + +## ¡No puedo ver mi escena 3D 😭! + +Has seguido la [guía de inicio](/guide/getting-started.md) pero aún no puedes ver tu escena renderizada. + +Estas son las razones más comunes por las que es posible que no puedas ver tu escena: + +### Verifica la altura de tu lienzo 📏 + +Otro problema común es que el componente `TresCanvas` crea por defecto un elemento `canvas` que toma el `width` y `height` del elemento padre. Si el elemento padre no tiene altura, el lienzo tampoco la tendrá. + +![No se encontró altura](/canvas-height.png) + +También verás este error en la consola: + +![Advertencia de altura del lienzo](/canvas-height-warning.png) + +Una forma sencilla de solucionar esto es establecer la altura del elemento padre en `100%`: + +```css +html, +body { + margin: 0; + padding: 0; + height: 100%; + width: 100%; +} +#app { + height: 100%; + width: 100%; + background-color: #000; +} +``` + +O también puedes establecer la propiedad `window-size` del componente `TresCanvas`: + +```vue + + + + +``` + +## Error al resolver el componente: TresComponent... + +![](/failed-to-resolve-component.png) + +Dado que **TresJS v2** utiliza un Renderizador Personalizado de Vue dentro de la instancia principal de la aplicación Vue, el renderizador principal de Vue que actúa como padre no reconocerá los componentes dentro del componente `TresCanvas`. Aunque no afecta la representación, mostrará una advertencia en la consola. + +![](/failed-to-resolve-component.png) + +En este momento, no hay soporte nativo de Vue para definir el renderizador utilizado en la etiqueta `