🐕
React+TypeScriptなWebアプリで、Tweenしてみた001。(回転しながら横移動)
Abstract
React+TypeScriptで、tween.jsライブラリを使ってアニメーションするシリーズ1回目。
今回の参考はここ(hello_world)。
結論
今回の成果物はココ↓
tween.jsライブラリとは
道路標識みたいなせ目的地とかを空間上に表示する機能。
回転、拡縮、横移動を簡単に実装できるアニメーションライブラリ。複雑なアニメーションを簡単に表現できる。
前提
- React+Typescriptの開発環境は構築済 [環境構築]WindowsにVSCode+React+TypeScriptの開発環境を構築してみた。
- このスケルトンコードから始める。react-r3f-tutorial010
手順
1.プロジェクト生成 -> VSCodeで開く
めんどいから、このスケルトンコードから始める。react-r3f-tutorial010
で、下記コマンドでフォルダ名とか整備する。
フォルダリネームとか
$ D:
$ cd .\Products\React.js\ # ご自身の適当なフォルダで。
$ rd /q /s D:\Products\React.js\react-r3f-advanced010
$ git clone https://github.com/aaaa1597/react-r3f-tutorial010.git
$ rd /q /s react-r3f-tutorial010/.git
$ ren react-r3f-tutorial010 react-tweenjs001
$ cd react-tweenjs001
準備
$ npm install --save three
$ npm install --save @types/three
$ npm install --save @react-three/fiber
$ npm install --save @react-three/drei
$ npm install --save @tweenjs/tween.js
App.tsx
まず全体。
App.tsx
-import React, {useRef} from 'react';
+import React, {useRef, useEffect } from 'react';
import './App.css';
import { Canvas, useFrame, MeshProps } from '@react-three/fiber'
import * as THREE from 'three'
import { OrbitControls, Environment } from '@react-three/drei'
+import TWEEN from '@tweenjs/tween.js'
const Box = (props: MeshProps) => {
const ref = useRef<THREE.Mesh>(null!)
+ useEffect(() => {
+ const tween = new TWEEN.Tween(ref.current.position)
+ .to({x: 1, y: 3, z: 0, rotation: 0}, 2000)
+ .delay(1000)
+ .easing(TWEEN.Easing.Elastic.InOut)
+ const tweenrot = new TWEEN.Tween(ref.current.rotation)
+ .to({x: Math.PI, y: 0, z: 0, rotation: 0}, 2000)
+ .easing(TWEEN.Easing.Elastic.InOut)
+ const tweenBack = new TWEEN.Tween(ref.current.position)
+ .to({x: 1, y: 1, z: 1, rotation: 0}, 3000)
+ .easing(TWEEN.Easing.Elastic.InOut)
+ tween.chain(tweenrot)
+ tweenrot.chain(tweenBack)
+ tweenBack.chain(tween)
+ tween.start()
+ }, []);
useFrame((_, delta) => {
- if( !ref.current) return
- ref.current.rotation.x += 1 * delta
- ref.current.rotation.y += 0.5 * delta
+ // ref.current!.rotation.x += 1 * delta
+ // ref.current!.rotation.y += 0.5 * delta
})
return (
<mesh {...props} ref={ref}>
<boxGeometry />
<meshNormalMaterial />
</mesh>
)
}
const Tween = () => {
useFrame(() => {
TWEEN.update()
})
return(<></>)
}
const App = () => {
return (
- <div style={{ width: "75vw", height: "75vh" }}>
+ <div style={{ width: "100vw", height: "75vh" }}>
<Canvas camera={{ position: [3, 1, 2] }}>
<Box position={[1, 1, 1]} name="A" />
+ <Tween />
<Environment preset="forest" background />
<OrbitControls />
<axesHelper args={[5]} />
<gridHelper />
</Canvas>
</div>
);
}
export default App;
で、実行。
出来た!!
ポイント
- TWEENをimportする。
App.tsx
import TWEEN from '@tweenjs/tween.js'
- Tween関数コンポーネントを作って、<Tween />タグを埋め込む。
App.tsx
const Tween = () => {
useFrame(() => {
TWEEN.update()
})
return(<></>)
}
~略~
<Tween />
- new TWEEN.Tween()で生成、いろいろ設定して、startで開始する。
App.tsx
const tween = new TWEEN.Tween(ref.current.position)
.to({x: 1, y: 3, z: 0, rotation: 0}, 2000)
.delay(1000)
.easing(TWEEN.Easing.Elastic.InOut)
const tweenrot = new TWEEN.Tween(ref.current.rotation)
.to({x: Math.PI, y: 0, z: 0, rotation: 0}, 2000)
.easing(TWEEN.Easing.Elastic.InOut)
const tweenBack = new TWEEN.Tween(ref.current.position)
.to({x: 1, y: 1, z: 1, rotation: 0}, 3000)
.easing(TWEEN.Easing.Elastic.InOut)
tween.chain(tweenrot)
tweenrot.chain(tweenBack)
tweenBack.chain(tween)
tween.start()
- useEffectで初回startすると、動き続ける。デフォルト繰り返し?
to()に設定するrotationは値設定しても意味ないみたい。
移動させたいときは、new TWEEN.Tween()の引数に、ref.current.positionを設定して、
回転させたいときは、new TWEEN.Tween()の引数に、ref.current.rotationを設定する。
一度に移動させたいときは...?調査中。
Discussion