From 29f87cff84d7ba19b10ff4b44ad10be33d087d02 Mon Sep 17 00:00:00 2001 From: Jan Rychly Date: Tue, 14 Nov 2023 18:07:39 -0900 Subject: [PATCH] Add cool 3D art - introduce three.js and tween.js - render a group of tiles that react to the mouse position - setup components for a background canvas and a moving display target - add a switch to hide the art/distraction --- package.json | 5 +- src/components/CoolArt/CoolArt.tsx | 48 ++++++++++ src/components/CoolArt/CoolArtSwitch.tsx | 22 +++++ src/components/CoolArt/CoolArtTarget.tsx | 42 +++++++++ src/components/CoolArt/animationUtils.ts | 37 ++++++++ src/components/CoolArt/artPositioning.ts | 46 ++++++++++ src/components/CoolArt/index.ts | 3 + src/components/CoolArt/three-main.ts | 109 +++++++++++++++++++++++ src/components/CoolArt/tileMatrix.ts | 48 ++++++++++ src/layouts/Layout.tsx | 24 +++-- src/pages/LandingPage/LandingPage.tsx | 11 ++- src/pages/Things/Things.tsx | 54 ++++++----- src/theme.ts | 2 +- yarn.lock | 40 +++++++++ 14 files changed, 451 insertions(+), 40 deletions(-) create mode 100644 src/components/CoolArt/CoolArt.tsx create mode 100644 src/components/CoolArt/CoolArtSwitch.tsx create mode 100644 src/components/CoolArt/CoolArtTarget.tsx create mode 100644 src/components/CoolArt/animationUtils.ts create mode 100644 src/components/CoolArt/artPositioning.ts create mode 100644 src/components/CoolArt/index.ts create mode 100644 src/components/CoolArt/three-main.ts create mode 100644 src/components/CoolArt/tileMatrix.ts diff --git a/package.json b/package.json index 9087440..4be3e76 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@tweenjs/tween.js": "^21.0.0", "@types/jest": "^27.5.2", "@types/lodash": "^4.14.199", "@types/node": "^16.18.49", @@ -20,7 +21,8 @@ "react-dom": "^18.2.0", "react-router-dom": "^6.15.0", "react-scripts": "5.0.1", - "showdown": "^2.1.0" + "showdown": "^2.1.0", + "three": "^0.157.0" }, "scripts": { "start": "react-scripts start", @@ -55,6 +57,7 @@ "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@types/showdown": "^2.0.2", + "@types/three": "^0.157.2", "@typescript-eslint/eslint-plugin": "^5.60.1", "@typescript-eslint/parser": "^5.60.1", "eslint": "^8.43.0", diff --git a/src/components/CoolArt/CoolArt.tsx b/src/components/CoolArt/CoolArt.tsx new file mode 100644 index 0000000..8bb3626 --- /dev/null +++ b/src/components/CoolArt/CoolArt.tsx @@ -0,0 +1,48 @@ +import { createContext, useContext, useEffect, useRef } from 'react' +import { getRendererDomElement, updateRendererSize } from './three-main' +import { Box, BoxProps } from '@mui/material' +import { mergeSxProps } from '../../utils' + + +export const CoolArtContext = createContext({ hidden: false, setHidden: (val: boolean) => { val; return } }) +export const useCoolArtContext = () => useContext(CoolArtContext) + +export const CoolArt = ({ sx, ...rest }: BoxProps) => { + const canvasContainer = useRef() + const handleWindowResize = () => { + if (canvasContainer.current) + updateRendererSize(canvasContainer.current.offsetWidth, canvasContainer.current.offsetHeight) + } + // Attach the Three.js canvas to this container through a ref + useEffect(() => { + canvasContainer.current?.appendChild(getRendererDomElement()) + handleWindowResize() // also set the size + }, [canvasContainer.current]) + + // Handle canvas resizing + useEffect(() => { + handleWindowResize() + window.addEventListener('resize', handleWindowResize) + return () => window.removeEventListener('resize', handleWindowResize) + }, [canvasContainer, canvasContainer.current]) + + const { hidden } = useCoolArtContext() + + return ( +