ScrollControls
ScrollControls
use scroll as a trigger for control the scene, you can use the HTML native scroll or use the one that it get creates for you.
The cientos
package create this controls from scratch for you, and comes with really useful props to customize your experiences, try it out. ✨
Usage
To start using it, you just need to import it and play with it.
<script setup lang="ts">
import { Box, ScrollControls, Stars } from '@tresjs/cientos'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { useControls } from '@tresjs/leches'
import { ref } from 'vue'
import '@tresjs/leches/styles'
const boxRef = ref()
const progress = ref(0)
useControls('fpsgraph')
useControls({
progress: progress.value,
})
const { onLoop } = useRenderLoop()
onLoop(() => {
if (boxRef.value) {
boxRef.value.instance.rotation.x = progress.value * 10
boxRef.value.instance.rotation.y = progress.value * 2
}
})
</script>
<template>
<TresCanvas
class="important-absolute"
clear-color="#333"
>
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Stars :radius="1" />
<TresGridHelper :args="[10, 10]" />
<ScrollControls />
<Box
:scale="0.5"
:color="0xFF00FF"
:position="[-1, 1, 0]"
/>
</TresCanvas>
</template>
WARNING
Is really important that the Perspective camera is set first in the canvas. Otherwise might break.
You can use the horizontal
prop, to makes the scroll horizontal way.
<script setup lang="ts">
import { Box, ScrollControls, Stars } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas
class="important-absolute"
clear-color="#333"
>
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Stars :radius="1" />
<TresGridHelper :args="[10, 10]" />
<ScrollControls horizontal />
<Box
:scale="0.5"
:color="0xFF00FF"
:position="[-1, 1, 0]"
/>
</TresCanvas>
</template>
With the pages
prop you can control the length of the scroll, and with the distance
you can control how much movement is apply to the objects ( you can for example use it with 0 value and use the progress element)
In addition a nice effect could be achieve by using the smoothScroll
prop like so:
<script setup lang="ts">
import { Box, ScrollControls, Stars } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas
class="important-absolute"
clear-color="#333"
>
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Stars :radius="1" />
<TresGridHelper :args="[10, 10]" />
<ScrollControls
:pages="20"
:distance="20"
:smooth-scroll="0.05"
/>
<Box
:scale="0.5"
:color="0xFF00FF"
:position="[-1, 1, 0]"
/>
</TresCanvas>
</template>
By default ScrollControls
creates a scroll around the canvas and takes the camera as a default for animate, also it comes with a reactive progress
param that returns a normalized value from 0 (start point) to 1 (end point) you just need to attach it to a v-model.
<script setup lang="ts">
import { Box, ScrollControls, Stars } from '@tresjs/cientos'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { ref } from 'vue'
const boxRef = ref()
const progress = ref(0)
const { onLoop } = useRenderLoop()
onLoop(() => {
if (boxRef.value) {
boxRef.value.instance.rotation.x = progress.value * 10
boxRef.value.instance.rotation.y = progress.value * 2
boxRef.value.instance.position.x = progress.value * 4.5
}
})
</script>
<template>
<TresCanvas
class="important-absolute"
clear-color="#333"
>
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Stars :radius="1" />
<TresGridHelper :args="[10, 10]" />
<ScrollControls
v-model="progress"
:distance="2"
/>
<Box
ref="boxRef"
:scale="0.5"
:color="0xFF00FF"
:position="[-1, 1, 0]"
/>
</TresCanvas>
</template>
If you don't want to use the default camera movement you can set the distance to 0 a just rely on progress to animate (the progress is not affected by the smoothScroll
)
But it's not all, you can also pass the htmlScroll
props this will deactivate the custom scroll and use the native html scroll.
<ScrollControls htmlScroll />
WARNING
- If you set the
htmlScroll
you need to set your html to have content that create scroll. so thepages
prop will not work - The
htmlScroll
will set the TresCanvas as a fixed background.
Slots
The elements that you pass as a slot will be affected by the scroll effect, and follow the camera.
<script setup lang="ts">
import { Box, ScrollControls, Sphere, Stars } from '@tresjs/cientos'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { ref } from 'vue'
const scRef = ref()
const boxRef = ref()
const progress = ref(0)
const { onLoop } = useRenderLoop()
onLoop(() => {
if (boxRef.value) {
boxRef.value.instance.rotation.x = progress.value * 10
boxRef.value.instance.rotation.y = progress.value * 2
}
})
</script>
<template>
<TresCanvas
clear-color="#333"
class="important-absolute"
>
<TresPerspectiveCamera :position="[0, 2, 5]" />
<Stars :radius="1" />
<TresGridHelper :args="[10, 10]" />
<Sphere
:scale="0.1"
:position="[1, 2, 0]"
/>
<ScrollControls
ref="scRef"
v-model="progress"
:distance="20"
:smooth-scroll="0.1"
>
<Box
ref="boxRef"
:scale="0.5"
:color="0xFF00FF"
:position="[-1, 1, 0]"
/>
</ScrollControls>
</TresCanvas>
</template>
Props
Prop | Description | Default |
---|---|---|
pages | The length of the scroll (not available with htmlScroll) | 4 |
distance | The distance to move the objects | 4 |
smoothScroll | The smooth factor of the scrolling. | 0.5 |
horizontal | Whether the scroll is horizontal or vertical. | false |
htmlScroll | Whether to use the native HTML scroll. | false |
WARNING
Currently the props are not reactive for this control