3dsvg-interactive-react

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

3dsvg — Interactive React 3D Components from SVGs

3dsvg — 从SVG生成交互式React 3D组件

Skill by ara.so — Daily 2026 Skills collection.
3dsvg
extrudes SVG paths, text, and shapes into fully interactive 3D React components powered by Three.js and React Three Fiber. It ships as an embeddable
<SVG3D>
component (npm) plus a visual editor at 3dsvg.design.
ara.so提供的技能 — 属于Daily 2026 Skills合集。
3dsvg
可将SVG路径、文本和形状拉伸为完全交互式的React 3D组件,底层基于Three.js和React Three Fiber实现。它以可嵌入的
<SVG3D>
组件(npm包)形式发布,同时配套了3dsvg.design可视化编辑器。

Installation

安装

bash
npm install 3dsvg
bash
npm install 3dsvg

or

yarn add 3dsvg
yarn add 3dsvg

or

pnpm add 3dsvg

**Peer dependencies** (install if not already present):

```bash
npm install three @react-three/fiber @react-three/drei
pnpm add 3dsvg

**Peer dependencies**(若尚未安装则需安装):

```bash
npm install three @react-three/fiber @react-three/drei

Quick Start

快速开始

tsx
import { SVG3D } from "3dsvg";

// Spin text in 3D
<SVG3D text="Hello" animate="spin" />

// 3D logo from SVG file
<SVG3D svg="/logo.svg" material="gold" />

// Pixel editor input
<SVG3D svg="<svg>...</svg>" material="chrome" animate="float" />
tsx
import { SVG3D } from "3dsvg";

// 让文本以3D形式旋转
<SVG3D text="Hello" animate="spin" />

// 从SVG文件生成3D Logo
<SVG3D svg="/logo.svg" material="gold" />

// 像素编辑器输入
<SVG3D svg="<svg>...</svg>" material="chrome" animate="float" />

SVG3DProps — Full API

SVG3DProps — 完整API

tsx
import { SVG3D } from "3dsvg";

<SVG3D
  // Input (choose one)
  text="Hello World"          // Text string (uses Google Fonts)
  svg="/path/to/file.svg"     // URL to SVG file
  // svg="<svg>...</svg>"     // Raw SVG markup string

  // Font (when using text=)
  font="Inter"                // Google Font name (10 presets available)

  // Material preset
  material="default"          // "default" | "plastic" | "metal" | "glass"
                              // "rubber" | "chrome" | "gold" | "clay"
                              // "emissive" | "holographic"

  // Animation
  animate="spin"              // "spin" | "float" | "pulse" | "wobble"
                              // "swing" | "spin+float" | undefined (static)

  // Geometry
  depth={0.2}                 // Extrusion depth (default: 0.2)
  bevelEnabled={true}         // Enable bevel on edges
  bevelThickness={0.02}       // Bevel thickness
  bevelSize={0.02}            // Bevel size
  bevelSegments={3}           // Bevel smoothness

  // Lighting
  ambientIntensity={0.5}      // Ambient light (0–1)
  keyLightIntensity={1.0}     // Key light brightness
  keyLightX={5}               // Key light X position
  keyLightY={5}               // Key light Y position
  keyLightZ={5}               // Key light Z position
  shadows={true}              // Enable shadow casting

  // Camera
  zoom={1}                    // Initial zoom level
  autoRotate={false}          // Auto-rotate camera (overrides animate)

  // Texture
  texture="none"              // "none" or procedural preset name, or URL
/>
tsx
import { SVG3D } from "3dsvg";

<SVG3D
  // 输入(选择其一)
  text="Hello World"          // 文本字符串(使用Google Fonts)
  svg="/path/to/file.svg"     // SVG文件的URL
  // svg="<svg>...</svg>"     // 原始SVG标记字符串

  // 字体(使用text属性时生效)
  font="Inter"                // Google Font名称(内置10种预设)

  // 材质预设
  material="default"          // "default" | "plastic" | "metal" | "glass"
                              // "rubber" | "chrome" | "gold" | "clay"
                              // "emissive" | "holographic"

  // 动画
  animate="spin"              // "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}               // 主光源X轴位置
  keyLightY={5}               // 主光源Y轴位置
  keyLightZ={5}               // 主光源Z轴位置
  shadows={true}              // 启用阴影投射

  // 相机
  zoom={1}                    // 初始缩放级别
  autoRotate={false}          // 自动旋转相机(覆盖animate属性)

  // 纹理
  texture="none"              // "none"、程序化预设名称或URL
