Three.js:如何在IcosahedronGeometry球体表面正确渲染2D图标?
问题描述
跟着YouTube的代码教程开发基于Three.js和TailwindCSS的项目(无TypeScript),已成功渲染13个IcosahedronGeometry球体,但球体上的2D图标无法显示,控制台无报错。作为Three.js新手,折腾一周无果,需求是让图标像高尔夫球logo一样显示在球体侧面。此前修改Ball.jsx仅能让图标拉伸覆盖球体,还触发ESLint的"no-undefined"问题,效果不佳。
核心代码文件
Tech.jsx
import { BallCanvas } from './canvas' import { SectionWrapper } from '../hoc' import { technologies } from '../constants/index' const TechComponent = () => { return ( <div className='flex flex-row flex-wrap justify-center gap-10'> {technologies.map((technology) => ( <div className='w-28 h-28' key={technology.name}> <BallCanvas icon={technology.icon} /> </div> ))} </div> ) } const Tech = SectionWrapper(TechComponent, "about"); export default Tech;
Balls.jsx
import { Suspense } from 'react' import { Canvas } from '@react-three/fiber' import { Decal, Float, OrbitControls, Preload, useTexture } from '@react-three/drei' import CanvasLoader from '../Loader' import PropTypes from 'prop-types'; const Ball = (props) => { const [decal] = useTexture([props.imgURL]) return ( <Float speed={1.75} rotationIntensity={1} floatIntensity={2}> <ambientLight intensity={0.25}/> {/* eslint-disable-next-line react/no-unknown-property */} <directionalLight position={[0, 0, 0.05]} /> {/* eslint-disable-next-line react/no-unknown-property */} <mesh castShadow receiveShadow> {/* eslint-disable-next-line react/no-unknown-property */} <icosahedronGeometry attach="geometry" args={[4, 3]} /> {/* eslint-disable-next-line react/no-unknown-property */} <meshStandardMaterial color="#fff8eb" polygonOffset polygonOffsetFactor={-5} flatShading /> <Decal position={[0, 0, 1]} map={decal}/> {/*decal not loading*/} </mesh> </Float> ) } const BallCanvas = ({ icon }) => { return ( <Canvas frameloop="demand" shadows camera={{ position: [20, 3, 5], fov:25}} gl={{ preserveDrawingBuffer: true}} > <Suspense fallback={<CanvasLoader />}> <OrbitControls enableZoom={false} /> <Ball imgURL={icon}/> </Suspense> <Preload all /> </Canvas> ) } Ball.propTypes = { imgURL: PropTypes.string.isRequired, }; BallCanvas.propTypes = { icon: PropTypes.string.isRequired, }; export default BallCanvas;
constants/index.js 片段
import { mobile, backend, creator, web, javascript, typescript, html, css, reactjs, redux, tailwind, nodejs, mongodb, git, figma, docker, meta, starbucks, tesla, shopify, carrent, jobit, tripguide, threejs, } from "../assets"; const technologies = [ { name: "HTML 5", icon: html, }, { name: "CSS 3", icon: css, }, { name: "JavaScript", icon: javascript, }, { name: "TypeScript", icon: typescript, }, { name: "React JS", icon: reactjs, }, { name: "Redux Toolkit", icon: redux, }, { name: "Tailwind CSS", icon: tailwind, }, { name: "Node JS", icon: nodejs, }, { name: "MongoDB", icon: mongodb, }, { name: "Three JS", icon: threejs, }, { name: "git", icon: git, }, { name: "figma", icon: figma, }, { name: "docker", icon: docker, }, ];
package.json
{ "name": "portfolio-rob-2023", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { "@emailjs/browser": "^3.11.0", "@react-three/drei": "^9.66.6", "@react-three/fiber": "^8.13.0", "@types/three": "^0.152.0", "framer-motion": "^10.12.8", "maath": "^0.5.3", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-parallax-tilt": "^1.7.140", "react-router-dom": "^6.11.1", "react-tilt": "^1.0.2", "react-vertical-timeline-component": "^3.6.0", "three": "^0.152.2" }, "devDependencies": { "@types/node": "^20.1.1", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^4.0.0", "autoprefixer": "^10.4.14", "eslint": "^8.38.0", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.3.4", "postcss": "^8.4.23", "tailwindcss": "^3.3.2", "vite": "^4.3.2" } }
tailwind.config.js
/** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./src/**/*.{js,jsx}" ], mode: "jit", theme: { extend: { colors: { primary: "#050816", secondary: "#aaa6c3", tertiary: "#151030", "black-100": "#100d25", "black-200": "#090325", "white-100": "#f3f3f3", }, boxShadow: { card: "0px 35px 120px -15px #211e35", }, screens: { xs: "450px", }, backgroundImage: { "hero-pattern": "url('/src/assets/herobg.png')", }, }, }, plugins: [], };
内容的提问来源于stack exchange,提问作者Rabbie Wordie
相关产品推荐
相关产品推荐

