-
-
Save adrianhajdin/7bc0603ee0b1bd2872b80a62c24b5e5f to your computer and use it in GitHub Desktop.
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&family=Work+Sans:wght@100;200;300;400;500;600;700;800;900&display=swap"); | |
@tailwind base; | |
@tailwind components; | |
@tailwind utilities; | |
:root { | |
--blue-rgb: 237 245 255; | |
--green-rgb: 125 161 35; | |
} | |
body { | |
font-family: "Work Sans", sans-serif; | |
} | |
body:has(.card[data-color="blue"]:hover) { | |
background-color: rgb(var(--blue-rgb) / 25%); | |
} | |
body:has(.card[data-color="green"]:hover) { | |
background-color: rgb(var(--green-rgb) / 25%); | |
} | |
@layer utilities { | |
.max-container { | |
@apply max-w-5xl mx-auto sm:p-16 pb-12 !pt-[126px] px-8 min-h-[calc(100vh-80px)]; | |
} | |
.head-text { | |
@apply sm:text-5xl text-3xl font-semibold sm:leading-snug font-poppins; | |
} | |
.subhead-text { | |
@apply font-semibold sm:text-3xl text-xl relative font-poppins; | |
} | |
.blue-gradient_text { | |
@apply bg-gradient-to-r from-[#00c6ff] to-[#0072ff] bg-clip-text text-transparent; | |
} | |
.input { | |
@apply bg-white border border-gray-200 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 mt-2.5 font-normal shadow-card; | |
} | |
.textarea { | |
@apply block p-2.5 w-full text-sm text-gray-900 bg-white rounded-lg border border-gray-200 focus:ring-blue-500 focus:border-blue-500 mt-2.5 font-normal shadow-card; | |
} | |
.btn { | |
@apply text-white bg-gradient-to-r from-[#00c6ff] to-[#0072ff] focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center; | |
} | |
.header { | |
@apply flex justify-between items-center sm:px-16 px-8 py-4 max-w-5xl mx-auto absolute top-0 bg-transparent z-10 right-0 left-0; | |
} | |
.footer { | |
@apply max-w-5xl mx-auto sm:px-16 pb-6 px-8 flex flex-col gap-7; | |
} | |
.footer-container { | |
@apply flex flex-wrap gap-7 items-center justify-between; | |
} | |
.info-box { | |
@apply mx-5 relative flex text-white flex-col gap-3 max-w-2xl neo-brutalism-blue pt-4 pb-12 px-8; | |
} | |
.neo-btn { | |
@apply py-3 px-6 rounded-lg text-blue-500 text-center font-semibold sm:w-1/2 w-[90%] -bottom-5 absolute mx-auto right-0 left-0 flex justify-center items-center gap-3; | |
} | |
.cta { | |
@apply w-full flex items-center md:flex-row flex-col sm:mt-16 mt-8 gap-7; | |
} | |
.cta-text { | |
@apply text-black-500 font-extrabold flex-1 text-3xl max-md:text-center; | |
} | |
} | |
.glassmorphism { | |
background: rgba(8, 116, 239, 0.07); | |
backdrop-filter: blur(10px); | |
-webkit-backdrop-filter: blur(10px); | |
border-radius: 10px; | |
border: 1px solid rgba(255, 255, 255, 0.18); | |
} | |
.logo { | |
border-radius: 8.889px; | |
background: #fff; | |
box-shadow: 0px 10px 35px -4px rgba(67, 83, 255, 0.15), | |
0px 1.5px 4px -1px rgba(67, 83, 255, 0.2); | |
} | |
.block-container { | |
position: relative; | |
transition: 250ms; | |
perspective: 500px; | |
} | |
.block-container .btn-back { | |
position: absolute; | |
inset: 0; | |
z-index: -1; | |
width: inherit; | |
height: inherit; | |
transition: 250ms; | |
transform-style: preserve-3d; | |
transform-origin: bottom right; | |
transform: rotateZ(15deg); | |
will-change: transform; | |
box-shadow: 16px 0 40px #e4e4e4; | |
} | |
.block-container .btn-back-red { | |
background: linear-gradient(135deg, #ff4b1f -20%, #ff9068 120%); | |
} | |
.block-container .btn-back-green { | |
background: linear-gradient(135deg, #adfda2 -20%, #11d3f3 120%); | |
} | |
.block-container .btn-back-yellow { | |
background: linear-gradient(135deg, #f7971e -20%, #ffd200 120%); | |
} | |
.block-container .btn-back-blue { | |
background: linear-gradient(135deg, #0061ff -20%, #60efff 120%); | |
} | |
.block-container .btn-back-orange { | |
background: linear-gradient(135deg, #ff0f7b -20%, #f89b29 120%); | |
} | |
.block-container .btn-back-pink { | |
background: linear-gradient(135deg, #e81cff -20%, #40c9ff 120%); | |
} | |
.block-container .btn-back-black { | |
background: linear-gradient(135deg, #0a1647 -20%, #e4e7e4 120%); | |
} | |
.block-container .btn-front { | |
position: absolute; | |
inset: 0; | |
z-index: 1; | |
width: inherit; | |
height: inherit; | |
background-color: #ffffff33; | |
-webkit-backdrop-filter: blur(20px); | |
backdrop-filter: blur(20px); | |
transition: 250ms; | |
transform-style: preserve-3d; | |
transform-origin: top left; | |
overflow: hidden; | |
} | |
.block-container:hover > .btn-back { | |
transform: translateZ(20px) rotateZ(15deg) rotateX(-20deg) rotateY(-20deg); | |
} | |
.block-container:hover > .btn-front { | |
transform: translateZ(80px) translateY(-5px) rotateX(15deg) rotateY(15deg); | |
} | |
/* Neo Brutalism */ | |
.neo-brutalism-blue { | |
background: #2b77e7; | |
position: relative; | |
border-radius: 10px; | |
border: #2b77e7; | |
box-shadow: 0.6vmin 0.6vmin #336cc1, 1vmin 1vmin #0092db, 1vmin 1vmin #0092db, | |
0.65vmin 1vmin #0092db, 1vmin 0.65vmin #0092db; | |
} | |
.neo-brutalism-white { | |
background: #fff; | |
border: #fff; | |
box-shadow: 0.6vmin 0.6vmin #fff, 1vmin 1vmin #d2e4ff, 1vmin 1vmin #d2e4ff, | |
0.65vmin 1vmin #d2e4ff, 1vmin 0.65vmin #d2e4ff; | |
} |
import { meta, shopify, starbucks, tesla } from "../assets/images"; | |
import { | |
car, | |
contact, | |
css, | |
estate, | |
express, | |
git, | |
github, | |
html, | |
javascript, | |
linkedin, | |
mongodb, | |
motion, | |
mui, | |
nextjs, | |
nodejs, | |
pricewise, | |
react, | |
redux, | |
sass, | |
snapgram, | |
summiz, | |
tailwindcss, | |
threads, | |
typescript | |
} from "../assets/icons"; | |
export const skills = [ | |
{ | |
imageUrl: css, | |
name: "CSS", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: express, | |
name: "Express", | |
type: "Backend", | |
}, | |
{ | |
imageUrl: git, | |
name: "Git", | |
type: "Version Control", | |
}, | |
{ | |
imageUrl: github, | |
name: "GitHub", | |
type: "Version Control", | |
}, | |
{ | |
imageUrl: html, | |
name: "HTML", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: javascript, | |
name: "JavaScript", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: mongodb, | |
name: "MongoDB", | |
type: "Database", | |
}, | |
{ | |
imageUrl: motion, | |
name: "Motion", | |
type: "Animation", | |
}, | |
{ | |
imageUrl: mui, | |
name: "Material-UI", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: nextjs, | |
name: "Next.js", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: nodejs, | |
name: "Node.js", | |
type: "Backend", | |
}, | |
{ | |
imageUrl: react, | |
name: "React", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: redux, | |
name: "Redux", | |
type: "State Management", | |
}, | |
{ | |
imageUrl: sass, | |
name: "Sass", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: tailwindcss, | |
name: "Tailwind CSS", | |
type: "Frontend", | |
}, | |
{ | |
imageUrl: typescript, | |
name: "TypeScript", | |
type: "Frontend", | |
} | |
]; | |
export const experiences = [ | |
{ | |
title: "React.js Developer", | |
company_name: "Starbucks", | |
icon: starbucks, | |
iconBg: "#accbe1", | |
date: "March 2020 - April 2021", | |
points: [ | |
"Developing and maintaining web applications using React.js and other related technologies.", | |
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.", | |
"Implementing responsive design and ensuring cross-browser compatibility.", | |
"Participating in code reviews and providing constructive feedback to other developers.", | |
], | |
}, | |
{ | |
title: "React Native Developer", | |
company_name: "Tesla", | |
icon: tesla, | |
iconBg: "#fbc3bc", | |
date: "Jan 2021 - Feb 2022", | |
points: [ | |
"Developing and maintaining web applications using React.js and other related technologies.", | |
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.", | |
"Implementing responsive design and ensuring cross-browser compatibility.", | |
"Participating in code reviews and providing constructive feedback to other developers.", | |
], | |
}, | |
{ | |
title: "Web Developer", | |
company_name: "Shopify", | |
icon: shopify, | |
iconBg: "#b7e4c7", | |
date: "Jan 2022 - Jan 2023", | |
points: [ | |
"Developing and maintaining web applications using React.js and other related technologies.", | |
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.", | |
"Implementing responsive design and ensuring cross-browser compatibility.", | |
"Participating in code reviews and providing constructive feedback to other developers.", | |
], | |
}, | |
{ | |
title: "Full stack Developer", | |
company_name: "Meta", | |
icon: meta, | |
iconBg: "#a2d2ff", | |
date: "Jan 2023 - Present", | |
points: [ | |
"Developing and maintaining web applications using React.js and other related technologies.", | |
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.", | |
"Implementing responsive design and ensuring cross-browser compatibility.", | |
"Participating in code reviews and providing constructive feedback to other developers.", | |
], | |
}, | |
]; | |
export const socialLinks = [ | |
{ | |
name: 'Contact', | |
iconUrl: contact, | |
link: '/contact', | |
}, | |
{ | |
name: 'GitHub', | |
iconUrl: github, | |
link: 'https://github.com/YourGitHubUsername', | |
}, | |
{ | |
name: 'LinkedIn', | |
iconUrl: linkedin, | |
link: 'https://www.linkedin.com/in/YourLinkedInUsername', | |
} | |
]; | |
export const projects = [ | |
{ | |
iconUrl: pricewise, | |
theme: 'btn-back-red', | |
name: 'Amazon Price Tracker', | |
description: 'Developed a web application that tracks and notifies users of price changes for products on Amazon, helping users find the best deals.', | |
link: 'https://github.com/adrianhajdin/pricewise', | |
}, | |
{ | |
iconUrl: threads, | |
theme: 'btn-back-green', | |
name: 'Full Stack Threads Clone', | |
description: 'Created a full-stack replica of the popular discussion platform "Threads," enabling users to post and engage in threaded conversations.', | |
link: 'https://github.com/adrianhajdin/threads', | |
}, | |
{ | |
iconUrl: car, | |
theme: 'btn-back-blue', | |
name: 'Car Finding App', | |
description: 'Designed and built a mobile app for finding and comparing cars on the market, streamlining the car-buying process.', | |
link: 'https://github.com/adrianhajdin/project_next13_car_showcase', | |
}, | |
{ | |
iconUrl: snapgram, | |
theme: 'btn-back-pink', | |
name: 'Full Stack Instagram Clone', | |
description: 'Built a complete clone of Instagram, allowing users to share photos and connect with friends in a familiar social media environment.', | |
link: 'https://github.com/adrianhajdin/social_media_app', | |
}, | |
{ | |
iconUrl: estate, | |
theme: 'btn-back-black', | |
name: 'Real-Estate Application', | |
description: 'Developed a web application for real estate listings, facilitating property searches and connecting buyers with sellers.', | |
link: 'https://github.com/adrianhajdin/projects_realestate', | |
}, | |
{ | |
iconUrl: summiz, | |
theme: 'btn-back-yellow', | |
name: 'AI Summarizer Application', | |
description: 'App that leverages AI to automatically generate concise & informative summaries from lengthy text content, or blogs.', | |
link: 'https://github.com/adrianhajdin/project_ai_summarizer', | |
} | |
]; |
const normalizedRotation = | |
((rotation % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI); | |
// Set the current stage based on the island's orientation | |
switch (true) { | |
case normalizedRotation >= 5.45 && normalizedRotation <= 5.85: | |
setCurrentStage(4); | |
break; | |
case normalizedRotation >= 0.85 && normalizedRotation <= 1.3: | |
setCurrentStage(3); | |
break; | |
case normalizedRotation >= 2.4 && normalizedRotation <= 2.6: | |
setCurrentStage(2); | |
break; | |
case normalizedRotation >= 4.25 && normalizedRotation <= 4.75: | |
setCurrentStage(1); | |
break; | |
default: | |
setCurrentStage(null); | |
} |
/** @type {import('tailwindcss').Config} */ | |
export default { | |
content: [ | |
"./index.html", | |
"./src/**/*.{js,ts,jsx,tsx}", | |
], | |
theme: { | |
extend: { | |
colors: { | |
gray: { | |
200: "#D5DAE1" | |
}, | |
black: { | |
DEFAULT: "#000", | |
500: "#1D2235" | |
}, | |
blue: { | |
500: "#2b77e7" | |
} | |
}, | |
fontFamily: { | |
worksans: ["Work Sans", "sans-serif"], | |
poppins: ['Poppins', "sans-serif"] | |
}, | |
boxShadow: { | |
card: '0px 1px 2px 0px rgba(0, 0, 0, 0.05)' | |
} | |
}, | |
}, | |
plugins: [], | |
} |
i want to that my human walk but it does not actions as object like hit run walk etc. what can i do to make my women walk
the app controls rotation with keys and drag, How can i add scroll to it?
Hello! Hope all is well. Rather than use an island, I decided to use a ship for my main center piece for my interactive resume website.
It was all going amazing until it was time to implement the ship rotating when being dragged.
Now whenever I load the website I have a white page, and the errors and my Ship.jsx can be found below:
`/* eslint-disable react/no-unknown-property */
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Author: Eric de Menezes (https://sketchfab.com/ericmvieira28)
License: SKETCHFAB Standard (https://sketchfab.com/licenses)
Source: https://sketchfab.com/3d-models/going-merry-one-piece-518566a3846c4b10ae45ea0794b46fe7
Title: Going Merry One Piece
*/
import { useRef, useEffect } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import {useFrame, useThree } from '@react-three/fiber';
import shipScene from '../assets/3d/going_merry_one_piece.glb';
import { a } from '@react-spring/three';
const Ship = ({isRotating, setIsRotating, ...props}) => {
const {gl , viewport} = useThree();
const shipRef = useRef();
const group = useRef();
const { nodes, materials, animations } = useGLTF(shipScene);
const { actions } = useAnimations(animations, group);
const lastX = useRef(0);
const rotationSpeed = useRef(0);
const dampingFactor = 0.95;
const handlePointerDown = (e) => {
e.stopPropagation();
e.preventDefault();
setIsRotating(true);
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
lastX.current = clientX;
}
const handlePointerUp = (e) => {
e.stopPropagation();
e.preventDefault();
setIsRotating(false);
}
const handlePointerMove = (e) => {
e.stopPropagation();
e.preventDefault();
if(isRotating){
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const delta = (clientX - lastX.current) / viewport.width;
shipRef.current.rotation.y += delta * 0.01 * Math.PI;
lastX.current = clientX;
rotationSpeed.current = delta * 0.01 * Math.PI;
}
}
const handleKeyDown = (e) => {
if(e.key === 'ArrowLeft') {
if(!isRotating) setIsRotating(true);
shipRef.current.rotation.y += 0.01 * Math.PI;
} else if (e.key === 'ArrowRight') {
if(!isRotating) setIsRotating(true);
shipRef.current.rotation.y -= 0.01 * Math.PI;
}
}
const handleKeyUp = (e) => {
if(e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
setIsRotating(false);
}
}
useEffect(() => {
const canvas = gl.domElement;
canvas.addEventListener('pointerdown', handlePointerDown);
canvas.addEventListener('pointerup', handlePointerUp);
canvas.addEventListener('pointermove', handlePointerMove);
document.addEventListener('keydown', handleKeyDown)
document.addEventListener('keyup', handleKeyUp)
return () => {
canvas.removeEventListener('pointerdown', handlePointerDown);
canvas.removeEventListener('pointerup', handlePointerUp);
canvas.removeEventListener('pointermove', handlePointerMove);
document.removeEventListener('keydown', handleKeyDown)
document.removeEventListener('keyup', handleKeyUp)
}
}, [gl, handlePointerDown, handlePointerUp, handlePointerMove]);
useFrame(() => {
if(!isRotating) {
rotationSpeed.current = { ...rotationSpeed.current, y: rotationSpeed.current.y * dampingFactor };
if(Math.abs(rotationSpeed.current) < 0.001){
rotationSpeed.current = { ...rotationSpeed.current, y: 0 };
const currentRotation = rotation.y;
}
} else {
const {rotation} = shipRef.current;
}
})
const normalizedRotation =
((rotation % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);
// Set the current stage based on the island's orientation
switch (true) {
case normalizedRotation >= 5.45 && normalizedRotation <= 5.85:
setCurrentStage(4);
break;
case normalizedRotation >= 0.85 && normalizedRotation <= 1.3:
setCurrentStage(3);
break;
case normalizedRotation >= 2.4 && normalizedRotation <= 2.6:
setCurrentStage(2);
break;
case normalizedRotation >= 4.25 && normalizedRotation <= 4.75:
setCurrentStage(1);
break;
default:
setCurrentStage(null);
}
return (
<a.group ref={shipRef} {...props} dispose={null}>
<group name="Sketchfab_Scene">
<group name="Sketchfab_model" rotation={[-Math.PI / 2, 0, 0]}>
<group name="root">
<group name="GLTF_SceneRootNode" rotation={[Math.PI / 2, 0, 0]}>
<group name="Empty_0" position={[133.633, 3.843, 8.289]} />
<group
name="CameraShakifyv2_Camera_0_4"
position={[-12308.8, -11100.4, -3524]}
/>
<group name="GoingMerry_5">
<mesh
name="Object_6"
geometry={nodes.Object_6.geometry}
material={materials.UV_04}
/>
<mesh
name="Object_7"
geometry={nodes.Object_7.geometry}
material={materials.UV_04}
/>
<mesh
name="Object_8"
geometry={nodes.Object_8.geometry}
material={materials.UV_03}
/>
<mesh
name="Object_9"
geometry={nodes.Object_9.geometry}
material={materials.UV_01}
/>
<mesh
name="Object_10"
geometry={nodes.Object_10.geometry}
material={materials.UV_02}
/>
</group>
<group
name="Trees_8"
position={[2.576, 4.768, 0.02]}
rotation={[0.004, 0, 0.028]}
scale={1.127}
>
<mesh
name="Object_12"
geometry={nodes.Object_12.geometry}
material={materials["Material.003"]}
/>
<mesh
name="Object_13"
geometry={nodes.Object_13.geometry}
material={materials["Material.004"]}
/>
<mesh
name="Object_14"
geometry={nodes.Object_14.geometry}
material={materials["Material.004"]}
/>
<mesh
name="Object_15"
geometry={nodes.Object_15.geometry}
material={materials["Material.004"]}
/>
<mesh
name="Object_16"
geometry={nodes.Object_16.geometry}
material={materials["Material.004"]}
/>
<mesh
name="Object_17"
geometry={nodes.Object_17.geometry}
material={materials["Material.004"]}
/>
</group>
</group>
</group>
</group>
</group>
</a.group>
);
}
export default Ship;
`
@Yashpatole81 Hi! For me your problem seems to be located in Island.jsx on line 25. Check it or show as the Island.jsx.
Thanks a lot for your tutorial, it's a cool project.
Here is my finished version, had a little bit of modification.
https://jishen027.github.io/3d_portfolio/
Island.jsx:23 Uncaught TypeError: Cannot read properties of undefined (reading 'geometry')
Hello! Hope all is well. Rather than use an island, I decided to use a ship for my main center piece for my interactive resume website.
It was all going amazing until it was time to implement the ship rotating when being dragged.
Now whenever I load the website I have a white page, and the errors and my Ship.jsx can be found below:
````/* eslint-disable react/no-unknown-property /
/
Auto-generated by: https://github.com/pmndrs/gltfjsx
Author: Eric de Menezes (https://sketchfab.com/ericmvieira28)
License: SKETCHFAB Standard (https://sketchfab.com/licenses)
Source: https://sketchfab.com/3d-models/going-merry-one-piece-518566a3846c4b10ae45ea0794b46fe7
Title: Going Merry One Piece
*/import { useRef, useEffect } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import {useFrame, useThree } from '@react-three/fiber';
import shipScene from '../assets/3d/going_merry_one_piece.glb';
import { a } from '@react-spring/three';const Ship = ({isRotating, setIsRotating, ...props}) => {
const {gl , viewport} = useThree();
const shipRef = useRef();
const group = useRef();
const { nodes, materials, animations } = useGLTF(shipScene);
const { actions } = useAnimations(animations, group);
const lastX = useRef(0);
const rotationSpeed = useRef(0);
const dampingFactor = 0.95;const handlePointerDown = (e) => {
e.stopPropagation();
e.preventDefault();
setIsRotating(true);const clientX = e.touches ? e.touches[0].clientX : e.clientX; lastX.current = clientX;
}
const handlePointerUp = (e) => {
e.stopPropagation();
e.preventDefault();
setIsRotating(false);
}
const handlePointerMove = (e) => {
e.stopPropagation();
e.preventDefault();
if(isRotating){
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const delta = (clientX - lastX.current) / viewport.width;
shipRef.current.rotation.y += delta * 0.01 * Math.PI;
lastX.current = clientX;
rotationSpeed.current = delta * 0.01 * Math.PI;
}}
const handleKeyDown = (e) => {
if(e.key === 'ArrowLeft') {
if(!isRotating) setIsRotating(true);
shipRef.current.rotation.y += 0.01 * Math.PI;
} else if (e.key === 'ArrowRight') {
if(!isRotating) setIsRotating(true);
shipRef.current.rotation.y -= 0.01 * Math.PI;}
}
const handleKeyUp = (e) => {
if(e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
setIsRotating(false);
}
}
useEffect(() => {
const canvas = gl.domElement;
canvas.addEventListener('pointerdown', handlePointerDown);
canvas.addEventListener('pointerup', handlePointerUp);
canvas.addEventListener('pointermove', handlePointerMove);
document.addEventListener('keydown', handleKeyDown)
document.addEventListener('keyup', handleKeyUp)return () => { canvas.removeEventListener('pointerdown', handlePointerDown); canvas.removeEventListener('pointerup', handlePointerUp); canvas.removeEventListener('pointermove', handlePointerMove); document.removeEventListener('keydown', handleKeyDown) document.removeEventListener('keyup', handleKeyUp) }
}, [gl, handlePointerDown, handlePointerUp, handlePointerMove]);
useFrame(() => {
if(!isRotating) {
rotationSpeed.current = { ...rotationSpeed.current, y: rotationSpeed.current.y * dampingFactor };
if(Math.abs(rotationSpeed.current) < 0.001){
rotationSpeed.current = { ...rotationSpeed.current, y: 0 };
const currentRotation = rotation.y;
}
} else {
const {rotation} = shipRef.current;
}
})
const normalizedRotation =
((rotation % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);// Set the current stage based on the island's orientation
switch (true) {
case normalizedRotation >= 5.45 && normalizedRotation <= 5.85:
setCurrentStage(4);
break;
case normalizedRotation >= 0.85 && normalizedRotation <= 1.3:
setCurrentStage(3);
break;
case normalizedRotation >= 2.4 && normalizedRotation <= 2.6:
setCurrentStage(2);
break;
case normalizedRotation >= 4.25 && normalizedRotation <= 4.75:
setCurrentStage(1);
break;
default:
setCurrentStage(null);
}return (
<a.group ref={shipRef} {...props} dispose={null}> <group name="Sketchfab_Scene"> <group name="Sketchfab_model" rotation={[-Math.PI / 2, 0, 0]}> <group name="root"> <group name="GLTF_SceneRootNode" rotation={[Math.PI / 2, 0, 0]}> <group name="Empty_0" position={[133.633, 3.843, 8.289]} /> <group name="CameraShakifyv2_Camera_0_4" position={[-12308.8, -11100.4, -3524]} /> <group name="GoingMerry_5"> <mesh name="Object_6" geometry={nodes.Object_6.geometry} material={materials.UV_04} /> <mesh name="Object_7" geometry={nodes.Object_7.geometry} material={materials.UV_04} /> <mesh name="Object_8" geometry={nodes.Object_8.geometry} material={materials.UV_03} /> <mesh name="Object_9" geometry={nodes.Object_9.geometry} material={materials.UV_01} /> <mesh name="Object_10" geometry={nodes.Object_10.geometry} material={materials.UV_02} /> </group> <group name="Trees_8" position={[2.576, 4.768, 0.02]} rotation={[0.004, 0, 0.028]} scale={1.127} > <mesh name="Object_12" geometry={nodes.Object_12.geometry} material={materials["Material.003"]} /> <mesh name="Object_13" geometry={nodes.Object_13.geometry} material={materials["Material.004"]} /> <mesh name="Object_14" geometry={nodes.Object_14.geometry} material={materials["Material.004"]} /> <mesh name="Object_15" geometry={nodes.Object_15.geometry} material={materials["Material.004"]} /> <mesh name="Object_16" geometry={nodes.Object_16.geometry} material={materials["Material.004"]} /> <mesh name="Object_17" geometry={nodes.Object_17.geometry} material={materials["Material.004"]} /> </group> </group> </group> </group> </group> </a.group>
);
}
export default Ship;
`
I have also got this error.Have u solved this error then please help me to solve this.
Thanks a lot for your tutorial, it's a cool project. Here is my finished version, had a little bit of modification. https://jishen027.github.io/3d_portfolio/
Heyy Jishen, I was having trouble in deploying this project on github . Can you please give me the steps to deploy this 3d portfolio? I have deployed it on github but not loading 3d island. I am giving my deployed link too. Please check it and help me. Thanks in advance.
https://sainathgaikwad.github.io/Sainath-Gaikwad-Portfolio/
HI i am getting issues in HomeInfo.jsx . As in the video when you rotate the island you get different stages but when I followed the same I am just getting the 1st stage that is introduction and not the other stages. Also when i inspect I get this error "chunk-25Y2DYCY.js?v=91d39a21:16442 Text is not allowed in the R3F tree! This could be stray whitespace or characters."
Do let me know what is the issue.
import React from "react"
import { Link } from "react-router-dom";
import { arrow } from "../assets/icons";
const InfoBox = ({ text, link, btnText }) => (
);const renderContent = {
1: (
Hi, I am Arpit👋
A Software Engineer from India
),
2: (
),
3: (
),
4: (
),
};
const HomeInfo = ({ currentStage }) => {
return renderContent[currentStage] || null;
}
export default HomeInfo;
import { useState, Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import Island from "../models/Island";
import Loader from "../components/Loader";
import Sky from "../models/Sky";
import Bird from "../models/Bird";
import Plane from "../models/Plane";
import HomeInfo from "../components/HomeInfo";
const Home = () => {
const [isRotating, setIsRotating] = useState(false);
const [currentStage, setcurrentStage] = useState(1);
const adjustIslandForScreenSize = () => {
let screenScale = null;
let screenPosition = [0, -6.5, -43];
let rotation = [0.1, 4.7, 0];
if (window.innerWidth < 768) {
screenScale = [0.9, 0.9, 0.9];
} else {
screenScale = [1, 1, 1];
}
return [screenScale, screenPosition, rotation];
};
const adjustPlaneForScreenSize = () => {
let screenScale, screenPosition;
if (window.innerWidth < 768) {
screenScale = [1.5, 1.5, 1.5];
screenPosition = [0, -1.5, 0];
} else {
screenScale = [3, 3, 3];
screenPosition = [0, -4, -4];
}
return [screenScale, screenPosition];
};
const [islandScale, islandPosition, islandRotation] =
adjustIslandForScreenSize();
const [planeScale, planePosition] = adjustPlaneForScreenSize();
return (
{currentStage && }
<Canvas
className={`w-full h-screen bg-transparent ${
isRotating ? "cursor-grabbing" : "cursor-grab"
}`}
camera={{ near: 0.1, far: 1000 }}
>
<Suspense fallback={<Loader />}>
<directionalLight position={[1, 1, 1]} intensity={2} />
<ambientLight intensity={0.5} />
<hemisphereLight
skyColor="#b1e1ff"
groundColor="#000000"
intensity={1}
/>
<Bird />
<Sky isRotating={isRotating} />
<Island
position={islandPosition}
scale={islandScale}
rotation={islandRotation}
isRotating={isRotating}
setIsRotating={setIsRotating}
setcurrentStage={setcurrentStage}
/>
<Plane
isRotating={isRotating}
planePosition={planePosition}
planeScale={planeScale}
rotation={[0, 20, 0]}
/>
</Suspense>
</Canvas>
</section>
);
};
export default Home;
please can you help me the arrow does not appear and when i scroll on the screen, it is not appear the about , contectand projects page
import React from "react";
import { Link } from "react-router-dom";
import { arrow } from "../assets/icons";
// Functional component InfoBox to display information with a link and button
const InfoBox = ({ text, link, btnText }) => (
{/* Create a link with specified destination and button text */} {btnText} {/* Display an arrow image when hovered over */}
// Object containing different content to render based on currentStage
const renderContent = {
1: (
Hi, I am Muaz 👋
A Software Engineer from Eibtikar Tech
),
2: (
),
3: (
),
4: (
),
};
// Functional component HomeInfo to render content based on currentStage
const HomeInfo = ({ currentStage }) => {
return renderContent[currentStage] || null;
};
export default HomeInfo;
Hello I am getting this error when I click on the 3D object to move it. As soon as I click and drag on the webpage it pops the error message of:
There is an error regarding a TypeError: Cannot read properties of undefined (reading 'rotation').
The specific lines of code that are not working are using the "current.rotation.y".
Any Help Would be Greatly Appreciated!!
Thank you
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Author: nimzu (https://sketchfab.com/nimzuk)
License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
Source: https://sketchfab.com/3d-models/foxs-islands-163b68e09fcc47618450150be7785907
Title: Fox's islands
*/
import {a} from '@react-spring/three';
import React, { useRef, useEffect } from 'react';
import { useGLTF } from '@react-three/drei';
import { useFrame, useThree } from '@react-three/fiber';
import islandScene from '../assets/3d/island.glb';
const Island = (props) => {
const isLandRef = useRef();
const { nodes, materials } = useGLTF(islandScene)
return (
<a.group ref={isLandRef}{...props} >
</a.group>
)
}
export default Island;
my 3d models not showing
Thank you @ng9000 for this. You are a real one