Tresjs / cientos

Collection of useful helpers and fully functional, ready-made abstractions for TresJS
https://cientos.tresjs.org/
MIT License
288 stars 40 forks source link

Add more props to MouseParallax #226

Closed JaimeTorrealba closed 8 months ago

JaimeTorrealba commented 1 year ago

Description

MouseParallax could offer much more... rotation, invert, canvasSize

The use of slots (only affect elements inside)

Suggested solution

Implement all that new properties

Alternative

Any other alternative is considered

Additional context

No response

Validations

andretchen0 commented 1 year ago

If I can piggyback on this ...

Feature request

Make the viewport contents shift relative to the viewport plane.

Description

If it's not too hard to implement, one thing that would be nice is for the MouseParallax to work the same regardless of the camera orientation:

Background

Looking at the demo, it seems like what's described above is the desired effect. But it only works in the demo because the camera is oriented the "right way" – the camera is oriented toward the world -z. If the camera is oriented toward the world +z for example, then the right/left are reversed.

The default Tres camera doesn't look at the world -z.

Using the demo code from the docs, here's what happens if the default camera is used instead:

https://github.com/Tresjs/cientos/assets/20469369/81f63eff-a5e2-4b34-8962-57e39c15ef15

Here's an SFC with the scene.

<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, SRGBColorSpace, NoToneMapping } from 'three'
import { MouseParallax, TorusKnot } from '@tresjs/cientos'

const gl = {
  clearColor: '#82DBC5',
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
}
</script>

<template>
  <TresCanvas v-bind="gl">
    <TorusKnot>
      <TresMeshNormalMaterial />
    </TorusKnot>
    <MouseParallax
      :factor="5"
      :ease="3"
    />
    <TresAmbientLight :intensity="1" />
  </TresCanvas>
</template>

Alternative

Document the current behavior.

andretchen0 commented 1 year ago

Hey @JaimeTorrealba ,

Can you explain a bit more about the options you'd like to add?

Thanks!

JaimeTorrealba commented 1 year ago

Hi yes.

Currently, the effect is just moving the camera (camera group) so if you move your mouse up, the scene moves down Rotation aims to change for rotating the camera (camera group) so if my mouse goes up, you should rotate the camera down

Invert (or maybe revert is a better name) aims to invert the current directions, for example if you move your mouse up, you camera move down, so the scene goes up (the contrary effect)

canvasSize: currently we're taking all the viewport, so this boolean will take the canvasSize (provided by useTresContext) so the effect will be applied only when the mouse is on the canvas

Slots is a little more complex, here we aim to not moving the camera, but instead the object inside the slots, (kind of like scrollControls) you can apply different effects for different objects

Others: is just that, if you have any suggestion please feel free to apply it

andretchen0 commented 1 year ago

Rotation

Maybe this should be a separate component? I think it could be worked in here, but for me, the component name makes it non-obvious. For me anyway, "parallax" is this effect:

4e1f26b5974e7b192ec268d88c55201d

canvasSize, invert

We have the pieces for these. I think it's just a question of getting the API right.

Inversion could be grouped with what's currently called factor. It could optionally accept a [number, number], where a negative number inverts the coordinates for the axis. Should factor be scale?

For canvasSize, the behavior you describe sort of reminds me of GLSL "clamp" for textures. Would that be a good name?

ease

Maybe change this prop to speed? What do you think?

The current implementation will break if ease is set to a high value, e.g., 3000. As far as I can tell, this would fix that:

cameraGroup.position.lerp(target, 1-Math.exp(delta * -props.ease));

Reactivity – remove?

There are some reactive elements in the current code, but it seems like they can be removed:

Since we read values every frame, we always have the updated values.

For the cameraGroupRef, the template currently uses a ref that's initialized as ref<Group>(). That means we have to check the ref.value on every loop. If instead we create a THREE.Group in the <script>, we can just use that, without the overhead of the ref. Is that ok?

Can we remove cameraGroupRef and use

 <primitive :object="cameraGroup" />

Is it ok to remove these refs/computeds?

JaimeTorrealba commented 1 year ago

1.- Don't know if a different component but just renamed it? I like something like MouseGesture (is something I thought before)

2.- I like the Idea of rename factor to scale and treat like [number, number] but with the options to if you provide a single value. EJ :factor="0.5" will be translated as [0.5, 0.5] made sense to you?

3.- we should rename it like speed of smooth as you wish, regarded the function sound perfect to me

4.- My only argument against his, is that would be more difficult and uncomfortable to handle the slots if we apply this way, I like what you mention and every unnecessary reactive prop should be avoid, but if we plan to handle slots it's way easier using a group in the template and then the conditionals, please check the scrollControls implementation. But if you have a better solution to the slots question, I listen.

Handle slots for useSlots (it's kind of uncomfortable I think)

JaimeTorrealba commented 1 year ago

Are you currently working in this? @andretchen0 As we'll create another pkg of gestures, maybe my scope was too big for this component. Would you be able to discuss this on discord?