update mouse hover

add animation
This commit is contained in:
DefectingCat
2022-10-08 17:38:00 +08:00
parent 642b8be2ef
commit 4a657c456c
4 changed files with 79 additions and 25 deletions

View File

@ -2,6 +2,7 @@
* @type {import('next').NextConfig}
*/
const isExport = process.env.NEXT_BUILD === 'export';
const nextConfig = {
/* config options here */
reactStrictMode: true,
@ -10,10 +11,9 @@ const nextConfig = {
images: isExport ? { unoptimized: true } : {},
experimental: {
// runtime: 'nodejs',
// outputStandalone: true,
},
compiler: {
removeConsole: true,
removeConsole: process.env.NODE_ENV === 'production',
},
// assetPrefix: isExport ? './' : undefined,
// images:

View File

@ -32,7 +32,7 @@
"rehype-slug": "^5.0.1",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1",
"rua-three": "^1.0.9",
"rua-three": "^1.1.1",
"sharp": "^0.31.0",
"stats.js": "^0.17.0",
"three": "^0.145.0"

View File

@ -2,7 +2,7 @@ import cn from 'classnames';
import dynamic from 'next/dynamic';
import Image from 'next/future/image';
import Head from 'next/head';
import { useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { InitFn, THREE, useThree } from 'rua-three';
import styles from 'styles/index/index.module.css';
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
@ -14,6 +14,9 @@ const Loading = dynamic(() => import('components/RUA/loading/RUALoading'));
const manager = new THREE.LoadingManager();
const gltfLoader = new GLTFLoader(manager);
const rotationY = 0.4;
const rotationX = 0.18;
const Home: NextPageWithLayout = () => {
const wrapper = useRef<HTMLDivElement>(null);
const [size, setSize] = useState({
@ -30,7 +33,7 @@ const Home: NextPageWithLayout = () => {
}, 300);
};
const setCanvasSize = () => {
const setCanvasSize = useCallback(() => {
if (!wrapper.current) return;
const width = wrapper.current.clientWidth;
const height = wrapper.current.clientHeight;
@ -38,7 +41,7 @@ const Home: NextPageWithLayout = () => {
width,
height,
});
};
}, []);
useEffect(() => {
setCanvasSize();
window.addEventListener('resize', setCanvasSize);
@ -46,46 +49,97 @@ const Home: NextPageWithLayout = () => {
return () => {
window.removeEventListener('resize', setCanvasSize);
};
}, []);
}, [setCanvasSize]);
const init: InitFn = ({ scene, camera, controls, frameArea }) => {
controls.enablePan = false;
controls.minDistance = 1;
controls.minPolarAngle = Math.PI * 0.2;
controls.maxPolarAngle = Math.PI * 0.5;
controls.maxAzimuthAngle = Math.PI * 0.2;
camera.position.set(0, 5, 5);
const init: InitFn = ({
scene,
camera,
controls,
frameArea,
isOrbitControls,
isPerspectiveCamera,
addWindowEvent,
addRenderCallback,
}) => {
if (isOrbitControls(controls)) {
controls.enableRotate = false;
controls.enablePan = false;
controls.enableZoom = false;
controls.minDistance = 1;
controls.minPolarAngle = Math.PI * 0.2;
controls.maxPolarAngle = Math.PI * 0.5;
controls.maxAzimuthAngle = Math.PI * 0.2;
}
const light = new THREE.SpotLight(0xffffff, 1.4, 100, 15);
scene.add(new THREE.AmbientLight(0xffffff, 0.8));
const light = new THREE.SpotLight(0xffffff, 2, 100, 15);
scene.add(new THREE.AmbientLight(0xffffff, 1));
scene.add(light);
const handleLoad = (gltf: GLTF) => {
const root = gltf.scene;
scene.add(root);
const clock = new THREE.Clock();
const mixer = new THREE.AnimationMixer(root);
gltf.animations.forEach((clip) => {
mixer.clipAction(clip).play();
});
addRenderCallback((time) => {
mixer.update(clock.getDelta());
});
const box = new THREE.Box3().setFromObject(root);
const boxSize = box.getSize(new THREE.Vector3()).length();
const boxCenter = box.getCenter(new THREE.Vector3());
light.target = root;
light.position.set(0, 2, 4);
light.position.set(0, 2, 6);
light.rotateX(Math.PI * 0.4);
frameArea(boxSize * 0.8, boxSize, boxCenter, camera);
isPerspectiveCamera(camera) &&
frameArea(boxSize * 0.8, boxSize, boxCenter, camera);
controls.maxDistance = boxSize * 10;
// controls.maxDistance = boxSize * 10;
controls.target.copy(boxCenter);
controls.update();
const halfWidth = Math.floor(window.innerWidth / 2);
const halfHeight = Math.floor(window.innerHeight / 2);
const updateMousePosition = (e: MouseEvent | globalThis.TouchEvent) => {
let x;
let y;
if (e instanceof MouseEvent) {
x = e.clientX;
y = e.clientY;
} else {
x = e.touches[0].clientX;
y = e.touches[0].clientY;
}
// > 0 is right, < 0 is left
const directionX = x - halfWidth;
const directionY = y - halfHeight;
// if (directionX > 0) root.rotation.y += 0.01;
root.rotation.y = rotationY * (directionX / halfWidth);
root.rotation.x = rotationX * (directionY / halfHeight);
};
addWindowEvent('mousemove', updateMousePosition, {
passive: true,
});
addWindowEvent('touchmove', updateMousePosition, {
passive: true,
});
};
gltfLoader.load('/models/just_a_hungry_cat/scene.gltf', handleLoad);
gltfLoader.load('./models/just_a_hungry_cat/scene.gltf', handleLoad);
};
const { ref } = useThree({
init,
...size,
alpha: true,
renderOnDemand: true,
});
return (

View File

@ -7761,10 +7761,10 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rua-three@^1.0.9:
version "1.0.9"
resolved "https://registry.npmjs.org/rua-three/-/rua-three-1.0.9.tgz#64f6d9d27ff6982fabe82125cd9d5013725f6c51"
integrity sha512-elvrI+NLCx0t50jJsxTVktqmUXEM7EmwbDC9b1Js4lupnjVIvkCFknZ+7AMGRIri5150XxTxr03aH30hiqFY8w==
rua-three@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/rua-three/-/rua-three-1.1.1.tgz#c6d2e28fc60ed4e3bde5018332787c014515d7a3"
integrity sha512-eESIlFHebKIQjWKlDGoRHmeXTniCu32o8U5DhKCYXtDXC9kyXcOa5mqJBAR7nRD1QCrSd7LFKg+wdkSIKdVIYQ==
run-async@^2.4.0:
version "2.4.1"