From 7de4b7bbfa84dc32c8c7eddf5d7f28e9e548a24b Mon Sep 17 00:00:00 2001 From: tony Date: Wed, 19 Apr 2023 23:11:25 -0700 Subject: [PATCH] Created a contact form section installed three js added test model to contact form section fixed issue with double render of useEffect that was causing it to show up twice once compiled. This was resolved using a boolean check to see if it is mounted first. n Next.js, when you navigate between pages, the entire React tree is unmounted and then remounted. This means that any component with a useEffect hook will run its cleanup function before being unmounted, and then its effect function again when it is remounted. This can cause the effect to run twice. --- .../Elements/ContactThreeJsComponent.jsx | 98 +++++++++++++++++++ Components/Layout/ContactFormSection.jsx | 36 +++++++ Components/Layout/sub-section.jsx | 18 ++++ package-lock.json | 81 ++++++++++++++- package.json | 5 +- pages/about.js | 35 ++++++- pages/index.js | 1 - styles/globals.css | 2 +- tailwind.config.js | 4 + 9 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 Components/Elements/ContactThreeJsComponent.jsx create mode 100644 Components/Layout/ContactFormSection.jsx create mode 100644 Components/Layout/sub-section.jsx diff --git a/Components/Elements/ContactThreeJsComponent.jsx b/Components/Elements/ContactThreeJsComponent.jsx new file mode 100644 index 0000000..0fbc1ae --- /dev/null +++ b/Components/Elements/ContactThreeJsComponent.jsx @@ -0,0 +1,98 @@ +import React, { useRef, useEffect, useState } from 'react'; +import * as THREE from 'three'; +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; +import { RGBShiftShader } from 'three/examples/jsm/shaders/RGBShiftShader.js'; +import { DotScreenShader } from 'three/examples/jsm/shaders/DotScreenShader.js'; + +const ContactThreeJsComponent = React.memo(() => { + const [isMounted, setIsMounted] = useState(false); + const mountRef = useRef(null); + + useEffect(() => { + setIsMounted(true); + + if (isMounted) { + console.log("useEffect called"); + let camera, renderer, composer; + let object; + + function init() { + renderer = new THREE.WebGLRenderer(); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + mountRef.current.appendChild(renderer.domElement); + + camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); + camera.position.z = 400; + + const scene = new THREE.Scene(); + scene.fog = new THREE.Fog(0x000000, 1, 1000); + + object = new THREE.Object3D(); + scene.add(object); + + const geometry = new THREE.SphereGeometry(1, 4, 4); + const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); + + for (let i = 0; i < 100; i++) { + const mesh = new THREE.Mesh(geometry, material); + mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); + mesh.position.multiplyScalar(Math.random() * 400); + mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2); + mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50; + object.add(mesh); + } + + scene.add(new THREE.AmbientLight(0x222222)); + + const light = new THREE.DirectionalLight(0xffffff); + light.position.set(1, 1, 1); + scene.add(light); + + composer = new EffectComposer(renderer); + composer.addPass(new RenderPass(scene, camera)); + + const effect1 = new ShaderPass(DotScreenShader); + effect1.uniforms['scale'].value = 4; + composer.addPass(effect1); + + const effect2 = new ShaderPass(RGBShiftShader); + effect2.uniforms['amount'].value = 0.0015; + composer.addPass(effect2); + + window.addEventListener('resize', onWindowResize); + } + + function onWindowResize() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize(window.innerWidth, window.innerHeight); + composer.setSize(window.innerWidth, window.innerHeight); + } + + function animate() { + requestAnimationFrame(animate); + object.rotation.x += 0.005; + object.rotation.y += 0.01; + composer.render(); + } + + init(); + animate(); + + return () => { + // cleanup logic + window.removeEventListener('resize', onWindowResize); + renderer.dispose(); + composer.dispose(); + }; + } + }, [isMounted]); + + return
; +}); + +export default ContactThreeJsComponent; diff --git a/Components/Layout/ContactFormSection.jsx b/Components/Layout/ContactFormSection.jsx new file mode 100644 index 0000000..7f53426 --- /dev/null +++ b/Components/Layout/ContactFormSection.jsx @@ -0,0 +1,36 @@ +import VideoButton from "/home/clyde/Code/shiloh/Components/Buttons/video-button.jsx"; +import Link from "next/link"; +import ContactThreeJsComponent from "../Elements/ContactThreeJsComponent.jsx"; + +const ContactFormSection = ({ + text, + videoId, + buttonOneText, + buttonTwoText, + buttonLink = "/", // add a default value, +}) => { + + return ( +
+
+ +
+
+
+

{text}

+
+
+ + + {buttonTwoText} + +
+
+
+ ); +}; + +export default ContactFormSection; \ No newline at end of file diff --git a/Components/Layout/sub-section.jsx b/Components/Layout/sub-section.jsx new file mode 100644 index 0000000..92e1a8a --- /dev/null +++ b/Components/Layout/sub-section.jsx @@ -0,0 +1,18 @@ +import Link from "next/link"; + +const SubSection = ({ h2Text, p1Text, h3Text, p2Text }) => { + return ( +
+
+
+

{h2Text}

+
+

{p1Text}

+

{h3Text}

+

{p2Text}

+
+
+ ); +}; + +export default SubSection; diff --git a/package-lock.json b/package-lock.json index 607c367..8533439 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,15 +12,18 @@ "animejs": "^3.2.1", "autoprefixer": "10.4.14", "framer-motion": "^10.12.4", + "grid": "^4.10.8", "next": "13.3.0", "observer": "^0.0.2", + "pagination": "^0.4.6", "postcss": "8.4.22", "react": "^18.2.0", "react-dom": "18.2.0", "react-intersection-observer": "^9.4.3", "react-modal-video": "^2.0.0", "react-player": "^2.12.0", - "tailwindcss": "3.3.1" + "tailwindcss": "3.3.1", + "three": "^0.151.3" } }, "node_modules/@ampproject/remapping": { @@ -2187,6 +2190,11 @@ } ] }, + "node_modules/capitalize": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/capitalize/-/capitalize-0.5.0.tgz", + "integrity": "sha512-PaTkpRT5BKne4tmt7a80HqCikvZCOKKbHkZIycqo77VSKfY/mGW3foKUky6Gi/6MsZmYegctEakY7o5YZXwz5w==" + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2360,6 +2368,11 @@ "node": ">= 10" } }, + "node_modules/click-off": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/click-off/-/click-off-0.2.1.tgz", + "integrity": "sha512-EL4RXbrwIr/Sv3tcvnm5gVGqix8vna4X9q9nm3vZ2co9PmRVwH7XVdd+0sJLZZ/HZQaBPvF9fNRrWeUlBfRgvg==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -3181,6 +3194,19 @@ "node": ">=0.10.0" } }, + "node_modules/element-class": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/element-class/-/element-class-0.1.1.tgz", + "integrity": "sha512-jUN7QxMb2Yv255s/5DYSD0UZoAqC/J1tLVbbYAqzrwDp+yrTcjh6QfinLJEw0lT2h1R23wk27Vcfm/66LfXiIg==", + "dependencies": { + "inherits": "~1.0.0" + } + }, + "node_modules/element-class/node_modules/inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha512-Al67oatbRSo3RV5hRqIoln6Y5yMVbJSIn4jEJNL7VCImzq/kLr7vvb6sFRJXqr8rpHc/2kJOM+y0sPKN47VdzA==" + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -3392,6 +3418,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==" + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3416,6 +3447,11 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escape-stack": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/escape-stack/-/escape-stack-0.1.2.tgz", + "integrity": "sha512-nP/9OVJS7anQGhIYsVhWv1pXtwiuMB5E/N73iux0yjuOpwv5bDvOrtyMGOdB4uz4AYVnDGpe9wqSIOL72X13DA==" + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -4497,6 +4533,24 @@ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, + "node_modules/grid": { + "version": "4.10.8", + "resolved": "https://registry.npmjs.org/grid/-/grid-4.10.8.tgz", + "integrity": "sha512-OKq4zhEj0ojpV+DyskQLpaGr8mSa1ZgA753NPTlJ67xeagqUA0tUjhDg3s0kEF0dEOigxVQ/cWjBMNfzcExtyg==", + "dependencies": { + "capitalize": "^0.5.0", + "click-off": "~0.2.1", + "element-class": "^0.1.1", + "es6-object-assign": "~1.1.0", + "escape-stack": "~0.1.2", + "inner-text-shim": "~1.0.1", + "key": "^0.1.11", + "time-now": "~0.2.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -5010,6 +5064,11 @@ "source-map": "~0.5.3" } }, + "node_modules/inner-text-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/inner-text-shim/-/inner-text-shim-1.0.1.tgz", + "integrity": "sha512-8phW5hjjTpaxobktHFpW0YJcerSc5YS27lPSiF06LJmp5c7/Cms0zw8YORNE3Uy3+pOVjLLHApYA4KEIJiAh3Q==" + }, "node_modules/inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", @@ -5927,6 +5986,11 @@ "node": ">=4.0" } }, + "node_modules/key": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/key/-/key-0.1.11.tgz", + "integrity": "sha512-VCXx+Fo7vtA4/TnNJZg3znjQ9br6egswvnvObuu5gQfgsGay7kpxgbnqZk51y68qLceOYbR0/CUphWfMr9H09w==" + }, "node_modules/keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -8263,6 +8327,11 @@ "node": ">=6" } }, + "node_modules/pagination": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/pagination/-/pagination-0.4.6.tgz", + "integrity": "sha512-TnZ3l17uuC5H9Wlc9FMYuEi65JlUCSn1ZAbnLnvUGkR7RgaFknUNGQTEumhjq1Jy1ePkXSiYUFFbHH70LGb9dA==" + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10489,6 +10558,11 @@ "node": ">=0.8" } }, + "node_modules/three": { + "version": "0.151.3", + "resolved": "https://registry.npmjs.org/three/-/three-0.151.3.tgz", + "integrity": "sha512-+vbuqxFy8kzLeO5MgpBHUvP/EAiecaDwDuOPPDe6SbrZr96kccF0ktLngXc7xA7bzyd3N0t2f6mw3Z9y6JCojQ==" + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -10503,6 +10577,11 @@ "xtend": "~4.0.1" } }, + "node_modules/time-now": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/time-now/-/time-now-0.2.1.tgz", + "integrity": "sha512-DVmKHeai63/4uu1//Ao8HyXOY6jmZYuhk3hng6KwY0y8sa+f8gYPu9UIG58JcRH+sMhcms7iFSEa7TqsUhZeig==" + }, "node_modules/timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", diff --git a/package.json b/package.json index 55b887b..45eab89 100644 --- a/package.json +++ b/package.json @@ -13,14 +13,17 @@ "animejs": "^3.2.1", "autoprefixer": "10.4.14", "framer-motion": "^10.12.4", + "grid": "^4.10.8", "next": "13.3.0", "observer": "^0.0.2", + "pagination": "^0.4.6", "postcss": "8.4.22", "react": "^18.2.0", "react-dom": "18.2.0", "react-intersection-observer": "^9.4.3", "react-modal-video": "^2.0.0", "react-player": "^2.12.0", - "tailwindcss": "3.3.1" + "tailwindcss": "3.3.1", + "three": "^0.151.3" } } diff --git a/pages/about.js b/pages/about.js index 00d0c3c..ea9b71a 100644 --- a/pages/about.js +++ b/pages/about.js @@ -1,7 +1,8 @@ import React from "react"; import Navbar from "../Components/Layout/navbar.jsx"; -import Section from "../Components/Layout/section.jsx" - +import Section from "../Components/Layout/section.jsx"; +import SubSection from "../Components/Layout/sub-section.jsx"; +import ContactFormSection from "@/Components/Layout/ContactFormSection.jsx"; export default function Home() { return ( <> @@ -10,9 +11,33 @@ export default function Home() { key="aboutSection0" videoUrl="https://vid.puffyan.us/latest_version?id=--khbXchTeE&itag=22" text="about" - buttonTwoText="learn more" - buttonOneText="watch" videoId="uu01xBw_BVE" + buttonTwoText="reach out" + buttonOneText="watch" + videoId="uu01xBw_BVE" /> - + + + + + + ); } diff --git a/pages/index.js b/pages/index.js index 3caa4b4..57a00a7 100644 --- a/pages/index.js +++ b/pages/index.js @@ -3,7 +3,6 @@ import React from "react"; import Navbar from "../Components/Layout/navbar.jsx"; import Section from "../Components/Layout/section.jsx" - export default function Home() { return ( <> diff --git a/styles/globals.css b/styles/globals.css index 7eddeb5..217e0fd 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -5,7 +5,7 @@ :root { --foreground-rgb: 0, 0, 0; --background-start-rgb: 39,40,34; - --background-end-rgb:117,113,94; + --background-end-rgb:39,40,34; } @media (prefers-color-scheme: dark) { diff --git a/tailwind.config.js b/tailwind.config.js index e9a97d2..9bf7dca 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -54,6 +54,10 @@ module.exports = { "px-5", "text-base", "px-2", + "text-5xl", + "mx-4", + "px-2", + ], theme: { extend: {