Skip to content
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

feat: 633 useFrame and useRender #640

Closed
wants to merge 18 commits into from
Closed

feat: 633 useFrame and useRender #640

wants to merge 18 commits into from

Conversation

alvarosabu
Copy link
Member

@alvarosabu alvarosabu commented Apr 13, 2024

Closes #633

Based on the team dicussion. This PR introduces two new APIs.

useFrame

This composable allows you to execute a callback on every rendered frame, similar to useRenderLoop but unique to each TresCanvas instance and with access to the context.

This composable allows you to execute a callback on every rendered frame, similar to useRenderLoop but unique to each TresCanvas instance and with access to the context.

Warning

useFrame can be only be used inside of a TresCanvas since this component acts as the provider for the context data.

<script setup>
import { TresCanvas } from '@tresjs/core'
import AnimatedBox from './AnimatedBox.vue'
</script>

<template>
  <TresCanvas>
    <AnimatedBox />
  </TresCanvas>
</template>
<script setup>
import { useFrame } from '@tresjs/core'

const boxRef = ref()

useFrame(({ delta }) => {
  boxRef.value.rotation.y += 0.01
})
</script>

<template>
  <TresMesh ref="boxRef">
    <TresBoxGeometry />
    <TresMeshBasicMaterial color="teal" />
  </TresMesh>
</template>

Your callback function will be triggered just before a frame is rendered and it will be unmounted automatically when the component is destroyed.

Render priority

The useFrame composable accepts a second argument index which is used to determine the order in which the loop functions are executed. The default value is 0 which means the function will be executed after the renderer updates the scene. If you set the value to -1, the function will be executed before the renderer updates the scene.

useFrame(() => {
  console.count('before renderer')
}, -1)

useFrame(() => {
  console.count('after renderer')
}, 1)

useRender (Take control of the render loop)

By default, the render-loop is automatically started when the component is mounted. However, you can take control of the render-loop by using this composable.

useRender(({ renderer, scene, camera }) => {
  // Takes over the render-loop, the user has the responsibility to render
  renderer.value.render(scene.value, camera.value)
})

@alvarosabu alvarosabu changed the base branch from main to v4 April 13, 2024 14:35
@alvarosabu alvarosabu self-assigned this Apr 13, 2024
Copy link

netlify bot commented Apr 13, 2024

Deploy Preview for tresjs-docs ready!

Name Link
🔨 Latest commit 2ff1c15
🔍 Latest deploy log https://app.netlify.com/sites/tresjs-docs/deploys/661a98290f7e3f0008df204f
😎 Deploy Preview https://deploy-preview-640--tresjs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@alvarosabu alvarosabu added feature p3-significant High-priority enhancement (priority) labels Apr 13, 2024
@alvarosabu alvarosabu added the v4 label Apr 13, 2024
@andretchen0
Copy link
Contributor

Hey @alvarosabu ,

This approach doesn't work for directives, at least not directly.

import type { Object3D } from 'three'
import type { Ref } from 'vue'
import { extractBindingPosition } from '../utils'
import type { TresVector3 } from '../types'
import { useLogger, useLoop } from '../composables'

const { logWarning } = useLogger()

export const vAlwaysLookAt = {
  updated: (el: Object3D, binding: Ref<TresVector3>) => {
    const observer = extractBindingPosition(binding)
    if (!observer) {
      logWarning(`v-always-look-at: problem with binding value: ${binding.value}`)
      return
    }
    useLoop(() => {
      el.lookAt(observer)
    })
  },
}

Any thoughts on how to proceed?

@alvarosabu alvarosabu removed the v4 label Apr 24, 2024
@andretchen0
Copy link
Contributor

@alvarosabu

Do you still want a review on this PR?

@alvarosabu
Copy link
Member Author

Hey @andretchen0 not yet, will update it depending of the result of the dicussion on Discord.

I still need to figure out how to not break directives

@alvarosabu alvarosabu changed the title feat: 633 use loop feat: 633 useFrame and useRender Apr 28, 2024
@alvarosabu
Copy link
Member Author

alvarosabu commented Apr 28, 2024

Hey @alvarosabu ,

This approach doesn't work for directives, at least not directly.

import type { Object3D } from 'three'
import type { Ref } from 'vue'
import { extractBindingPosition } from '../utils'
import type { TresVector3 } from '../types'
import { useLogger, useLoop } from '../composables'

const { logWarning } = useLogger()

export const vAlwaysLookAt = {
  updated: (el: Object3D, binding: Ref<TresVector3>) => {
    const observer = extractBindingPosition(binding)
    if (!observer) {
      logWarning(`v-always-look-at: problem with binding value: ${binding.value}`)
      return
    }
    useLoop(() => {
      el.lookAt(observer)
    })
  },
}

Any thoughts on how to proceed?

Doing a search on GitHub about usage of the affected directives:

v-always-look-at https://github.com/search?q=v-always-look-at&type=code&p=1
v-rotate: https://github.com/search?q=v-rotate&type=code&p=1

Couting @JaimeTorrealba there are like 2 more users currently using those. I will suggest updating the directives to useFrame and help you and hawk migrate their code to use subcomponents, otherwise they would not work with the new features

@andretchen0
Copy link
Contributor

@alvarosabu

For sure. It's not so much "don't break existing directives" as "we need to create a convenient API for getting a contextful useLoop outside of the provide tree".

@alvarosabu alvarosabu changed the title feat: 633 useFrame and useRender feat: 633 useLoop May 2, 2024
@alvarosabu alvarosabu changed the title feat: 633 useLoop feat: 633 useFrame and useRender May 2, 2024
@alvarosabu
Copy link
Member Author

alvarosabu commented May 4, 2024

Closed this in favor of #673

@alvarosabu alvarosabu closed this May 4, 2024
@alvarosabu alvarosabu added the wontfix This will not be worked on label May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature p3-significant High-priority enhancement (priority) wontfix This will not be worked on
Projects
None yet
2 participants