From f81e93726d270e9e8f77b7f9baa00a5100f66f28 Mon Sep 17 00:00:00 2001 From: DefectingCat Date: Sat, 8 Oct 2022 17:38:00 +0800 Subject: [PATCH] update mouse hover --- package.json | 2 +- pages/index.tsx | 70 ++++++++++++++++++++++++++++++++++++++++--------- yarn.lock | 8 +++--- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index ffc034e..a3fb0da 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/pages/index.tsx b/pages/index.tsx index 77ce5eb..76ea984 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -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(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,14 +49,25 @@ 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; + const init: InitFn = ({ + scene, + camera, + controls, + frameArea, + isOrbitControls, + isPerspectiveCamera, + addWindowEvent, + }) => { + if (isOrbitControls(controls)) { + controls.enableRotate = false; + 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 light = new THREE.SpotLight(0xffffff, 1.4, 100, 15); @@ -72,20 +86,50 @@ const Home: NextPageWithLayout = () => { light.target = root; light.position.set(0, 2, 4); 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.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 ( diff --git a/yarn.lock b/yarn.lock index 0ebad85..7bc6522 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"