/>

Common Patterns

常见使用模式

Basic Logo Viewer

基础Logo查看器

tsx
import { SVG3D } from "3dsvg";

export function LogoViewer() {
  return (
    <div style={{ width: 400, height: 400 }}>
      <SVG3D
        svg="/logo.svg"
        material="metal"
        animate="float"
        depth={0.3}
        bevelEnabled={true}
        bevelThickness={0.03}
      />
    </div>
  );
}
tsx
import { SVG3D } from "3dsvg";

export function LogoViewer() {
  return (
    <div style={{ width: 400, height: 400 }}>
      <SVG3D
        svg="/logo.svg"
        material="metal"
        animate="float"
        depth={0.3}
        bevelEnabled={true}
        bevelThickness={0.03}
      />
    </div>
  );
}

Interactive 3D Text Badge

交互式3D文本徽章

tsx
import { SVG3D } from "3dsvg";

export function HeroBadge() {
  return (
    <SVG3D
      text="LAUNCH"
      font="Inter"
      material="chrome"
      animate="spin"
      depth={0.4}
      keyLightIntensity={1.5}
      ambientIntensity={0.3}
    />
  );
}
tsx
import { SVG3D } from "3dsvg";

export function HeroBadge() {
  return (
    <SVG3D
      text="LAUNCH"
      font="Inter"
      material="chrome"
      animate="spin"
      depth={0.4}
      keyLightIntensity={1.5}
      ambientIntensity={0.3}
    />
  );
}

Static Product Icon (No Animation)

静态产品图标(无动画)

tsx
import { SVG3D } from "3dsvg";

export function ProductIcon({ svgUrl }: { svgUrl: string }) {
  return (
    <SVG3D
      svg={svgUrl}
      material="gold"
      depth={0.15}
      bevelEnabled={true}
      shadows={true}
      ambientIntensity={0.6}
      keyLightX={3}
      keyLightY={8}
      keyLightZ={3}
    />
  );
}
tsx
import { SVG3D } from "3dsvg";

export function ProductIcon({ svgUrl }: { svgUrl: string }) {
  return (
    <SVG3D
      svg={svgUrl}
      material="gold"
      depth={0.15}
      bevelEnabled={true}
      shadows={true}
      ambientIntensity={0.6}
      keyLightX={3}
      keyLightY={8}
      keyLightZ={3}
    />
  );
}

Holographic Animated Logo

全息动画Logo

tsx
import { SVG3D } from "3dsvg";

export function HolographicLogo() {
  return (
    <SVG3D
      svg="/brand.svg"
      material="holographic"
      animate="spin+float"
      depth={0.1}
      ambientIntensity={0.8}
    />
  );
}
tsx
import { SVG3D } from "3dsvg";

export function HolographicLogo() {
  return (
    <SVG3D
      svg="/brand.svg"
      material="holographic"
      animate="spin+float"
      depth={0.1}
      ambientIntensity={0.8}
    />
  );
}

Inline SVG String

内联SVG字符串

tsx
import { SVG3D } from "3dsvg";

const starSvg = `
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <polygon points="50,5 61,35 95,35 68,57 79,91 50,70 21,91 32,57 5,35 39,35"
    fill="#FFD700"/>
</svg>
`;

export function Star3D() {
  return (
    <SVG3D
      svg={starSvg}
      material="gold"
      animate="pulse"
      depth={0.25}
    />
  );
}
tsx
import { SVG3D } from "3dsvg";

const starSvg = `
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <polygon points="50,5 61,35 95,35 68,57 79,91 50,70 21,91 32,57 5,35 39,35"
    fill="#FFD700"/>
</svg>
`;

export function Star3D() {
  return (
    <SVG3D
      svg={starSvg}
      material="gold"
      animate="pulse"
      depth={0.25}
    />
  );
}

Material Presets Reference

材质预设参考

