Merge pull request #7 from MetaFam/fix/mac-issues

Fix/mac issues
This commit is contained in:
luxumbra
2022-05-23 19:39:20 +01:00
committed by GitHub
13 changed files with 346 additions and 475 deletions

View File

@@ -54,12 +54,13 @@ const OctoEasterEgg = (props) => {
ref={mesh}
name="BabyOcto"
// scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]}
rotation={[0,0,0]}
rotation={[0, 0, 0]}
onClick={(e) => setActive(!active)}
dispose={null}
>
<planeBufferGeometry attach="geometry" args={[1, 1]} />
<meshBasicMaterial attach="material" ref={material} />
</mesh>
<meshBasicMaterial attach="material" ref={material} />
</mesh>
)
};

View File

@@ -6,19 +6,22 @@ import { EffectComposer, DepthOfField } from '@react-three/postprocessing'
import { useControls, folder } from 'leva'
import { CanvasLoader } from '@/components/canvas/Loader'
import { useCallback } from 'react'
// eslint-disable-next-line react/display-name
const Galaxy = ({ dof, parameters, nucleus, helper, effects, ...props }) => {
const group = useRef();
const particles = useRef()
const particles = useRef(null)
const material = useRef()
const geometry = useRef()
const points = useRef()
//const [movement] = useState(() => new THREE.Vector3())
const [temp] = useState(() => new THREE.Vector3())
const [focus] = useState(() => new THREE.Vector3())
const clock = new THREE.Clock();
let previousTime = 0;
const galaxyCreated = useRef(false);
/**
* Textures
*/
@@ -29,19 +32,22 @@ const Galaxy = ({ dof, parameters, nucleus, helper, effects, ...props }) => {
planeAlphaTexture.generateMipmaps = true;
// const { animationRef } = props
useEffect(() => {
generateGalaxy()
// console.log(dof);
})
if (!galaxyCreated.current) {
generateGalaxy()
}
console.log('Galaxy created: ', galaxyCreated.current);
}, [galaxyCreated, generateGalaxy])
useFrame((state, delta) => {
const elapsedTime = clock.getElapsedTime();
const deltaTime = elapsedTime - previousTime;
previousTime = elapsedTime;
//dof.current.target = focus.lerp(particles.current.position, 0.05)
//movement.lerp(temp.set(state.mouse.x, state.mouse.y * 0.2, 0), 0.2)
if (dof.current) {
dof.current.target = focus.lerp(particles.current.position, 0.05)
movement.lerp(temp.set(state.mouse.x, state.mouse.y * 0.2, 0), 0.2)
dof.current.circleOfConfusionMaterial.uniforms.focusDistance.value = parameters.focusDistance
dof.current.circleOfConfusionMaterial.uniforms.focalLength.value = parameters.focalLength
dof.current.resolution.height = parameters.height
@@ -68,13 +74,16 @@ const Galaxy = ({ dof, parameters, nucleus, helper, effects, ...props }) => {
})
const generateGalaxy = () => {
/**
* TODO: Look at converting the positions/particles to a `useMemo` which i hope will improve matters on MacOS.
* */
const generateGalaxy = useCallback(() => {
const positions = new Float32Array(parameters.count * 3)
const colors = new Float32Array(parameters.count * 3)
const colorInside = new THREE.Color(parameters.insideColor)
const colorOutside = new THREE.Color(parameters.outsideColor)
const sections = 6;
const sections = 7;
const objectsDistance = 4;
@@ -245,28 +254,23 @@ const Galaxy = ({ dof, parameters, nucleus, helper, effects, ...props }) => {
// material.current.opacity = parameters.opacity
// }
}
galaxyCreated.current = true;
}, [parameters, planeAlphaTexture, planeColorTexture])
return (
<>
<Suspense fallback={<CanvasLoader />}>
<group ref={group} {...props}>
<points ref={particles}>
<bufferGeometry />
<pointsMaterial ref={material} size={parameters.size} sizeAttenuation={true} depthWrite={true} vertexColors={true} blending={THREE.AdditiveBlending} />
</points>
{nucleus && (
<Nucleus size={0.125} />
)}
{helper && (
<axesHelper args={[2, 2, 2]} />
)}
</group>
</Suspense>
{/* {effects && (
<Effects ref={dof} />
)} */}
<group ref={group} {...props} dispose={null}>
<points ref={particles}>
<bufferGeometry ref={geometry} />
<pointsMaterial ref={material} size={parameters.size} sizeAttenuation={true} depthWrite={true} vertexColors={true} blending={THREE.AdditiveBlending} />
</points>
{nucleus && (
<Nucleus size={0.125} />
)}
{helper && (
<axesHelper args={[2, 2, 2]} />
)}
</group>
</>
)
}

View File

@@ -1,76 +0,0 @@
import React, { Suspense, useEffect, useMemo, useRef, useState } from "react";
import { useFrame, useLoader } from '@react-three/fiber'
import { TextureLoader } from 'three/src/loaders/TextureLoader'
import { useGLTF, useTexture } from "@react-three/drei";
import * as THREE from "three";
import gsap from "gsap";
import useStore from '@/helpers/store'
import SeedLogo from "@/static/assets/textures/particles/seed_logo.png";
// import BabyOctoImg from "../static/assets/textures/baby_octo_alpha_0001.png";
// import BabyOctoAlpha from "../static/assets/textures/baby_octo_alpha_map.png";
export const starfieldParams = {
count: 35000,
size: 0.01
}
export default function Starfield({ parameters, ...props }) {
const group = useRef();
const particles = useRef();
const clock = new THREE.Clock();
let previousTime = 0;
const sections = 6;
const objectsDistance = 4;
const particleTextures = useTexture({
map: '/assets/textures/particles/seed_logo.png'
})
useEffect(() => {
console.log(parameters);
generateStarfield();
});
function generateStarfield() {
const positions = new Float32Array(parameters.count * 3);
const colors = new Float32Array(parameters.count * 3);
for (let i = 0; i < parameters.count; i++) {
const i3 = i * 3;
positions[i3 + 0] = (Math.random() - 0.5) * 10;
positions[i3 + 1] =
objectsDistance * 0.8 -
Math.random() * objectsDistance * (sections.length * 2);
positions[i3 + 2] = (Math.random() - 0.5) * 10;
}
// if (particles.current) {
// console.log('pc:', particles);
particles.current.geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
particles.current.geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))
// }
}
// useFrame(() => {
// const elapsedTime = clock.getElapsedTime();
// const deltaTime = elapsedTime - previousTime;
// previousTime = elapsedTime;
// // if (group.current) {
// // // group.current.position.x = -3.5 + Math.sin(elapsedTime * 0.9) * Math.PI * 0.05;
// // // group.current.position.y = -1.5 - Math.cos(elapsedTime * 0.1) * Math.PI * 0.5;
// // // group.current.rotation.y = elapsedTime * 0.6;
// // }
// })
return (
// <Suspense fallback={null}>
// <group ref={group} {...props}>
<points ref={particles}>
<bufferGeometry attach="geometry" />
<pointsMaterial attach="material" size={parameters.size} {...particleTextures} sizeAttenuation={true} depthWrite={true} vertexColors={true} blending={THREE.AdditiveBlending} />
</points>
// </group>
// </Suspense>
);
}

