前端开发
需要把 SVG 或文字做成可交互 React 3D 组件时…
在 React 项目中用 3dsvg 把 SVG 或文字挤出为可交互 3D 组件,并通过属性或可视化编辑器配置材质、动画、灯光和导出。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
需要把 SVG 或文字做成可交互 Rea特定
解决思路
- 安装 3dsvg:运行 `npm install 3dsvg`,或 `yarn add 3dsvg`,或 `pnpm add 3dsvg`。
- 安装 peer dependencies(若尚未安装):运行 `npm install three @react-three/fiber @react-three/drei`。
- 在 React 组件中导入:`import { SVG3D } from '3dsvg';`。
- 快速创建 3D 旋转文字:`<SVG3D text='Hello' animate='spin' />`。
- 从 SVG 文件创建 3D logo:`<SVG3D svg='/logo.svg' material='gold' />`。
- 传入原始 SVG 字符串(如像素编辑器输入):`<SVG3D svg='<svg>...</svg>' material='chrome' animate='float' />`。
- 输入选择一项:使用 `text='Hello World'` 传文本字符串(使用 Google Fonts)。
- 输入选择一项:使用 `svg='/path/to/file.svg'` 传 SVG 文件 URL。
- 输入选择一项:使用 `svg='<svg>...</svg>'` 传原始 SVG markup 字符串。
- 使用 `text=` 时设置 `font='Inter'`,从 10 个 Google Font 预设中选择字体。
- 设置 `material` 材质预设:可选 `'default'`、`'plastic'`、`'metal'`、`'glass'`、`'rubber'`、`'chrome'`、`'gold'`、`'clay'`、`'emissive'`、`'holographic'`。
- 设置 `animate` 动画预设:可选 `'spin'`、`'float'`、`'pulse'`、`'wobble'`、`'swing'`、`'spin+float'`、`undefined`(静态)。
- 设置 `depth={0.2}` 控制挤出深度(默认 `0.2`)。
- 设置 `bevelEnabled={true}` 启用边缘倒角。
- 设置 `bevelThickness={0.02}` 控制倒角厚度。
- 设置 `bevelSize={0.02}` 控制倒角大小。
- 设置 `bevelSegments={3}` 控制倒角平滑度。
- 设置 `ambientIntensity={0.5}` 控制环境光强度(0–1)。
- 设置 `keyLightIntensity={1.0}` 控制主光亮度。
- 设置 `keyLightX={5}`、`keyLightY={5}`、`keyLightZ={5}` 控制主光位置。
- 设置 `shadows={true}` 启用阴影投射。
- 设置 `zoom={1}` 设置初始缩放级别。
- 设置 `autoRotate={false}` 自动旋转相机(会覆盖 `animate`)。
- 设置 `texture='none'`,或程序化预设名,或 URL。
- 基础 Logo Viewer:用 `div` 包裹并设置 `width: 400, height: 400`,再传 `svg='/logo.svg'`、`material='metal'`、`animate='float'`、`depth={0.3}`、`bevelEnabled={true}`、`bevelThickness={0.03}`。
- 交互式 3D 文字徽章:传 `text='LAUNCH'`、`font='Inter'`、`material='chrome'`、`animate='spin'`、`depth={0.4}`、`keyLightIntensity={1.5}`、`ambientIntensity={0.3}`。
- 静态产品图标:传 `svg={svgUrl}`、`material='gold'`、`depth={0.15}`、`bevelEnabled={true}`、`shadows={true}`、`ambientIntensity={0.6}`、`keyLightX={3}`、`keyLightY={8}`、`keyLightZ={3}`。
- 全息动画 Logo:传 `svg='/brand.svg'`、`material='holographic'`、`animate='spin+float'`、`depth={0.1}`、`ambientIntensity={0.8}`。
- 内联 SVG 字符串:定义 `starSvg` 字符串(含 `<polygon points='...' fill='#FFD700'/>`),传 `svg={starSvg}`、`material='gold'`、`animate='pulse'`、`depth={0.25}`。
- 材质预设含义:`default` 标准 PBR;`plastic` 光滑微亮塑料;`metal` 哑光金属;`glass` 透明玻璃;`rubber` 柔软哑光橡胶;`chrome` 高光镜面铬;`gold` 暖金色 PBR;`clay` 柔和漫反射黏土(适合截图);`emissive` 自发光;`holographic` 彩虹虹彩箔。
- 动画预设含义:`spin` 连续 Y 轴旋转;`float` 轻柔上下浮动;`pulse` 呼吸缩放;`wobble` 左右摆动;`swing` 钟摆摆动;`spin+float` 旋转加浮动;`undefined` 静态,仅用户可拖拽。
- Monorepo 开发:`git clone https://github.com/renatoworks/3dsvg.git`;`cd 3dsvg`;`npm install`;`npm run build:engine` 构建 npm 包;`npm run dev:web` 在 `localhost:3000` 启动可视化编辑器。
- 仅开发 engine 包:`cd packages/engine`;`npm run build` 输出到 `dist/`;`npm run dev` 进入 watch 模式。
- 项目结构定位:`packages/engine/src/index.tsx` 是 `SVG3D` 公开组件;`scene.tsx` 是 Three.js 场景与 `ExtrudedSVG` mesh;`controls.tsx` 是动画逻辑与轨道控制;`materials.ts` 是 PBR 材质预设定义;`types.ts` 是 `SVG3DProps` TypeScript 类型;`use-font.ts` 是 Google Font 到矢量路径的加载器;`packages/web/src/app/` 是 Next.js 页面;`components/` 是编辑器 UI 面板与导出栏;`lib/` 是纹理生成器与 FFmpeg 工具。
- TypeScript 类型:`import type { SVG3DProps } from '3dsvg';`,定义 `const config: SVG3DProps = { svg: '/logo.svg', material: 'chrome', animate: 'float', depth: 0.3 };`,然后 `<SVG3D {...config} />`。
- Next.js 集成:因为 `SVG3D` 使用 Three.js(仅浏览器),使用 `dynamic` 且 `ssr: false`;在组件顶部加 `'use client';`;`const SVG3D = dynamic(() => import('3dsvg').then((m) => m.SVG3D), { ssr: false, loading: () => <div>Loading 3D...</div> });`;再渲染 `<SVG3D svg='/logo.svg' material='gold' animate='spin' />`。
- Vite / React 集成:无需特殊配置,直接 `import { SVG3D } from '3dsvg';`;用 `height: '100vh'` 容器包裹;渲染 `<SVG3D text='Vite + 3D' material='plastic' animate='float' />`。
- 可视化编辑器流程:访问 `https://3dsvg.design`。
- 在编辑器中选输入方式:`Text`、`Pixel Editor`、`SVG Code` 或 `File Upload`。
- 在编辑器中选择材质、动画和灯光配置。
- 使用 `Embed` 导出复制可粘贴的 `<SVG3D>` JSX 片段。
- 导出为 `PNG`(最高 4K)、`Video`(MP4/WebM)或 `3D Model`(GLB/STL/OBJ/PLY)。
- 将 SVG 文件拖放到编辑器任意位置以立即加载。
- 排查空白/白屏:确认安装了 `three`、`@react-three/fiber`、`@react-three/drei`;Next.js 确认使用 `dynamic` 且 `ssr: false`;用显式 `width` 和 `height` 的容器包裹。
- 排查 SVG 挤出错误:使用简单、闭合的 SVG paths;复杂 compound paths 可能无法挤出;路径上的内联 `fill` 属性会被尊重,避免只用 CSS fills;尝试增加 `bevelSegments` 让曲线更平滑。
- 排查文字不加载:`font` prop 从 Google Fonts 加载,确保网络访问或将字体本地托管;支持字体是 `use-font.ts` 中定义的 10 个预设。
- 排查性能问题:减少 `bevelSegments`(试 `1` 或 `2`);低端设备禁用 `shadows`;静态展示使用 `animate={undefined}`。
- 排查 FFmpeg/视频导出在 dev 失败:视频导出使用 FFmpeg WASM 且需要 `SharedArrayBuffer`;给 dev server 添加请求头 `Cross-Origin-Opener-Policy: same-origin` 和 `Cross-Origin-Embedder-Policy: require-corp`。
- 许可证:MIT — Renato Costa / Blueberry,按 MIT 条款使用。
适用边界 · 注意事项
- 非 React 项目,或无法安装 `3dsvg` 及其 peer dependencies `three`、`@react-three/fiber`、`@react-three/drei` 的环境。
- 需要服务端直接渲染 3D 组件且不能使用 `dynamic` + `ssr: false` 的 Next.js 场景;或 SVG 使用复杂 compound paths/CSS-only fills,可能无法正确挤出。
- 需要在内置 dev server 中进行 FFmpeg/WASM 视频导出,但不能设置 `SharedArrayBuffer` 所需 COOP/COEP headers 的环境。