Skip to content

Instantly share code, notes, and snippets.

@adrianhajdin
Forked from TidbitsJS/index.css
Last active April 30, 2024 04:20
Show Gist options
  • Star 51 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save adrianhajdin/7bc0603ee0b1bd2872b80a62c24b5e5f to your computer and use it in GitHub Desktop.
Save adrianhajdin/7bc0603ee0b1bd2872b80a62c24b5e5f to your computer and use it in GitHub Desktop.
3D Portfolio Gists
@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: [],
}
@ng9000
Copy link

ng9000 commented Nov 23, 2023

Does anyone know how to solve mobile scrolling issue where it freezes after trying to scroll?
(edit) I found the solution you have to add touch event listener to make it scroll nicely

useEffect(() => {
  // Add event listeners for pointer, keyboard and touch events
  const canvas = gl.domElement;
  canvas.addEventListener("pointerdown", handlePointerDown);
  canvas.addEventListener("pointerup", handlePointerUp);
  canvas.addEventListener("pointermove", handlePointerMove);
  canvas.addEventListener("touchstart", handlePointerDown);
  canvas.addEventListener("touchmove", handlePointerMove);
  canvas.addEventListener("touchend", handlePointerUp);
  window.addEventListener("keydown", handleKeyDown);
  window.addEventListener("keyup", handleKeyUp);

  // Remove event listeners
  return () => {
    canvas.removeEventListener("pointerdown", handlePointerDown);
    canvas.removeEventListener("pointerup", handlePointerUp);
    canvas.removeEventListener("pointermove", handlePointerMove);
    canvas.removeEventListener("touchstart", handlePointerDown);
    canvas.removeEventListener("touchmove", handlePointerMove);
    canvas.removeEventListener("touchend", handlePointerUp);
    window.removeEventListener("keydown", handleKeyDown);
    window.removeEventListener("keyup", handleKeyUp);
  };
}, [gl, handlePointerDown, handlePointerUp, handlePointerMove]);
portfolio_123.mp4

@Arshnoor19
Copy link

Arshnoor19 commented Nov 25, 2023

hey @ng9000 !

maybe something in the handlePointerMove is wrong

check the math again .... I guess that will fix the problem
also, check the dampingFactor, which is also really sensitive to a float value

@alexzborovskii
Copy link

thank you, @ng9000!

@BenjaminAdimachukwu
Copy link

BenjaminAdimachukwu commented Dec 14, 2023

I got stuck trying to debug this error. please who has any idea of how this can be resolved?

Screenshot 2023-12-14 at 2 12 09 PM

@alexzborovskii
Copy link

alexzborovskii commented Dec 14, 2023

@BenjaminAdimachukwu have you added something to the original code? I don't get this error, looks like you added something in Sky.jsx model, that crashed everithing. Can you show your sky code?
(btw its not tho best place for this kind of questions)

@BenjaminAdimachukwu
Copy link

@alexzborovskii yeah. thanks, bro. there was an error in the Sky.jsx code. it has been corrected now, and the app works fine. Thank you

@Archies13Singh
Copy link

Archies13Singh commented Dec 22, 2023

hey @Arshnoor19

Screenshot 2023-12-22 at 6 00 48 PM

whenver I am using useAnimations in Project i am getting error . Please refere above screenshots

@Arshnoor19
Copy link

Arshnoor19 commented Dec 22, 2023 via email

@Archies13Singh
Copy link

Thank you @Arshnoor19 , Now its working great

@Ajay-308
Copy link

hello i want to move my dragon as he used Take 001 to fly dragon i want to Walk my dragon what should i do
image

@DLParkin
Copy link

DLParkin commented Dec 22, 2023

hello i want to move my dragon as he used Take 001 to fly dragon i want to Walk my dragon what should i do image

Could log the actions and see what is available

If you work out the walk you can use something like this to make it walk with some minor modifications to the x, y, z

` useEffect(() => {
actions["Take 01"].play();
return () => {
actions["Take 01"].stop();
};
}, [actions]);

useFrame(({ clock }) => {
const time = clock.getElapsedTime() / 2;
// Define the flight path here, for example a circular path
const x = Math.sin(time) * 3;
const y = Math.cos(time) * 1;
const z = Math.sin(time) * Math.cos(time);

// Update position
ref.current.position.set(x, y, z);

// Update rotation to face the direction of movement
// Assuming the butterfly faces along the positive Y-axis by default
ref.current.rotation.y = Math.atan2(x, y);

// Add some scale changes for more natural movement
ref.current.scale.set(
  1 + Math.sin(time) * 0.1,
  1 + Math.cos(time) * 0.1,
  1
);

});`