ValueDescription
"default"
Standard PBR material
"plastic"
Smooth, slightly shiny plastic
"metal"
Matte metallic surface
"glass"
Transparent glass look
"rubber"
Soft matte rubber
"chrome"
High-gloss mirror chrome
"gold"
Warm gold PBR
"clay"
Soft diffuse clay (great for screenshots)
"emissive"
Glowing emission effect
"holographic"
Iridescent rainbow foil
描述
"default"
标准PBR材质
"plastic"
光滑、略带光泽的塑料材质
"metal"
哑光金属表面
"glass"
透明玻璃质感
"rubber"
柔软哑光橡胶
"chrome"
高光泽镜面铬合金
"gold"
暖色调PBR黄金材质
"clay"
柔软漫反射黏土(适合截图)
"emissive"
发光效果
"holographic"
彩虹色虹彩箔片

Animation Presets Reference

动画预设参考

ValueDescription
"spin"
Continuous Y-axis rotation
"float"
Gentle up/down bob
"pulse"
Breathing scale animation
"wobble"
Side-to-side wobble
"swing"
Pendulum swing
"spin+float"
Spin combined with float
undefined
Static, user-draggable only
描述
"spin"
沿Y轴持续旋转
"float"
缓慢上下浮动
"pulse"
呼吸式缩放动画
"wobble"
左右摇摆
"swing"
钟摆式摆动
"spin+float"
旋转与浮动结合
undefined
静态,仅支持用户拖拽

Monorepo Development Setup

单体仓库开发设置

bash
git clone https://github.com/renatoworks/3dsvg.git
cd 3dsvg
npm install
npm run build:engine   # Build the npm package
npm run dev:web        # Start the visual editor at localhost:3000
bash
git clone https://github.com/renatoworks/3dsvg.git
cd 3dsvg
npm install
npm run build:engine   # 构建npm包
npm run dev:web        # 在localhost:3000启动可视化编辑器

Engine package only

仅构建引擎包

bash
cd packages/engine
npm run build          # Outputs to dist/
npm run dev            # Watch mode
bash
cd packages/engine
npm run build          # 输出到dist/目录
npm run dev            # 监听模式

Project Structure

项目结构

packages/
├── engine/src/
│   ├── index.tsx      # SVG3D public component
│   ├── scene.tsx      # Three.js scene, ExtrudedSVG mesh
│   ├── controls.tsx   # Animation logic, orbit controls
│   ├── materials.ts   # PBR material preset definitions
│   ├── types.ts       # SVG3DProps TypeScript types
│   └── use-font.ts    # Google Font → vector path loader
└── web/src/
    ├── app/           # Next.js pages
    ├── components/    # Editor UI panels, export bar
    └── lib/           # Texture generators, FFmpeg utils
packages/
├── engine/src/
│   ├── index.tsx      # SVG3D公共组件
│   ├── scene.tsx      # Three.js场景、拉伸SVG网格
│   ├── controls.tsx   # 动画逻辑、轨道控制器
│   ├── materials.ts   # PBR材质预设定义
│   ├── types.ts       # SVG3DProps TypeScript类型
│   └── use-font.ts    # Google Font → 矢量路径加载器
└── web/src/
    ├── app/           # Next.js页面
    ├── components/    # 编辑器UI面板、导出栏
    └── lib/           # 纹理生成器、FFmpeg工具

TypeScript Types

TypeScript类型

tsx
import type { SVG3DProps } from "3dsvg";

const config: SVG3DProps = {
  svg: "/logo.svg",
  material: "chrome",
  animate: "float",
  depth: 0.3,
};

export function MyComponent() {
  return <SVG3D {...config} />;
}
tsx
import type { SVG3DProps } from "3dsvg";

const config: SVG3DProps = {
  svg: "/logo.svg",
  material: "chrome",
  animate: "float",
  depth: 0.3,
};

export function MyComponent() {
  return <SVG3D {...config} />;
}

Next.js Integration

Next.js 集成

Because
SVG3D
uses Three.js (browser-only), use dynamic import with
ssr: false
:
tsx
// components/Logo3D.tsx
"use client";
import dynamic from "next/dynamic";

const SVG3D = dynamic(
  () => import("3dsvg").then((m) => m.SVG3D),
  { ssr: false, loading: () => <div>Loading 3D...</div> }
);

export function Logo3D() {
  return (
    <SVG3D
      svg="/logo.svg"
      material="gold"
      animate="spin"
    />
  );
}
由于
SVG3D
依赖Three.js(仅支持浏览器环境),需使用动态导入并设置
ssr: false
tsx
// components/Logo3D.tsx
"use client";
import dynamic from "next/dynamic";

