Hey, I'm getting two rendered Images in my donut.js file. I've studied the tutorial and native codebase to find the problem, but I'm stumped. Is this a dependency issue with React?
#36
donut.js
`
import { useState, useEffect, useRef, useCallback } from 'react'
import { Box, Spinner } from '@chakra-ui/react'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { loadGLTFModel } from '../lib/model'
function easeOutCirc(x) {
return Math.sqrt(1 - Math.pow(x - 1, 4))
}
const Donut = () => {
const refContainer = useRef()
const [loading, setLoading] = useState(true)
const [renderer, setRenderer] = useState()
const [_camera, setCamera] = useState()
const [target] = useState(new THREE.Vector3(-0.5, 1.2, 0))
const [initialCameraPosition] = useState(
new THREE.Vector3(
20 * Math.sin(0.2 * Math.PI),
10,
20 * Math.cos(0.2 * Math.PI)
)
)
const [scene] = useState(new THREE.Scene())
const [_controls, setControls] = useState()
const handleWindowResize = useCallback(() => {
const { current: container } = refContainer
if (container && !renderer) {
const scW = container.clientWidth
const scH = container.clientHeight
renderer.setSize(scW, scH)
}
}, [renderer])
/* eslint-disable react-hooks/exhaustive deps */
useEffect(() => {
const { current: container} = refContainer
if (container && !renderer) {
const scW = container.clientWidth
const scH = container.clientHeight
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
})
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(scW, scH)
renderer.outputEncoding = THREE.sRGBEncoding
container.appendChild(renderer.domElement)
setRenderer(renderer)
const scale = scH * 0.005 + 25.8
const camera = new THREE.OrthographicCamera(
-scale,
scale,
scale,
-scale,
0.01,
5000
)
camera.position.copy(initialCameraPosition)
camera.lookAt(target)
setCamera(camera)
const ambientLight = new THREE.AmbientLight(0xcccccc, 1)
scene.add(ambientLight)
const controls = new OrbitControls (camera, renderer.domElement)
controls.autoRotate = true
controls.target = target
setControls(controls)
loadGLTFModel(scene, '/totoro.glb', {
receiveShadow: false,
castShadow: false
}).then(() => {
animate()
setLoading(false)
})
let req=null
let frame= 0
const animate = () => {
req = requestAnimationFrame(animate)
frame = frame <= 100 ? frame + 1 : frame
if(frame <= 100) {
const p = initialCameraPosition
const rotSpeed = -easeOutCirc(frame / 120) * Math.PI * 20
camera.position.y = 5
camera.position.x = p.x * Math.cos(rotSpeed) + p.z * Math.sin(rotSpeed)
camera.position.z = p.z * Math.cos(rotSpeed) - p.x * Math.sin(rotSpeed)
camera.lookAt(target)
} else {
controls.update()
}
renderer.render(scene, camera)
}
return () => {
console.log('unmount')
cancelAnimationFrame(req)
renderer.dispose()
}
}
}, [])
useEffect(() => {
window.addEventListener('resize', handleWindowResize, false)
return () => {
window.removeEventListener('resize', handleWindowResize, false)
}
}, [renderer, handleWindowResize])
return (
<Box
ref={refContainer}
className="donut"
m="auto"
at={['-20px', '-60px', '-120px' ]}
mb={['-40px', '-140px', '-200px' ]}
w={[280, 480, 640]}
h={[280, 480, 640]}
position="relative"
>
{loading && (
<Spinner
size="xl"
position="absolute"
left="50%"
top="50%"
ml="calc(0px - var(--spinner-size) /2"
mt="calc(0px - var(--spinner-size))"
/>
)}
</Box>
)
}
`
export default Donut
Main.js
`
import Head from 'next/head'
import Navbar from '../navbar'
import NoSsr from '../no-ssr'
import { Box, Container } from '@chakra-ui/react';
import Donut from '../donut'
const Main = ({ children, router }) => {
return (
<title>Darkskittlz - Homepage </title>
{children}
)
}
export default Main;
`
Donut-Loader
`
import { forwardRef } from 'react'
import { Box, Spinner } from '@chakra-ui/react'
export const DonutSpinner = () => (
)
export const DonutContainer = forwardRef(({ children }, ref) => (
<Box
ref={ref}
className="donut"
m="auto"
mt={['-20px', '-60px', '-120px']}
mb={['-40px', '-140px', '-200px']}
w={[280, 480, 640]}
h={[280, 480, 640]}
position="relative"
))
const Loader = () => {
return (
)
}
export default Loader
`
_app.js
`
import { ChakraProvider } from "@chakra-ui/react"
import Layout from '../components/layouts/main'
import Fonts from '../components/fonts'
import theme from '../lib/theme'
import { AnimatePresence } from 'framer-motion'
import { Suspense } from "react"
const Website = ({ Component, pageProps, router }) => {
return (
<Component {...pageProps} key={router.route} />
)
}
export default Website;
`
index.js
`
import {
Link,
Box,
Button,
Heading,
Container,
Text,
useColorModeValue
} from '@chakra-ui/react'
import { ChevronRightIcon } from '@chakra-ui/icons'
import Layout from '../components/layouts/article'
import styled from '@emotion/styled'
import Section from '../components/section'
import Paragraph from '../components/paragraph';
import { GridItem } from '../components/grid-item';
import Image from 'next/image';
const BioSection = styled(Box) padding-left: 3.4em; text-indent: -3.4em;
const BioYear = styled.spanfont-weight: bold; margin-right: 1em;
const Page = () => {
return (
<Box
borderRadius="lg"
bg={useColorModeValue('whiteAlpha.500', 'whiteAlpha.200')}
css={{ backdropFilter: 'blur(10px)' }}
align="center"
h={12}
ml={50}
mr={50}
mb={6}
p={3}
>
Hello, I'm a full-stack developer based in Miami!
<Box
display={{md: 'flex'}}
style={{flexDirection: "column"}}
>
Tristan Carlisle
Digital Artist, Developer, Designer
<Box
flexShrink={0}
mt={{ base: 4, md: 0 }}
ml={{ md: 6 }}
align="center"
>
<Section delay={0.1}>
<Heading as="h3" variant="section-title">
Work
</Heading>
<Paragraph>
Tristan is a react developer who specializes in the MERN/PERN stack. He enjoys developing frontend user interfaces that prioritize sleek design, integrate background animations, and consume APIs to display interactive information.
As a blockchain engineer, he enjoys connecting frontend web applications with the blockchain via Web3js.
</Paragraph>
<Box align="center" my={4}>
<Link href="/works">
<Button rightIcon={<ChevronRightIcon />} colorScheme="teal">
My Portfolio
</Button>
</Link>
</Box>
</Section>
<Section delay={0.2}>
<Heading as="h3" variant="section-title">
Bio
</Heading>
<BioSection>
<BioYear>1993</BioYear>
Born in Miami, FL
</BioSection>
<BioSection>
<BioYear>2020</BioYear>
Began programming journey with CodeAcademy & FreeCodeCamp
</BioSection>
</Section>
<Section delay={0.3}>
<Heading as="h3" variant="section-title">
I ❤
</Heading>
<Paragraph>Programming, 3D Rendering, Crypto, Rock Climbing, Parkour, Drums, Guitar {' '}
<Link href="https://beacons.ai/darkskittlz">Cosplay, </Link>
Skateboarding,
<Link href="https://beacons.ai/darkskittlz"> Youtube</Link>
</Paragraph>
</Section>
<Section delay={0.4}>
<Heading as="h3" variant="section-title">
Inspired By
</Heading>
<Paragraph>{' '}
<Link href="https://www.craftz.dog/">Takuyama Matsuyama </Link>
</Paragraph>
</Section>
</Container>
</Layout>
)
}
export default Page;
`
Thank you @craftzdog for your help. 🆘 ⛑️