View File

@@ -142,191 +142,6 @@ let geometry = null
let material = null
let points = null
export const generateGalaxy = (params) => {
// Destroy old galaxy
if (points !== null) {
geometry.dispose()
material.dispose()
scene.remove(points)
}
/**
* Geometry
*/
geometry = new THREE.BufferGeometry()
const positions = new Float32Array(params.count * 3)
const colors = new Float32Array(params.count * 3)
const colorInside = new THREE.Color(params.insideColor)
const colorOutside = new THREE.Color(params.outsideColor)
// Type 1
if (params.type === 1) {
for (let i = 0; i < params.count; i++) {
const i3 = i * 3
const radius = Math.random() * params.radius
const spinAngle = radius * params.spin
const branchAngle = (i % params.branches) / params.branches * Math.PI * 2
const randomX = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomY = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomZ = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
positions[i3 + 0] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = Math.sin(spinAngle + radius) * (radius - Math.PI * 2)
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / params.radius * 1.1)
colors[i3 + 0] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
if (i < 20) {
console.log(params.type, i, branchAngle)
}
}
} else if (params.type === 2) {
for (let i = 0; i < params.count; i++) {
const i3 = i * 3
const radius = Math.random() * params.radius
const spinAngle = radius * params.spin
const branchAngle = (i % params.branches) / params.branches * Math.PI * 0.5
const randomX = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomY = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomZ = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
positions[i3 + 0] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = (Math.PI * 0.12) * radius + randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / params.radius * 1.1)
colors[i3 + 0] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
if (i < 20) {
console.log(params.type, i, branchAngle)
}
}
} else if (params.type === 3) {
for (let i = 0; i < params.count; i++) {
const i3 = i * 3
const radius = Math.random() * params.radius
const spinAngle = radius * params.spin
const branchAngle = (i % params.branches) / params.branches * Math.PI * 2
const randomX = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomY = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomZ = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
positions[i3 + 0] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = Math.cos(spinAngle + radius) * radius + randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / params.radius * 2)
colors[i3 + 0] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
if (i < 20) {
console.log(params.type, i, branchAngle)
}
}
} else if (params.type === 4) {
for (let i = 0; i < params.count; i++) {
const i3 = i * 3
const radius = Math.random() * params.radius
const spinAngle = radius * params.spin
const branchAngle = (i % params.branches) / params.branches * Math.PI * 2
const randomX = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomY = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomZ = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
positions[i3 + 0] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = Math.sin(branchAngle - spinAngle) * radius + randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / params.radius * 1.5)
colors[i3 + 0] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
if (i < 20) {
console.log(params.type, i, branchAngle)
}
}
} else if (params.type === 5) {
for (let i = 0; i < params.count; i++) {
const i3 = i * 3
const radius = Math.random() * params.radius
const spinAngle = radius * params.spin
const branchAngle = (i % params.branches) / params.branches * Math.PI * 2
const randomX = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomY = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
const randomZ = Math.pow(Math.random(), params.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
positions[i3 + 0] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = Math.sin(branchAngle - spinAngle) * radius + randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / params.radius * 1.5)
colors[i3 + 0] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
if (i < 20) {
console.log(params.type, i, branchAngle)
}
}
}
geometry.setAttribute(
'position',
new THREE.BufferAttribute(positions, 3)
)
geometry.setAttribute(
'color',
new THREE.BufferAttribute(colors, 3)
)
/**
* Materials
*/
material = new THREE.PointsMaterial({
size: params.size,
sizeAttenuation: true,
// depth: false,
blending: THREE.AdditiveBlending,
vertexColors: true
})
/**
* Points
*/
points = new THREE.Points(geometry, material)
return points
}