const SVG3D = dynamic(
  () => import("3dsvg").then((m) => m.SVG3D),
  { ssr: false, loading: () => <div>加载3D内容中...</div> }
);

export function Logo3D() {
  return (
    <SVG3D
      svg="/logo.svg"
      material="gold"
      animate="spin"
    />
  );
}

Vite / React Integration

Vite / React 集成

tsx
// No special config needed — just import and use
import { SVG3D } from "3dsvg";

function App() {
  return (
    <div style={{ height: "100vh" }}>
      <SVG3D text="Vite + 3D" material="plastic" animate="float" />
    </div>
  );
}
tsx
// 无需特殊配置 — 直接导入使用
import { SVG3D } from "3dsvg";

function App() {
  return (
    <div style={{ height: "100vh" }}>
      <SVG3D text="Vite + 3D" material="plastic" animate="float" />
    </div>
  );
}

Visual Editor Workflow

可视化编辑器工作流程

  1. Go to 3dsvg.design
  2. Choose an input method: Text, Pixel Editor, SVG Code, or File Upload
  3. Pick a material, animation, and lighting configuration
  4. Use the Embed export to copy a ready-to-paste
    <SVG3D>
    JSX snippet
  5. Export as PNG (up to 4K), Video (MP4/WebM), or 3D Model (GLB/STL/OBJ/PLY)
Drag and drop an SVG file anywhere on the editor to load it instantly.
  1. 访问3dsvg.design
  2. 选择输入方式:文本像素编辑器SVG代码文件上传
  3. 选择材质、动画和光照配置
  4. 使用嵌入导出功能,复制可直接粘贴的
    <SVG3D>
    JSX代码片段
  5. 导出为PNG(最高4K)、视频(MP4/WebM)或3D模型(GLB/STL/OBJ/PLY)
将SVG文件拖拽到编辑器任意位置即可快速加载。

Troubleshooting

故障排除

Component renders blank / white screen
  • Ensure
    three
    ,
    @react-three/fiber
    , and
    @react-three/drei
    are installed
  • In Next.js, confirm you're using
    dynamic
    with
    ssr: false
  • Wrap in a container with explicit
    width
    and
    height
SVG not extruding correctly
  • Use simple, closed SVG paths; complex compound paths may not extrude
  • Inline
    fill
    attributes on paths are respected — avoid CSS-only fills
  • Try increasing
    bevelSegments
    for smoother curves
Text not loading
  • The
    font
    prop loads from Google Fonts — ensure network access or host fonts locally
  • Supported fonts are the 10 presets defined in
    use-font.ts
Performance issues
  • Reduce
    bevelSegments
    (try
    1
    or
    2
    )
  • Disable
    shadows
    for lower-end devices
  • Use
    animate={undefined}
    for static display
FFmpeg/video export fails in dev
  • Video export uses FFmpeg WASM and requires
    SharedArrayBuffer
  • Add these headers to your dev server:
    Cross-Origin-Opener-Policy: same-origin
    and
    Cross-Origin-Embedder-Policy: require-corp
组件渲染空白/白屏
  • 确保已安装
    three
    @react-three/fiber
    @react-three/drei
  • 在Next.js中,确认使用了带
    ssr: false
    的动态导入
  • 将组件包裹在带有明确
    width
    height
    的容器中
SVG无法正确拉伸
  • 使用简单的闭合SVG路径;复杂复合路径可能无法正常拉伸
  • 路径上的内联
    fill
    属性会被识别 — 避免仅使用CSS设置填充
  • 尝试增加
    bevelSegments
    以获得更平滑的曲线
文本无法加载
  • font
    属性从Google Fonts加载字体 — 确保网络可访问或本地托管字体
  • 支持的字体为
    use-font.ts
    中定义的10种预设
性能问题
  • 减少
    bevelSegments
    (尝试设置为
    1
    2
  • 为低端设备禁用
    shadows
  • 静态展示时使用
    animate={undefined}
开发环境中FFmpeg/视频导出失败
  • 视频导出使用FFmpeg WASM,需要
    SharedArrayBuffer
  • 为开发服务器添加以下响应头:
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Embedder-Policy: require-corp

License

许可证