Tween.js
Import
import TWEEN from '@tweenjs/tween.js'
Description
A tween (from in-between) is a concept that allows you to change the values of the properties of an object smoothly.
While Tween.js is not written with React Three Fiber in mind, it is still possible to use it.
Example 1 : Tween OrbitControls Target
In this example below, you can double-click the monkey head, or plane, and it will smoothly move the OrbitControls target to where you clicked the mesh.
Using Tween.js in R3F
Install the dependency
npm install @tweenjs/tween.js --save-dev
Import in your script,
import TWEEN from '@tweenjs/tween.js'
Note that the TWEEN
object is created as a singleton, which means that if you also import it in other files, then it will also point to the first instance that was registered in memory.
Next, we need to continually call TWEEN.Update()
. So, creating a simple component, and calling it within a useFrame is sufficient.
function Tween() {
useFrame(() => {
TWEEN.update()
})
}
And use the simple component it in your canvas.
<Canvas>
// ...
<Tween />
// ...
</Canvas>
All tweens started throughout your application will be updated.
The TWEEN
object will also manage its own delta time, so we don't need to pass that value in.
Note that you also only need one TWEEN.Update()
being called within your whole application for it to manage all currently executing tweens throughout.
In the example above, I am tweening the target property of the OrbitControls
. So in the Monkey
, or Plane
mesh, I have added a onDoubleClick
event that will use the {point}
object from the event to update the OrbitControls
target.
I also need to pass the OrbitControls
reference to the Monkey
and Plane
components when they are created, so that the onDoubleClick
event can modify the target
co-ordinates.
export default function App() {
const ref = useRef()
return (
<>
//...
<OrbitControls ref={ref} />
<Plane controls={ref} /> // Passing OrbitControls ref as a prop to the Plane
//...
}
function Plane({ controls }) {
return (
<mesh
// ...
onDoubleClick={({ point }) => {
new TWEEN.Tween(controls.current.target)
.to(
{
x: point.x,
y: point.y,
z: point.z
},
500
)
.easing(TWEEN.Easing.Cubic.Out)
.start()
}}>
// ...
)
}
Example 2 : Tween Component Position
This time, there will be two tweens running simultaneously, and a third tween that starts after one of the other tweens has completed.
This will result in the Monkey
appearing to bounce to the point where you've double-clicked the Plane
.
In order for the onDoubleClick
event of the Plane
to modify the Monkey
position, I needed to pass in the Monkey
reference to it.
export default function App() {
const ref = useRef()
return (
<>
//...
<Monkey ref={ref} />
<Plane monkey={ref} /> <!-- Passing the Monkey ref as a prop to the Plane -->
//...
}
And also since the Monkey
is a custom function component within my app, and you can't create refs directly to function components, I needed to create a forwardRef to the Monkey
for it to work.
const Monkey = forwardRef(function Monkey({ position }, ref) {
// ...
return (
<group ref={ref}>
// ...
})
And now I can configure multiple tweens to modify the Monkey
when the Plane
is double-clicked.
function Plane({ monkey }) {
return (
<mesh
// ...
onDoubleClick={({ point }) => {
// slide
new TWEEN.Tween(monkey.current.position)
.to(
{
x: point.x,
z: point.z
},
500
)
.start()
// arc up through the air
new TWEEN.Tween(monkey.current.position)
.to(
{
y: point.y + 3
},
250
)
.easing(TWEEN.Easing.Cubic.Out)
.start()
.onComplete(() => {
// arc down through the air and finish with a small bounce
new TWEEN.Tween(monkey.current.position)
.to(
{
y: point.y + 1
},
250
)
.easing(TWEEN.Easing.Bounce.Out)
.start()
})
}}>
// ...
)
}
The final little bounce when the Monkey
lands is due to using TWEEN.Easing.Bounce.Out
.
See Tween Easing Options for more possibilities.
Useful Links
Using tween.js | sbcode |
Tween OrbitControls | sbedit.net |
Tween Position | sbedit.net |
Tween.js | github.com/tweenjs |
User Guide | tweenjs.github.io |
Camera | sbcode |
Photogrammetry | sbcode |
GitHub Branch
git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout tween
npm install
npm start