View File

@@ -1,14 +1,29 @@
import { useState, useRef } from 'react'
import { useEffect, useState, useRef } from 'react'
import {
Text,
IconButton,
Box,
} from '@chakra-ui/react'
import { CloseIcon } from '@chakra-ui/icons'
import {getFromLS, saveToLS, localStore} from '@/helpers/store'
import { useIsMac } from '@/utils/hooks';
export function AlphaNotice() {
const [toggle, setToggle] = useState(true);
const notice= useRef(null);
const [toggle, setToggle] = useState(false);
const { dismiss } = localStore.get('MF2AlphaNotice') || { dismiss: toggle };
const notice = useRef(null);
const macOS = useIsMac();
const handleClick = () => {
setToggle(false);
localStore.set('MF2AlphaNotice', { dismiss: true });
}
useEffect(() => {
if (!dismiss) {
setToggle(true);
}
}, [dismiss]);
return (
<Box
@@ -37,32 +52,47 @@ export function AlphaNotice() {
justifyContent="space-around"
flexFlow="row nowrap"
mx="auto"
maxW={{base: '75%', md: '66%', '2xl': "6xl"}}
px={{base: 5, lg: 3}}
maxW={{ base: '75%', md: '66%', '2xl': "6xl" }}
px={{ base: 5, lg: 3 }}
py={3}
>
{/* <Image src={BabyOctoGif} boxSize="25px" objectFit="cover" /> */}
<Text fontSize={{base: "2vmin", lg: '0.7vmax'}} fontWeight={700}>
The site is in{" "}
<Text as="span" color="cyan" fontWeight="700">
Beta
{!macOS ? (
<Text fontSize={{ base: "2vmin", lg: '0.7vmax' }} fontWeight={700}>
The site is in{" "}
<Text as="span" color="cyan" fontWeight="700">
Beta
</Text>
.{" "}
<span role="img" aria-label="watchful eyes">
👀
</span>{" "}
We&apos;re still working on content, there&apos;s no Web3 connectivity (or is there...?) and there are some bugs. <br /> We&apos;re working to get it all ship shape ASAP!
</Text>
.{" "}
<span role="img" aria-label="watchful eyes">
👀
</span>{" "}
We&apos;re still working on content, there&apos;s no Web3 connectivity (or is there...?) and there
are some bugs. <br /> We&apos;re working to get it
all ship shape ASAP!
</Text>
) : (
<Text fontSize={{ base: "2vmin", lg: '0.7vmax' }} fontWeight={700}>
It would appear that you&apos;re on a{" "}
<Text as="span" color="cyan" fontWeight="700">
Mac
</Text>
.{" "}
<span role="img" aria-label="watchful eyes">
👀
</span>{" "}
<br />
There&apos;s an issue with ThreeJS and OSX where some features cause issues in the browser so we have disabled this functionality for the time being. Apologies.
</Text>
)}
{/* <Image src={BabyOctoGif} boxSize="35px" objectFit="cover" /> */}
<IconButton
onClick={() => setToggle(!toggle)}
onClick={handleClick}
colorScheme="ghost"
color="#927CFF"
pos="fixed"
bottom={3}
right={{base: 2, lg: 6}}
right={{ base: 2, lg: 6 }}
size="sm"
aria-label="Close notice"
icon={<CloseIcon />}

View File

@@ -16,7 +16,7 @@ import SeedLogo from "../img/assets/textures/particles/seed_logo.png";
import BabyOctoImg from "../static/assets/textures/baby_octo_alpha_0001.png";
import BabyOctoAlpha from "../static/assets/textures/baby_octo_alpha_map.png";
export const Canvas = ({toggleAnimations}) => {
export const Canvas = ({ toggleAnimations }) => {
useEffect(() => {
if (typeof window !== "undefined") {
const canvas = document.querySelector("canvas.webgl");
@@ -601,12 +601,12 @@ export const Canvas = ({toggleAnimations}) => {
//Click events
window.addEventListener("click", () => {
console.log(easterEgg1[0].classList);
// console.log(easterEgg1[0].classList);
if (currentIntersect) {
console.log("i", currentIntersect);
if (currentIntersect === plane1 || currentIntersect === plane3 || currentIntersect === galaxy1) {
easterEgg1[0].classList.toggle("found");
console.log(easterEgg1[0].classList);
// console.log(easterEgg1[0].classList);
}
} else {
console.log("no intersect", currentIntersect);
@@ -684,16 +684,16 @@ export const Canvas = ({toggleAnimations}) => {
const objectsToTest = [plane1, plane3];
const intersects = raycaster.intersectObjects(objectsToTest, false);
if (intersects.length) {
console.log('length', intersects.length);
console.log("Something is being hovered");
// console.log('length', intersects.length);
// console.log("Something is being hovered");
if (currentIntersect === null) {
}
currentIntersect = intersects[0];
console.log("mouse enter", currentIntersect);
// console.log("mouse enter", currentIntersect);
} else {
if (currentIntersect) {
console.log("mouse leave");
// console.log("mouse leave");
// easterEgg1.classList.remove('found')
}
currentIntersect = null;
@@ -709,7 +709,7 @@ export const Canvas = ({toggleAnimations}) => {
// if(toggleAnimations) return
// Call tick again on the next frame
window.requestAnimationFrame(tick);
window.requestAnimationFrame(tick);
};
tick();

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import {
Box,
Flex,
@@ -207,7 +207,6 @@ export function SiteHeader() {
</HStack>
</HStack>
<Flex alignItems="center" justifyContent="end" width={{ base: "25%", md: 'auto' }}>
<UIToggles />
{screenSize !== 'base' ? (
<Link
className="ui"
@@ -226,8 +225,8 @@ export function SiteHeader() {
Join MetaGame
</Link>
) : (
<Link
className="ui"
<Link
className="ui"
href="https://metagame.wtf"
px={0}
py={0}
@@ -292,106 +291,7 @@ export function SiteHeader() {
);
}
export const UIToggles = () => {
const [uiOn, setUiOn] = useState(true);
const [canvasOn, setCanvasOn] = useState(true)
const { dom } = useStore()
const screenSize = useBreakpoint()
const mob = screenSize === 'base' ? '-mob' : ''
const homeBg = `assets/img/home-bg${mob}.jpg`
const scheduleBg = `assets/img/schedule-bg${mob}.jpg`
const workshopsBg = `assets/img/workshops-bg${mob}.jpg`
const speakersBg = `assets/img/speakers-bg${mob}.jpg`
const metaverseBg = `assets/img/metaverse-bg${mob}.jpg`
const chatBg = `assets/img/chat-bg${mob}.jpg`
const applyBg = `assets/img/apply-bg${mob}.jpg`
const toggleUI = () => {
if (typeof window !== 'undefined') {
const ui = document.querySelectorAll('.ui')
const content = document.querySelectorAll('section')
ui.forEach((item, i) => {
item.style.transition = 'transform 0.3s 0.1s ease, opacity 0.3s 0.2s'
console.log(item);
if (uiOn) {
item.style.opacity = 0
} else {
item.style.opacity = 1
}
})
content.forEach((item, i) => {
item.style.transition = 'opacity 0.3s 0.4s ease'
console.log(item);
if (uiOn) {
item.style.opacity = 0
} else {
item.style.opacity = 1
}
})
setUiOn(!uiOn)
}
}
const toggleCanvas = () => {
if (typeof window !== 'undefined') {
const canvas = document.querySelector('canvas')
const content = document.querySelectorAll('section')
if (canvas.style.display === 'block') {
canvas.style.display = 'none'
content[0].style.backgroundImage = `url(${homeBg})`
content[1].style.backgroundImage = `url(${scheduleBg}) `
content[2].style.backgroundImage = `url(${workshopsBg}) `
content[3].style.backgroundImage = `url(${speakersBg}) `
content[4].style.backgroundImage = `url(${metaverseBg})`
content[5].style.backgroundImage = `url(${chatBg})`
content[6].style.backgroundImage = `url(${applyBg})`
} else {
canvas.style.display = 'block'
content.forEach(item => {
item.style.background = `none`
})
}
setCanvasOn(!canvasOn)
}
}
return (
<HStack fontSize={{ base: '3vw', lg: '0.7vw' }} fontWeight={500} position="fixed" bottom={5} right={{base: 3, lg: 5}} opacity={0.5} transition="opacity 0.3s ease" _hover={{
opacity: 1
}}>
<VStack spacing={0}>
<IconButton
icon={uiOn ? <FaToggleOn /> : <FaToggleOff />}
aria-label="Toggle UI"
flex={0}
fontSize={{ base: '12vmin', lg: "2vmax" }}
colorScheme="ghost"
color={uiOn ? "#FF61E6" : "#7C56FF"}
alignSelf="center"
onClick={toggleUI}
/>
<Text as="span">UI</Text>
</VStack>
<VStack spacing={0}>
<IconButton
icon={canvasOn ? <FaToggleOn /> : <FaToggleOff />}
aria-label="Toggle Effects"
flex={0}
fontSize={{ base: '12vmin', lg: "2vmax" }}
colorScheme="ghost"
color={canvasOn ? "#FF61E6" : "#7C56FF"}
alignSelf="center"
onClick={toggleCanvas}
/>
<Text as="span">Effects</Text>
</VStack>
</HStack>
)
}
export const MenuIcon2SVG = ({ toggle }) => (
<Box>

View File

@@ -1,18 +1,14 @@
import dynamic from 'next/dynamic'
import { Canvas, useFrame } from '@react-three/fiber'
import * as THREE from "three";
import { Environment, OrbitControls, Preload } from '@react-three/drei'
import {
Box
} from '@chakra-ui/react'
import useStore from '@/helpers/store'
import { Suspense, useCallback, useEffect, useRef, useState } from 'react'
import { EffectComposer, Bloom, Glitch, GodRays, Scanline, DepthOfField, Vignette } from '@react-three/postprocessing';
import { EffectComposer, Glitch, Scanline, DepthOfField, Vignette } from '@react-three/postprocessing';
import { GlitchMode, BlendFunction } from 'postprocessing'
// const { OctoEasterEggR3F } = dynamic(() => import('@/components/canvas/EasterEgg.r3f'), {
// ssr: false,
// })
import { CanvasLoader } from '@/components/canvas/Loader'
import { useIsMac } from '@/utils/hooks';
const LControl = () => {
const dom = useStore((state) => state.dom)
@@ -29,12 +25,14 @@ const LControl = () => {
return <OrbitControls ref={control} domElement={dom.current} />
}
const LCanvas = ({ children }) => {
const dom = useStore((state) => state.dom)
const { dom } = useStore()
const [on, setOn] = useState(false)
const macOS = useIsMac();
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
const canvas = useRef();
const delay = (() => { });
const glitchEgg = dom.current.querySelector('.ee2');
const onPointerUp = useCallback(() => {
if (delay.current) clearTimeout(delay.current)
@@ -57,7 +55,7 @@ const LCanvas = ({ children }) => {
useEffect(() => {
if (typeof window !== 'undefined') {
const el = dom.current
if(isMobile) return
if (isMobile) return
el.addEventListener('pointerup', onPointerUp)
el.addEventListener('pointerdown', onPointerDown)
@@ -78,6 +76,7 @@ const LCanvas = ({ children }) => {
shadows="PCFSoft"
dpr={Math.min(2, isMobile && typeof window !== 'undefined' ? window.devicePixelRatio : 1)}
style={{
display: macOS ? 'none' : 'block',
position: 'fixed',
top: 0,
width: '100%',
@@ -88,8 +87,8 @@ const LCanvas = ({ children }) => {
onCreated={(state) => state.events.connect(dom.current)}
>
{/* <LControl /> */}
<Preload all />
<Suspense fallback={<CanvasLoader />}>
<Preload all />
<Environment preset="forest" />
{children}
<Effect on={on} />
@@ -101,7 +100,6 @@ const LCanvas = ({ children }) => {
export default LCanvas
export const Effect = ({ on }) => {
// console.log('onoff', on);
const [material, setMaterial] = useState()
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
const clock = new THREE.Clock();
@@ -124,9 +122,9 @@ export const Effect = ({ on }) => {
<Scanline density={on ? 3.5 : 50} blendFunction={BlendFunction.OVERLAY} />,
<DepthOfField focusDistance={2} focalLength={0.5} bokehScale={6} />,
<Scanline density={on ? 3.5 : 0} blendFunction={on && BlendFunction.OVERLAY} />
)}
)}
<Glitch active={on} ratio={0.89} delay={[0.5, 2]} strength={[0.1, 0.5]} mode={GlitchMode.CONSTANT_WILD} />
<Glitch active={on} ratio={0.89} delay={[0.5, 2]} strength={[0.1, 0.5]} mode={GlitchMode.CONSTANT_WILD} />
</EffectComposer>
)

View File

@@ -1,19 +1,33 @@
import useStore from '@/helpers/store'
import { useEffect, useRef } from 'react'
import useStore, {getFromLS, saveToLS, localStore} from '@/helpers/store'
import { useEffect, useRef, useState } from 'react'
import {
Box,
HStack,
IconButton,
Text,
VStack,
} from "@chakra-ui/react";
import {SiteHeader} from "@/components/dom/Header";
import { FaToggleOn, FaToggleOff } from 'react-icons/fa'
import { useIsMac } from "@/utils/hooks";
import { SiteHeader } from "@/components/dom/Header";
import { SiteFooter } from "@/components/dom/Footer";
import { AlphaNotice } from '@/components/dom/AlphaNotice';
import { EasterEgg } from '@/components/dom/EasterEgg';
import { EasterEggGlitch } from '@/components/dom/EasterEggGlitch';
import { useCallback } from 'react';
const Dom = ({ children }) => {
const ref = useRef(null)
const macOS = useIsMac();
useEffect(() => {
useStore.setState({ dom: ref })
}, [])
if (macOS) {
gracefulDegradation(macOS)
useStore.setState({ dom: ref })
} else {
useStore.setState({ dom: ref })
}
}, [macOS])
return (
<Box
@@ -29,15 +43,16 @@ const Dom = ({ children }) => {
m: 0,
p: 0,
section: {
scrollSnapAlign: { base: "start" },
scrollSnapStop: { base: "smooth" },
scrollSnapAlign: { base: "start", lg: 'unset' },
scrollSnapStop: { base: "smooth", lg: 'unset' },
},
}}
>
<SiteHeader />
{children}
<SiteFooter />
<AlphaNotice />
<UIToggles />
<AlphaNotice />
<EasterEgg />
<EasterEggGlitch />
</Box>
@@ -45,3 +60,142 @@ const Dom = ({ children }) => {
}
export default Dom
export const UIToggles = () => {
const macOS = useIsMac();
const [canvasOn, setCanvasOn] = useState(macOS ? false : true)
const { on } = localStore.get('MF2Effects') || { on: canvasOn };
const [uiOn, setUiOn] = useState(true);
const toggleUI = () => {
if (typeof window !== 'undefined') {
const ui = document.querySelectorAll('.ui')
const content = document.querySelectorAll('section')
if (!canvasOn) return;
ui.forEach((item, i) => {
item.style.transition = 'transform 0.3s 0.1s ease, opacity 0.3s 0.2s'
// console.log(item);
if (uiOn) {
item.style.opacity = 0
} else {
item.style.opacity = 1
}
})
content.forEach((item, i) => {
item.style.transition = 'opacity 0.3s 0.4s ease'
// console.log(item);
if (uiOn) {
item.style.opacity = 0
} else {
item.style.opacity = 1
}
})
setUiOn(!uiOn)
}
return
}
const toggleCanvas = useCallback(() => {
if (macOS || !uiOn) return
setCanvasOn(!canvasOn)
gracefulDegradation(canvasOn)
localStore.set('MF2Effects', { on: !canvasOn })
}, [canvasOn, macOS, uiOn])
useEffect(() => {
if(!on && !macOS ) {
setCanvasOn(on)
gracefulDegradation(!on)
} else {
if(!macOS) {
setCanvasOn(on)
gracefulDegradation(!on)
}
}
}, [on, canvasOn, macOS, toggleCanvas]);
return (
<HStack fontSize={{ base: '3vw', lg: '0.7vw' }} fontWeight={500} position="fixed" bottom={5} right={{ base: 3, lg: 5 }} opacity={0.5} transition="opacity 0.3s ease" zIndex={3000} _hover={{
opacity: 1
}}>
<VStack spacing={0}>
<IconButton
icon={uiOn ? <FaToggleOn /> : <FaToggleOff />}
aria-label="Toggle UI"
flex={0}
fontSize={{ base: '12vmin', lg: "2vmax" }}
colorScheme="ghost"
color={uiOn ? "#FF61E6" : "#7C56FF"}
alignSelf="center"
onClick={toggleUI}
isDisabled={macOS || !canvasOn}
/>
<Text as="span">UI</Text>
</VStack>
<VStack spacing={0}>
<IconButton
icon={canvasOn && !macOS ? <FaToggleOn /> : <FaToggleOff />}
aria-label="Toggle Effects"
flex={0}
fontSize={{ base: '12vmin', lg: "2vmax" }}
colorScheme="ghost"
color={canvasOn && !macOS ? "#FF61E6" : "#7C56FF"}
alignSelf="center"
onClick={() => toggleCanvas()}
isDisabled={macOS || !uiOn}
/>
<Text as="span">Effects</Text>
</VStack>
</HStack>
)
}
/**
* MacOS has an issue with performance related to various aspects of ThreeJS/WebGL.
* I *think* using `useMemo` for the particles in Galaxy.jsx would be more performant.
* */
export const gracefulDegradation = (isOn) => {
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
const mob = isMobile ? '-mob' : ''
const homeBg = `assets/img/home-bg${mob}.jpg`
const scheduleBg = `assets/img/schedule-bg${mob}.jpg`
const workshopsBg = `assets/img/workshops-bg${mob}.jpg`
const speakersBg = `assets/img/speakers-bg${mob}.jpg`
const metaverseBg = `assets/img/metaverse-bg${mob}.jpg`
const chatBg = `assets/img/chat-bg${mob}.jpg`
const applyBg = `assets/img/apply-bg${mob}.jpg`
if (typeof window !== 'undefined') {
const content = document.querySelectorAll('section')
const canvas = document.querySelector('canvas')
if (isOn) {
console.log('degrading features');
if (content) {
content[0].style.backgroundImage = `url(${homeBg})`
content[1].style.backgroundImage = `url(${scheduleBg}) `
content[2].style.backgroundImage = `url(${workshopsBg}) `
content[3].style.backgroundImage = `url(${speakersBg}) `
content[4].style.backgroundImage = `url(${metaverseBg})`
content[5].style.backgroundImage = `url(${chatBg})`
content[6].style.backgroundImage = `url(${applyBg})`
}
if (canvas) {
canvas.style.display = 'none'
}
} else {
if (content) {
content.forEach(item => {
item.style.backgroundImage = `unset`
})
}
if (canvas) {
canvas.style.display = 'block'
}
}
}
}

View File

@@ -4,7 +4,35 @@ const useStore = create(() => {
return {
router: null,
dom: null,
os: null,
}
})
export default useStore
export const localStore = {
set: function (key, value) {
if(!global.localStorage) return
if (!key || !value) {return;}
console.log('setter', key, value);
if (typeof value === "object") {
value = JSON.stringify(value);
}
global.localStorage.setItem(key, value);
},
get: function(key) {
const value = global.localStorage ? global.localStorage.getItem(key) : null;
if (!value) {return;}
// assume it is an object that has been stringified
if (value[0] === "{") {
value = JSON.parse(value);
}
return value;
}
}

View File

@@ -1,13 +1,13 @@
import "@/styles/App.css";
import React, { useRouter } from 'next/router'
import { useRouter } from 'next/router'
import useStore from '@/helpers/store'
import { useEffect, useRef } from 'react'
import { useIsMac, useLocalStore } from "@/utils/hooks";
import React, { useEffect, useRef, useState } from 'react'
import { HeadComponent } from "@/components/dom/HeadComponent";
import Dom from '@/components/layout/dom'
import partition from '@/helpers/partition'
import dynamic from 'next/dynamic'
import { settings } from '@/seo.config';
import SocialImg from "@/static/assets/img/social.png";
import { ChakraProvider, CSSReset, extendTheme, useBreakpointValue } from "@chakra-ui/react";
@@ -90,7 +90,7 @@ const theme = extendTheme({
base: "translateY(5px)",
lg: "translateY(9px)",
"2xl": "translateY(10px)",
},
},
}
},
h2: {
@@ -220,19 +220,21 @@ const LCanvas = dynamic(() => import('@/components/layout/canvas'), {
})
const Balance = ({ child }) => {
const [r3f, dom] = partition(child, (c) => c.props.r3f === true)
const [r3f, dom] = partition(child, (c) => c.props.r3f === true);
const mobile = useBreakpointValue({ base: true, lg: false });
const macOS = useIsMac();
return (
<>
<Dom>{dom}</Dom>
<LCanvas isMobile={mobile}>{r3f}</LCanvas>
<LCanvas isMobile={mobile} >{r3f}</LCanvas>
</>
)
}
function App({ Component, pageProps = { title: 'index' } }) {
const router = useRouter()
const { os } = useStore();
const curURL = useRef(null);
let host = curURL ?? curURL.current;
@@ -241,19 +243,25 @@ function App({ Component, pageProps = { title: 'index' } }) {
const getHostname = () => {
if (typeof window !== "undefined") {
curURL.current = window.location.origin;
// console.log(window.location);
// return host;
return null;
console.log('HOST: ', host.current);
return host;
}
};
getHostname();
}
}, [curURL]);
}, [curURL, host]);
useEffect(() => {
useStore.setState({ router })
}, [router])
if (typeof window !== "undefined") {
useStore.setState({
os: navigator.userAgent.toUpperCase() ?? null
})
}
}, [os, router])
const child = Component(pageProps).props.children

View File

@@ -23,7 +23,6 @@ import {
galaxy4Params,
galaxy5Params,
} from '@/components/canvas/galaxies';
import { CanvasLoader } from "@/components/canvas/Loader";
@@ -52,6 +51,7 @@ const Galaxy = dynamic(() => import('@/components/canvas/Galaxy'), {
// dom components goes here
const DOM = () => {
return (
<>
<HomeSection />
@@ -108,7 +108,6 @@ const R3F = () => {
const rayMouse = new THREE.Vector2();
/**
* Animate
*/
@@ -126,7 +125,6 @@ const R3F = () => {
useEffect(() => {
if (typeof window !== "undefined") {
sizes.current = {
width: window.innerWidth,
@@ -309,7 +307,7 @@ const R3F = () => {
if (nomad.current) {
// console.log('mob?', isMobile);
nomad.current.position.y = -1.5 - Math.cos(elapsedTime * 0.1) * Math.PI * 0.05;
nomad.current.position.y = -1.5 - Math.cos(elapsedTime * 0.1) * Math.PI * 0.05;
// group.current.rotation.y = elapsedTime * 0.03;
nomad.current.rotation.z = -0.05 - Math.sin(elapsedTime * 0.3) * Math.PI * 0.03;
@@ -322,9 +320,9 @@ const R3F = () => {
jetsetter.current.rotation.z = -0.05 - Math.sin(elapsedTime * 0.3) * Math.PI * 0.03;
}
if (octoEasterEgg.current) {
octoEasterEgg.current.position.x = -3.5 + Math.sin(elapsedTime * 0.9) * Math.PI * 0.05;
octoEasterEgg.current.position.y = -1.5 - Math.cos(elapsedTime * 0.1) * Math.PI * 0.5;
octoEasterEgg.current.rotation.z = -elapsedTime * 0.06;
octoEasterEgg.current.position.x = -3.5 + Math.sin(elapsedTime * 0.9) * Math.PI * 0.05;
octoEasterEgg.current.position.y = -1.5 - Math.cos(elapsedTime * 0.1) * Math.PI * 0.5;
octoEasterEgg.current.rotation.z = -elapsedTime * 0.06;
}
});
@@ -336,7 +334,7 @@ const R3F = () => {
{/* <Stats /> */}
</group>
<Suspense fallback={<CanvasLoader />}>
<Galaxy
dof={dof}
parameters={galaxy5Params}
@@ -344,10 +342,10 @@ const R3F = () => {
position={[0, -3, -17]} />
<R3FSceneSection name="SectionOne" count={0}>
<group ref={octoEasterEgg}>
<OctoEasterEgg/>
<group ref={octoEasterEgg} dispose={null}>
<OctoEasterEgg />
</group>
<Galaxy dof={dof} parameters={galaxy1Params} position={[6, 0, -13]} rotation={[4.8, 4.15, 4.75]} />
<Galaxy dof={dof1} parameters={galaxy1Params} position={[6, 0, -13]} rotation={[4.8, 4.15, 4.75]} />
</R3FSceneSection>
<R3FSceneSection name="SectionTwo" count={1}>
@@ -355,7 +353,7 @@ const R3F = () => {
</R3FSceneSection>
<R3FSceneSection name="SectionThree" count={2}>
<Galaxy dof={dof} parameters={galaxy2Params} position={[0, -3, -15]} />
<Galaxy dof={dof2} parameters={galaxy2Params} position={[0, -3, -15]} />
</R3FSceneSection>
<R3FSceneSection name="SectionFour" count={3}>
@@ -369,9 +367,9 @@ const R3F = () => {
</R3FSceneSection>
<R3FSceneSection name="SectionSix" count={5}>
<OctoPetVox position={[0, -1.8, 0]} animate={true} rotation={[-Math.PI / 0.51, Math.PI / 4.5, 0]} />
<OctoPetVox position={[0, -1.8, 0]} animate={true} rotation={[-Math.PI / 0.51, Math.PI / 4.5, 0]} />
<BabyEarthVox position={[-1.5, -.8, -2]} animate={true} rotation={[-Math.PI / 0.51, Math.PI / 4.5, 0]} />
<Galaxy dof={dof} parameters={galaxy3Params} position={[6, -6.5, -15]} />
<Galaxy dof={dof3} parameters={galaxy3Params} position={[6, -6.5, -15]} />
</R3FSceneSection>
<R3FSceneSection name="SectionSeven" count={6}>
@@ -379,9 +377,8 @@ const R3F = () => {
<JetsetterVox animate={true} position={[-2, -1.8, 0]} rotation={[-Math.PI / .1, Math.PI / 6.5, 0]}
/>
</group>
<Galaxy dof={dof} parameters={galaxy4Params} position={[3, -1.5, -2]} />
</R3FSceneSection>
</Suspense>
<Galaxy dof={dof4} parameters={galaxy4Params} position={[3, -1.5, -2]} />
</R3FSceneSection>
</>
)
}
@@ -399,6 +396,7 @@ const Page = () => {
export default Page
export async function getStaticProps() {
return {
props: {
title: 'Index',

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { useToast } from "@chakra-ui/react";
import useStore from "@/helpers/store";
export const useOnScreen = (ref) => {
@@ -41,3 +42,13 @@ export const useDisabledMobileNotify = (type) => {
});
return notice;
};
// Tests for Mac users so we can degrade the 3D experience due to Mac/WebGL issues.
export const useIsMac = () => {
const { os } = useStore();
if (os) {
return os.indexOf('MAC') >= 0 ?? false;
}
return false;
}