@Ajay-308
Copy link

Thankyou @DLParkin but its not working what is Take 01 , Take 001 and from where its coming?

@VansRouges
Copy link

VansRouges commented Dec 30, 2023

Does anyone know how to solve mobile scrolling issue where it freezes after trying to scroll? (edit) I found the solution you have to add touch event listener to make it scroll nicely

useEffect(() => {
  // Add event listeners for pointer, keyboard and touch events
  const canvas = gl.domElement;
  canvas.addEventListener("pointerdown", handlePointerDown);
  canvas.addEventListener("pointerup", handlePointerUp);
  canvas.addEventListener("pointermove", handlePointerMove);
  canvas.addEventListener("touchstart", handlePointerDown);
  canvas.addEventListener("touchmove", handlePointerMove);
  canvas.addEventListener("touchend", handlePointerUp);
  window.addEventListener("keydown", handleKeyDown);
  window.addEventListener("keyup", handleKeyUp);

  // Remove event listeners
  return () => {
    canvas.removeEventListener("pointerdown", handlePointerDown);
    canvas.removeEventListener("pointerup", handlePointerUp);
    canvas.removeEventListener("pointermove", handlePointerMove);
    canvas.removeEventListener("touchstart", handlePointerDown);
    canvas.removeEventListener("touchmove", handlePointerMove);
    canvas.removeEventListener("touchend", handlePointerUp);
    window.removeEventListener("keydown", handleKeyDown);
    window.removeEventListener("keyup", handleKeyUp);
  };
}, [gl, handlePointerDown, handlePointerUp, handlePointerMove]);

portfolio_123.mp4

Thank you @ng9000 for this. You are a real one

@ishika3838
Copy link

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

@aivarkamchybek
Copy link

image
I stuck here, could you please help me to solve it?

@VansRouges
Copy link

image I stuck here, could you please help me to solve it?

You may need to check if a component you imported into the <Canvas></Canvas> component is using a div immediately after it's return key word to wrap its components. if it is, change it to a mesh component. Take for instance:
image
I hope this helps :)

@shubhankarsapa
Copy link

the app controls rotation with keys and drag, How can i add scroll to it?

@hkurdi
Copy link

hkurdi commented Jan 7, 2024

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:

Error Rotation

`/* 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
Copy link

Screenshot 2024-01-15 011444

I'm stuck at this point and it didn't showing any thing expect white background but if i check it in inspect tool i can find the image but it didn't rendering or something else please help me out this.

@alexzborovskii
Copy link

@Yashpatole81 Hi! For me your problem seems to be located in Island.jsx on line 25. Check it or show as the Island.jsx.

@YSoSeriousMax
Copy link

Error 1
Hey guys would anyone be able to figure out why my canvas isn't rendering at all?? all canvas's are not rendering. I suspect this has to be due to my home.jsx file but I have tried everything and nothing works.

@YSoSeriousMax
Copy link

Error 1 Hey guys would anyone be able to figure out why my canvas isn't rendering at all?? all canvas's are not rendering. I suspect this has to be due to my home.jsx file but I have tried everything and nothing works.

Code1
Code2

@jishen027
Copy link

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/
image

@PraneethRahee
Copy link

Island.jsx:23 Uncaught TypeError: Cannot read properties of undefined (reading 'geometry')

@SainathGaikwad
Copy link

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:

Error Rotation ```

`/* 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.

@SainathGaikwad
Copy link

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/ image

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/

@itsmeArpit07
Copy link

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 }) => (

{text}

{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;

@shreya05dixit
Copy link

shreya05dixit commented Apr 10, 2024

Screenshot (168)
Screenshot (170)
Screenshot (171)
Screenshot (173)
Screenshot (174)
I'm stuck at the rotating island step. It says problem with hooking island with canvas but the code seems right to me as it is same as provided in tutorial. Reinstalling the dependencies isn't helping either. Please help me out with this.

@muaz21
Copy link

muaz21 commented Apr 19, 2024

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

Screenshot 2024-04-19 162101

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 }) => (

{/* Display the provided text */}

{/* Create a link with specified destination and button text */} {btnText} {/* Display an arrow image when hovered over */} Arrow

);

// 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;

@Christian-Pantoja
Copy link

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:

error

There is an error regarding a TypeError: Cannot read properties of undefined (reading 'rotation').

err

The specific lines of code that are not working are using the "current.rotation.y".

Any Help Would be Greatly Appreciated!!
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment