Compare commits

...

4 Commits

Author SHA1 Message Date
de2293443c 1
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-05 18:46:16 +08:00
156c9c3a3a 1
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-05 18:09:38 +08:00
2e59bae10b yes
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-05 18:06:37 +08:00
24cebd2179 1 2026-01-05 17:41:00 +08:00
19 changed files with 569 additions and 898 deletions

View File

@ -1 +1 @@
VITE_PUBLIC = https://cdn.files.zguiy.com/studio/
VITE_PUBLIC = ./

342
cursor.md
View File

@ -1,178 +1,204 @@
# AI Code Generation Prompts: Startup Website Clone
**Tech Stack:** Vite + Vue 3 (Script Setup) + Tailwind CSS + Lucide Icons
# Web3D 场景 SDK 使用说明
本 SDK 用于在 Web 场景中快速完成三维展示与交互,核心能力包括:相机修改、灯光调参、环境贴图切换、按配置渲染热点、热点驱动抛出事件、模型热加载/热销毁/热替换,以及按部件切换材质。
---
## 🟢 Step 0: Project Setup (Global System Prompt)
*在开始编写具体页面前,先发送这条指令,建立全局的设计规范和技术栈。*
**Prompt:**
> **Role:** Senior Frontend Developer specializing in Pixel-Perfect UI cloning.
>
> **Tech Stack Requirements:**
> - **Framework:** Vue 3 (Composition API with `<script setup>`) + typescript.
> - **Build Tool:** Vite.
> - **Styling:** Tailwind CSS (Mobile-first approach).
> - **Icons:** `lucide-vue-next` (You must use this library).
> - **Language:** TypeScript.
>
> **Design System (Strict Adherence):**
> - **Visual Style:** Minimalist, "Vercel-like" aesthetic. High contrast, clean lines.
> - **Typography:** Inter or system-ui. Headings must use `tracking-tight` (letter-spacing: -0.025em).
> - **Colors:**
> - Background: `#ffffff` (White).
> - Surface/Card: `#ffffff` (White) with `border-gray-200`.
> - Primary Text: `#0f172a` (Slate-900).
> - Muted Text: `#64748b` (Slate-500).
> - Accents: Black buttons, Light gray backgrounds (`bg-gray-50`) for secondary elements.
> - **Borders & Radius:** Delicate borders (`border`, `border-gray-100`). Card radius is `rounded-xl` or `rounded-2xl`.
> - **Shadows:** Very subtle `shadow-sm`, hover states use `shadow-md`.
>
> **Instruction:** I will provide tasks to build 3 specific pages. You must replicate the layout, spacing, and Chinese copy exactly as described.
## 功能概览
- 相机控制:支持位置/目标点/FOV/远近裁剪的即时更新,带缓动动画。
- 灯光调参:主光、辅光、环境光强度、颜色、方向、阴影开关与软硬度。
- 环境贴图HDRI 切换、曝光度、旋转(偏航/俯仰)、模糊度。
- 热点系统:基于配置渲染热点 UI可按 click/hover/focus 抛出事件。
- 模型热更新:按 ID 进行加载、销毁、替换,支持队列并行与完成回调。
- 材质切换:按部件或分组应用/还原材质,支持预设表与回滚。
- 事件总线:统一事件接口,便于业务侧订阅热点/相机/模型状态。
---
## 🟡 Step 1: Pricing Page (定价页)
*复制此段生成定价页面组件。*
## 快速开始
```bash
npm install your-web3d-sdk
```
**Prompt:**
```ts
import { createViewer } from 'your-web3d-sdk'
> **Task:** Create a **`PricingPage.vue`** component. Clone the provided "Pricing" design exactly.
>
> **1. Page Header:**
> - Layout: Centered.
> - Overline: "PRICING" (uppercase, tracking-widest, text-xs, text-gray-400).
> - Title: "产品购买页面" (text-3xl font-bold tracking-tight).
> - Subtitle: "按需套餐付费,尊享 Codex 与 Claude Code 两大产品线" (text-gray-500 mt-2).
>
> **2. Section 1: Codex Plans (2-Column Grid):**
> - **Heading:** "Codex 套餐" (Bold, text-lg, mb-4).
> - **Layout:** Grid `grid-cols-1 md:grid-cols-2 gap-6`.
> - **Card Design:** `bg-white border border-gray-200 rounded-xl p-6 relative`.
> - **Left Card (Standard):**
> - Top: Icon + "Codex" + "codex标准套餐". Badge: "工效效率" (Top Right, gray bg, text-xs).
> - Price: "¥79.9/月" (text-4xl font-bold). Subtext: "性价比首选 | 强大智能".
> - Features: List with blue bullet points (daily budget $90, etc.).
> - **Right Card (Enterprise):**
> - Price: "¥ 999". Badge: "定制高频版".
> - Features: "个人/企业 定制高险套餐", "高频需求首选".
>
> **3. Section 2: Claude Code Plans (3-Column Grid):**
> - **Heading:** "Claude Code 套餐" (Bold, text-lg, mt-10 mb-4).
> - **Layout:** Grid `grid-cols-1 md:grid-cols-3 gap-6`.
> - **Cards:**
> - Card 1: ¥228/月. Badge: "轻量性价比".
> - Card 2: ¥398/月. Badge: "适合中等规模". (Highlight: slightly darker border or shadow).
> - Card 3: ¥520/月. Badge: "深度运算".
> - **Bottom Wide Card:** A full-width card for "Claude Code 定制套餐" (¥999).
>
> **4. CRITICAL COMPONENT - Bottom Action Button:**
> - Inside EVERY card, pinned to the bottom.
> - Container: `bg-gray-50` (light gray), `rounded-lg`, `p-4`, `mt-6`.
> - Layout: Flex row, `justify-between`, `items-center`.
> - Text Left: "联系顾问" (font-medium text-sm).
> - Text Right: Small gray caption (e.g., "codex标准套餐 · ¥79.9/月").
> - Icon: Small `ChevronDown` or `ChevronRight` on the right side.
>
> **5. Copy:** Use the exact Chinese text provided in the description.
const sdk = await createViewer({
container: '#viewer',
assetsBase: '/assets',
background: '#0f172a',
})
// 加载初始场景或模型
await sdk.model.load({ id: 'scene', url: '/models/showroom.glb' })
```
### 基础生命周期
1. 初始化 viewer`createViewer({ container })`
2. 加载模型或场景:`sdk.model.load(...)`
3. 设置环境贴图/灯光:`sdk.environment.setHDRI(...)``sdk.lights.update(...)`
4. 渲染热点:`sdk.hotspot.render(config.hotspots)`
5. 订阅事件:`sdk.on('hotspot:click', handler)`
6. 在业务侧按需调用相机/材质/模型热更新 API
---
## 🔵 Step 2: Documentation Page (使用文档页)
*复制此段生成文档页面组件。*
## 相机控制
```ts
// 直接设置视角
sdk.camera.set({
position: [2.5, 1.6, 3.2],
target: [0, 0.8, 0],
fov: 45,
near: 0.1,
far: 200,
})
**Prompt:**
> **Task:** Create a **`DocsPage.vue`** component. Clone the "Usage Guide" design exactly.
>
> **1. Header & Controls:**
> - Title: "使用说明". Subtitle: "新产品与插件安装的快速指南".
> - **Tabs (Model):** A pill-shaped toggle container. Items: [Codex | Claude Code | GLM].
> - Active State: Black background, White text.
> - Inactive State: Transparent background, Gray text.
> - **Tabs (OS):** Underline style. [Windows | macOS | Linux]. Active item has a black underline.
>
> **2. Vertical Stepper Layout (The Core Visual):**
> - **Container:** Max-width 800px, centered.
> - **Structure:** A vertical list of steps.
> - **Left Column:** A Step Indicator.
> - A black circle (`w-6 h-6 bg-black text-white rounded-full flex items-center justify-center text-xs font-bold`) with the number (1, 2, 3).
> - A thin gray vertical line (`w-px bg-gray-200`) connecting the numbers.
> - **Right Column:** The content.
>
> **3. Step Content Details:**
> - **Step 1 (Install Node.js):**
> - Title: "安装 Node.js 18+ (通用)".
> - Link: "官网下载 (推荐)" in blue.
> - Warning Box: A `bg-gray-50` rounded box containing bullet points about permissions.
> - Version Check: A dark bar `node --version`.
> - **Step 2 (Install CLI):**
> - Title: "安装 Codex CLI".
> - **Code Block:** A dark container (`bg-[#0f172a]`), `rounded-lg`, `p-4`, `shadow-inner`.
> - Text: `npm install -g @openai/codex` (White text, font-mono).
> - **Step 3 (Config):**
> - Title: "配置环境 (CodeX)".
> - **File Editor UI:** Create a mock code editor.
> - Filename: "config.toml文件" (gray text above block).
> - Code Content: Multi-line TOML config. Use specific colors for syntax highlighting (e.g., Strings in green, Keys in purple/white).
>
> **4. Component Abstraction:**
> - Please create a separate `<CodeBlock :code="code" :lang="lang" />` component for reusability.
// 平滑过渡到指定视角
sdk.camera.animateTo(
{ position: [1.2, 1, 2.4], target: [0, 0.8, 0], fov: 50 },
{ duration: 0.8, easing: 'easeOutCubic' }
)
```
---
## 🔴 Step 3: Features Page (功能特性页)
*复制此段生成功能着陆页组件。*
## 灯光调参
```ts
// 更新主方向光
sdk.lights.update('key', {
intensity: 1.5,
color: '#ffffff',
direction: [0.3, -1, 0.25],
castShadow: true,
})
**Prompt:**
> **Task:** Create a **`FeaturesPage.vue`** component. Clone the "Features" design exactly.
>
> **1. Hero Section:**
> - Alignment: Center.
> - Headline: "更快、更智能地构建软件" (text-5xl font-bold tracking-tight mb-6).
> - Subheadline: "聚合多模型,深度理解你的代码库..." (text-gray-500 max-w-2xl mx-auto).
> - Action Buttons:
> - Primary: "开始使用" (Black bg, white text, rounded-full, px-8 py-2.5).
> - Secondary: "查看文档" (White bg, border border-gray-200, black text, rounded-full, px-8 py-2.5).
>
> **2. The Bento Grid (Critical Visual):**
> - Section Title: "覆盖从编码到交付的全流程".
> - **Grid System:** `grid-cols-1 md:grid-cols-3 gap-6`.
> - **Card Anatomy:**
> - `bg-white border border-gray-200 rounded-xl p-6 flex flex-col h-full overflow-hidden hover:shadow-md transition-all`.
> - **Icon:** Top-left. Small Lucide icon inside a square `bg-gray-50` rounded container.
> - **Text:** Title (font-bold mt-4) + Description (text-sm text-gray-500 mt-2).
> - **The Mockup Area (Must Have):** At the bottom of each card, create a visual placeholder.
> - *Implementation:* A `div` with `bg-gray-50/50 mt-6 h-32 w-full rounded border border-dashed border-gray-200`. Put a small "skeleton" UI inside (e.g., a few gray bars representing code lines) to mimic the screenshots.
>
> **3. Stats Bar:**
> - Layout: Flex row, wide container.
> - Items:
> - "2x" (交付效率提升)
> - "40%" (Bug 修复加速)
> - "60%" (重复劳动减少)
> - Style: Numbers are huge (`text-5xl font-bold tracking-tighter`). Labels are small and gray.
>
> **4. Footer CTA:**
> - Text: "准备好升级研发效率了吗?"
> - Button: "免费开始" (White button, border, rounded-full).
// 环境光/辅光
sdk.lights.update('fill', { intensity: 0.6, color: '#dfe8ff' })
sdk.lights.update('ambient', { intensity: 0.25 })
```
---
## 💡 Developer Tips (For You)
## 环境贴图
```ts
await sdk.environment.setHDRI('/envs/showroom_2k.hdr', {
exposure: 1.1,
rotation: [0, 45, 0], // yaw/pitch/roll
blur: 0.2,
})
```
1. **Global Font Fix:** To get the crisp look from the screenshots, add this to your `index.css` or `style.css`:
```css
body {
font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
```
2. **Icon Installation:** Ensure you have the icons installed:
```bash
npm install lucide-vue-next
```
3. **Refining:** If the AI output looks "too loose", tell it: *"Reduce the border-radius to 12px and make the text colors sharper (slate-900 instead of gray-800)."*
---
## 热点渲染与事件
```ts
const hotspots = [
{
id: 'engine',
position: [0.8, 0.6, -0.2],
icon: 'info',
label: '发动机舱',
event: 'show-engine',
payload: { part: 'engine' },
},
{
id: 'door',
position: [1.1, 0.9, 0.4],
icon: 'action',
label: '开启车门',
event: 'toggle-door',
payload: { side: 'left' },
},
]
sdk.hotspot.render(hotspots)
sdk.hotspot.on('click', ({ id, payload }) => {
// 业务侧根据 id/payload 触发操作
})
sdk.hotspot.on('hover', ({ id, hovering }) => {
// hover 高亮或提示
})
```
事件命名建议(可按需扩展):
- `hotspot:click``hotspot:hover``hotspot:focus`
- `hotspot:rendered`(所有热点就绪)
---
## 模型热加载 / 热销毁 / 热替换
```ts
// 加载
await sdk.model.load({ id: 'car', url: '/models/car.glb', draco: true })
// 销毁
await sdk.model.destroy('car')
// 替换(内部自动销毁旧实例并加载新实例)
await sdk.model.replace('car', { url: '/models/car-white.glb' })
```
可以通过 `sdk.model.on('loaded' | 'replaced' | 'destroyed', handler)` 监听模型状态。
---
## 材质切换
```ts
// 应用材质预设
sdk.material.apply({
target: 'body', // 部件或分组名称
material: 'paint/blue', // 预设 Key
})
// 批量切换
sdk.material.batch([
{ target: 'wheel', material: 'rim/chrome' },
{ target: 'glass', material: 'glass/clear' },
])
// 还原默认材质
sdk.material.reset('body')
```
---
## 推荐的配置结构
```json
{
"camera": { "position": [2.5, 1.6, 3.2], "target": [0, 0.8, 0], "fov": 45 },
"environment": { "hdr": "/envs/showroom_2k.hdr", "exposure": 1.1, "rotation": [0, 45, 0] },
"lights": {
"key": { "intensity": 1.5, "color": "#ffffff", "direction": [0.3, -1, 0.25] },
"fill": { "intensity": 0.6, "color": "#dfe8ff" },
"ambient": { "intensity": 0.25 }
},
"hotspots": [
{ "id": "engine", "position": [0.8, 0.6, -0.2], "icon": "info", "label": "发动机舱", "event": "show-engine" },
{ "id": "door", "position": [1.1, 0.9, 0.4], "icon": "action", "label": "开启车门", "event": "toggle-door" }
]
}
```
---
## 事件清单(示例)
- 相机:`camera:changed`
- 热点:`hotspot:click``hotspot:hover``hotspot:rendered`
- 模型:`model:loaded``model:replaced``model:destroyed`
- 材质:`material:applied``material:reset`
订阅方式:
```ts
sdk.on('hotspot:click', (evt) => console.log(evt))
sdk.off('hotspot:click', handler) // 移除监听
```
---
## 调试建议
- 启用 `sdk.debug(true)` 查看加载、事件、帧率等日志。
- 逐步应用配置:先确认相机与灯光,再添加环境贴图与热点,最后再做材质/模型热更新。
- 热更新前后记录 ID/实例,避免重复销毁或遗漏解绑事件。

View File

@ -0,0 +1,105 @@
# SDK API 参考
下列 API 均可在全局挂载或 ESM 模式下使用。示例统一使用 `kernel` 作为实例,若为全局构建请替换为 `window.faceSDK.kernel`
## 相机 Camera
```ts
// 设置视角
kernel.camera.set({
position: [2.5, 1.6, 3.2],
target: [0, 0.8, 0],
fov: 45,
near: 0.1,
far: 200,
})
// 平滑过渡
kernel.camera.animateTo(
{ position: [1.2, 1, 2.4], target: [0, 0.8, 0], fov: 50 },
{ duration: 0.8, easing: 'easeOutCubic', onFinish: () => console.log('camera done') }
)
```
## 灯光 Lights
```ts
// 主方向光
kernel.lights.update('key', {
intensity: 1.5,
color: '#ffffff',
direction: [0.3, -1, 0.25],
castShadow: true,
})
// 环境光 / 辅光
kernel.lights.update('fill', { intensity: 0.6, color: '#dfe8ff' })
kernel.lights.update('ambient', { intensity: 0.25 })
```
## 环境贴图 Environment
```ts
await kernel.environment.setHDRI('/envs/showroom_2k.hdr', {
exposure: 1.1,
rotation: [0, 45, 0], // yaw/pitch/roll
blur: 0.2,
})
```
## 热点 Hotspot
```ts
const hotspots = [
{ id: 'engine', position: [0.8, 0.6, -0.2], icon: 'info', label: '发动机舱', event: 'show-engine' },
{ id: 'door', position: [1.1, 0.9, 0.4], icon: 'action', label: '开启车门', event: 'toggle-door' },
]
kernel.hotspot.render(hotspots)
kernel.hotspot.on('click', ({ id, payload }) => {
console.log('hotspot click', id, payload)
})
kernel.hotspot.on('hover', ({ id, hovering }) => {
console.log('hotspot hover', id, hovering)
})
```
## 模型 Model
```ts
// 加载
await kernel.model.load({ id: 'car', url: '/models/car.glb', draco: true })
// 销毁
await kernel.model.destroy('car')
// 替换
await kernel.model.replace('car', { url: '/models/car-white.glb' })
// 事件
kernel.model.on('loaded', (data) => console.log('loaded', data))
kernel.model.on('replaced', (data) => console.log('replaced', data))
kernel.model.on('destroyed', (data) => console.log('destroyed', data))
```
## 材质 Material
```ts
// 应用预设
kernel.material.apply({ target: 'body', material: 'paint/blue' })
// 批量切换
kernel.material.batch([
{ target: 'wheel', material: 'rim/chrome' },
{ target: 'glass', material: 'glass/clear' },
])
// 还原
kernel.material.reset('body')
```
## 事件总线与调试
```ts
// 订阅/取消
kernel.on('hotspot:click', (evt) => console.log(evt))
kernel.off('hotspot:click', handler)
// 开启调试日志
kernel.debug(true)
```

View File

@ -1,39 +0,0 @@
# 案例模板(可直接复制改内容)
> 这是一个 Markdown 案例模板,你可以复制成 `case-xxx.md`,然后在页面里直接预览。
## 项目背景
- 行业 / 场景:
- 目标(转化/展示/提效):
- 时间周期:
- 我的角色:前端 / 全栈 / Web3D / 小程序
## 交付内容
- 核心页面:
- 核心功能:
- 技术栈:
- 部署方式:
## 难点与解决方案
1. 难点:
2. 方案:
3. 结果:
## 代码片段(示例)
```ts
export type ApiResponse<T> = {
code: number
message: string
data: T
}
```
## 复盘
- 做得好的:
- 下次会更好的:

View File

@ -1,16 +0,0 @@
# 联系方式
> 建议把这里的联系方式换成你的真实信息。
- 微信:`TyTinSx`
- 邮箱:`14154666@qq.com`
## 发需求时建议包含
1. 项目类型:官网/后台/全栈/Web3D/小程序
2. 目标:要达成什么效果或指标
3. 范围:页面/功能清单(越具体越好)
4. 参考:竞品/参考链接、设计稿、文案素材
5. 时间:期望上线时间、是否有阶段节点
6. 现状:是否已有代码、接口、服务器、域名等

View File

@ -0,0 +1,71 @@
# 事件监听指南
说明如何订阅/取消订阅 SDK 事件,适用于全局挂载与 ESM 两种集成方式。
## 获取实例
- ESM`import { kernel } from '.../index.js'`
- 全局:`const kernel = window.faceSDK?.kernel`
以下示例统一使用 `kernel`
## 常见事件
- 相机:`camera:changed`
- 热点:`hotspot:click``hotspot:hover``hotspot:focus``hotspot:rendered`
- 模型:`model:loaded``model:replaced``model:destroyed``model:load:progress`
- 材质:`material:applied``material:reset`
- 其他:业务自定义事件(若有)
## 订阅与取消
```ts
// 订阅
const handleHotspotClick = (evt) => {
console.log('hotspot click', evt.id, evt.payload)
}
kernel.on('hotspot:click', handleHotspotClick)
// 取消订阅
kernel.off('hotspot:click', handleHotspotClick)
```
## 示例:热点事件
```ts
kernel.on('hotspot:hover', ({ id, hovering }) => {
// 根据 hovering 控制高亮/提示
})
kernel.on('hotspot:rendered', () => {
console.log('所有热点已就绪')
})
```
## 示例:模型事件
```ts
kernel.on('model:load:progress', ({ id, progress }) => {
console.log(`模型 ${id} 进度`, progress)
})
kernel.on('model:loaded', ({ id }) => {
console.log(`模型 ${id} 加载完成`)
})
kernel.on('model:replaced', ({ id }) => {
console.log(`模型 ${id} 已替换`)
})
```
## 示例:相机与材质
```ts
kernel.on('camera:changed', (state) => {
console.log('相机状态', state)
})
kernel.on('material:applied', ({ target, material }) => {
console.log(`材质已应用到 ${target}: ${material}`)
})
```
## 调试与日志
```ts
// 输出加载、事件、性能相关的调试信息
kernel.debug(true)
```

View File

@ -0,0 +1,58 @@
# 引入方式与事件监听
介绍两种集成方式(全局挂载 / 模块化 ESM以及统一的事件监听方法。
## 全局挂载(非模块化)
1. 引入全局构建产物(替换为你的实际部署地址):
```html
<script src="https://sdk.zguiy.com/zt/assets/index.global.js"></script>
```
2. 获取实例并初始化:
```js
const kernel = window.faceSDK?.kernel
if (!kernel) {
console.error('SDK 未加载')
} else {
kernel.init({
container: '#renderDom', // 容器 IDcanvas 或者 DOM 元素引用
modelUrlList: ['./model.glb'], // 模型列表
env: { envPath: '/public/hdr/hdr.env', intensity: 1.2, rotationY: 0.3 }, // 环境贴图等参数
})
}
```
## 模块化ESM
1. 在 `<script type="module">` 中导入:
```js
import { kernel } from 'https://sdk.zguiy.com/zt/assets/index.js' // 构建后路径自行替换
```
2. 初始化(与全局方式一致):
```js
kernel.init({
container: '#renderDom', // 容器 IDcanvas 或者 DOM 元素引用
modelUrlList: ['./model.glb'],
env: { envPath: '/public/hdr/hdr.env', intensity: 1.2, rotationY: 0.3 }, // 环境贴图等参数
})
```
## 事件监听(两种方式通用)
```js
kernel.on('model:load:progress', (data) => console.log('模型加载进度', data))
kernel.on('model:loaded', (data) => console.log('模型加载完成', data))
kernel.on('model:click', (data) => console.log('模型点击', data))
// 需要时可移除
// kernel.off('model:loaded', handler)
```
## 提供测试用的模型和环境贴图
```
https://sdk.zguiy.com/resurces/model/model.glb
```
```
https://sdk.zguiy.com/resurces/hdr/hdr.env
```

View File

@ -1,22 +0,0 @@
# 服务清单
## 我能做什么
- 企业官网 / 产品官网 / 落地页品牌展示、动效、响应式、SEO 基础、上线部署。
- 后台管理系统:权限、表格、筛选、导入导出、图表看板、审批流(按需)。
- 全栈业务开发:接口设计、鉴权、数据库建模、联调、部署(按需)。
- Web3D 互动展示Three.js / Babylon.js模型加载、交互热点、性能优化与业务联动。
- 3D 建模与渲染建模、UV、贴图烘焙、PBR 材质、灯光渲染与出片(静帧/视频)。
- 小程序开发:微信小程序 / uni-app按需常见业务页面与接口联调发布。
## 你需要提供什么
- 目标与范围:要解决什么问题?核心流程是什么?
- 参考与素材参考链接、设计稿Figma/蓝湖/Sketch、文案、图片、Logo 等。
- 约束条件:时间节点、预算范围、技术限制、已有接口/账号/服务器(如有)。
## 我会交付什么
- 可运行项目(源码 + 构建产物)
- 交付说明(部署/环境变量/使用说明)
- 里程碑验收清单(对照验收更省心)

View File

@ -1,63 +0,0 @@
# Web3D 案例展示
基于 Three.js / Babylon.js 开发的 3D 互动展示项目。
---
## 小型货车 3D 配置器
![蓝擎X1货车](/案例图片/web3d/5b86f5fffbab10515fa800a435620437.png)
蓝擎X1小型货车在线配置器支持颜色切换极光蓝/珠光白)、外观/内饰/行驶模式预览,可触发车门开关、车灯等交互动画。
🔗 暂无分享链接
---
## SUV 汽车 3D 展示
![星仓SUV](/案例图片/web3d/dfcac2db610f8005a823d0dc93d8cea9.png)
星仓系列 SUV 3D 展厅,支持宝石蓝、水晶紫、冰川银、岩石灰等多种车漆颜色实时切换,外观与内饰双视角浏览。
🔗 暂无分享链接
---
## 虚拟数字展厅
![虚拟展厅](/案例图片/web3d/de96ab4609d15338c15f7eb97ec82cc1.png)
企业虚拟展馆,第三人称漫游模式,集成产品陈列、数据大屏、中国地图可视化,支持虚拟人物导览。
🔗 暂无分享链接
---
## 摩托车 3D 展示
![摩托车展示](/案例图片/web3d/xw_20251231091651.png)
高精度摩托车模型展示,展厅灯光环境,支持 360° 旋转查看细节。
🔗 暂无分享链接
---
## 运动鞋 3D 配置器
![运动鞋配置](/案例图片/web3d/xw_20251231091744.png)
运动鞋在线定制工具,支持多种配色方案实时切换,材质纹理清晰可见。
🔗 暂无分享链接
---
## 自行车 3D 展示
![自行车展示](/案例图片/web3d/xw_20251231091809.png)
山地自行车户外场景展示,支持车型配置选择,实时渲染骑行效果预览。
🔗 暂无分享链接

View File

@ -1,33 +0,0 @@
# 建模与渲染PBR 流程)
面向「产品 / 角色 / 场景」资产制作:建模 → UV → 烘焙 → PBR 材质 → 灯光渲染 → 出片(静帧/视频)。流程可按你的项目预算与时间裁剪。
## 适合的需求
- 产品展示电商主图、详情图、爆炸图、360 展示、质感渲染
- 角色/道具:游戏或宣传视觉的资产制作与渲染出片
- 场景/小片段:镜头分镜、氛围灯光、简单动画与剪辑出片(按需)
## 标准流程(可按项目裁剪)
1. 需求对齐:用途(电商/游戏/交互/视频)、风格参考、镜头与交付规格(分辨率/FPS/时长)
2. 建模:高模/低模(按需)、拓扑优化、模型命名与层级整理
3. UV拆分、展开、打包为贴图与烘焙做准备
4. 烘焙Normal / AO / Curvature / ID 等(按项目需要)
5. 材质PBRBaseColor / Metallic / Roughness / Normal / AO+ Emissive/Opacity 按需)
6. 灯光与渲染HDRI/三点布光、材质校色、渲染参数与降噪(按引擎与预算)
7. 合成与出片通道AOV合成、调色、字幕/转场、输出静帧或视频
8. 交付:源文件 + 贴图 + 成片;需要适配引擎/平台也可输出 glTF/FBX按需
## 你需要提供什么
- 参考与目标:风格图/竞品链接、用途与核心卖点
- 素材Logo/贴纸/花纹(如有)、尺寸/结构信息(如有)
- 交付规格:分辨率、画幅、背景(透明/纯色/场景)、视频时长与帧率
## 我会交付什么
- 源文件(按工具):工程文件/模型文件/材质节点(按约定)
- 贴图文件PBR 贴图与烘焙贴图(按约定打包)
- 成片静帧PNG/JPG或视频MP4可提供可复用的镜头与灯光设置按需

View File

@ -1,34 +0,0 @@
# 按天合作
适合短期支援、技术咨询或灵活用工需求。
## 合作方式
1. 确认工作内容与时间
2. 按天计费,灵活安排
3. 每日同步进度
4. 按实际工作天数结算
## 适用场景
- 项目紧急支援
- 技术难题攻关
- 代码审查与优化
- 架构设计咨询
## 日费参考
| 服务类型 | 日费 |
|---------|------|
| 前端开发 | ¥800 - ¥1,500 |
| 后端开发 | ¥1,000 - ¥2,000 |
| 全栈开发 | ¥1,200 - ¥2,500 |
| 技术咨询 | ¥1,500 - ¥3,000 |
## 工作时间
- 标准8小时/天
- 支持远程协作
- 可根据需求调整
> 长期合作可享优惠价格

View File

@ -1,27 +0,0 @@
# 按项目合作
适合有明确需求、完整功能模块的客户。
## 合作方式
1. 需求沟通与评估
2. 报价与合同签订
3. 分阶段交付与验收
4. 项目上线与维护
## 适用场景
- 企业官网开发
- 小程序/App 开发
- 后台管理系统
- 定制化功能模块
## 报价参考
| 项目类型 | 周期 | 价格区间 |
|---------|------|---------|
| 企业官网 | 1-2周 | ¥3,000 - ¥8,000 |
| 小程序 | 2-4周 | ¥5,000 - ¥15,000 |
| 管理后台 | 3-6周 | ¥10,000 - ¥30,000 |
> 具体报价根据实际需求评估

View File

@ -22,7 +22,6 @@
<div class="h-5 w-5 rotate-45 rounded-[4px] border-2 border-slate-900 shadow-[0_2px_6px_rgba(0,0,0,0.08)]" />
<div class="grid leading-tight">
<span class="text-sm font-semibold">{{ site.brand }}</span>
<!-- <span class="text-[11px] text-gray-500">{{ site.subtitle }}</span> -->
</div>
</div>
@ -41,13 +40,12 @@
</nav>
<div class="flex items-center gap-3 max-[640px]:w-full max-[640px]:justify-between">
<a
<button
class="rounded-full border border-slate-900 bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white shadow-[0_10px_24px_rgba(0,0,0,0.12)] transition-[transform,box-shadow,background,color] duration-200 hover:shadow-[0_12px_28px_rgba(0,0,0,0.16)] active:translate-y-px"
:href="`mailto:${site.contact.email}`"
@click="handleNav('/docs')"
>
咨询合作
</a>
查看文档
</button>
</div>
</div>
</div>
@ -58,7 +56,7 @@
</main>
<footer class="border-t border-gray-200 bg-white">
<div class="mx-auto grid w-full max-w-[1200px] grid-cols-5 gap-6 px-6 pt-10 pb-6 max-[900px]:grid-cols-2 max-[640px]:grid-cols-1">
<div class="mx-auto grid w-full max-w-[1200px] grid-cols-4 gap-6 px-6 pt-10 pb-6 max-[900px]:grid-cols-2 max-[640px]:grid-cols-1">
<div class="col-span-2 grid gap-3 max-[900px]:col-span-2 max-[640px]:col-span-1">
<div class="inline-flex items-center gap-2.5">
<div class="h-5 w-5 rotate-45 rounded-[4px] border-2 border-slate-900 shadow-[0_2px_6px_rgba(0,0,0,0.08)]" />
@ -73,37 +71,26 @@
</div>
<div class="grid gap-2">
<div class="font-bold text-gray-900">服务</div>
<div class="font-bold text-gray-900">产品能力</div>
<ul class="m-0 grid list-none gap-1.5 p-0 text-gray-600">
<li>企业官网 / 落地页</li>
<li>后台管理系统</li>
<li>全栈业务开发</li>
<li>Web3D 互动展示</li>
<li>3D建模与渲染PBR</li>
<li>相机控制与动画</li>
<li>灯光与环境贴图</li>
<li>热点渲染与事件</li>
<li>模型热加载/替换</li>
<li>材质切换与预设</li>
</ul>
</div>
<div class="grid gap-2">
<div class="font-bold text-gray-900">技术栈</div>
<div class="font-bold text-gray-900">资源</div>
<ul class="m-0 grid list-none gap-1.5 p-0 text-gray-600">
<li>Vue / React / TypeScript</li>
<li>Node.js / NestJS / Express</li>
<li>MySQL / PostgreSQL / Redis</li>
<li>Three.js / Babylon.js</li>
</ul>
</div>
<div class="grid gap-2">
<div class="font-bold text-gray-900">合作</div>
<ul class="m-0 grid list-none gap-1.5 p-0 text-gray-600">
<li>按需求评估报价</li>
<li>按里程碑验收交付</li>
<li>支持远程协作</li>
<li>可提供维护服务</li>
<li><button class="text-left text-gray-600 hover:text-black" @click="handleNav('/')">首页</button></li>
<li><button class="text-left text-gray-600 hover:text-black" @click="handleNav('/docs')">SDK 文档</button></li>
<li><a class="text-gray-600 hover:text-black" :href="`mailto:${site.contact.email}`">技术支持</a></li>
</ul>
</div>
</div>
<div class="border-t border-gray-200 py-3 text-center text-xs text-gray-400">合作条款 · 交付说明</div>
<div class="border-t border-gray-200 py-3 text-center text-xs text-gray-400">Web3D 场景 SDK · 开箱即用的互动体验</div>
</footer>
</div>
</template>
@ -118,17 +105,14 @@ const route = useRoute()
const router = useRouter()
const tabs = [
{ id: 'features', label: '能力与服务', path: '/' },
// { id: 'pricing', label: '报价', path: '/' },
{ id: 'cooperation', label: '合作流程', path: '/cooperation' },
{ id: 'markdown', label: '案例/文章', path: '/markdown' },
{ id: 'home', label: '首页', path: '/' },
{ id: 'docs', label: 'SDK 文档', path: '/docs' },
] as const
const activeId = computed(() => {
if (route.name === 'features') return 'features'
if (route.name === 'cooperation') return 'cooperation'
if (route.name === 'markdown') return 'markdown'
return 'pricing'
if (route.name === 'home') return 'home'
if (route.name === 'docs') return 'docs'
return 'home'
})
const handleNav = (path: string) => {

View File

@ -1,8 +1,7 @@
export const site = {
brand: '子归云工作室',
// subtitle: '前端 · 全栈 · Web3D · 3D建模/渲染 · 官网/后台/小程序',
brand: 'Web3D 场景 SDK',
tagline:
'承接企业官网、后台管理、全栈业务系统、Web3D 互动展示Three.js / Babylon.js与 3D 建模渲染PBR 流程)。支持按需求评估、按里程碑交付、长期维护。',
'一站式 Web3D 互动 SDK相机控制、灯光/环境贴图、热点事件、模型热更新与材质切换,快速搭建可配置的三维体验。',
contact: {
wechat: 'TyTinSx',
email: '1415466602@qq.com',

View File

@ -1,13 +1,10 @@
import { createRouter, createWebHistory } from 'vue-router'
import PricingPage from '@/views/PricingPage.vue'
import FeaturesPage from '@/views/FeaturesPage.vue'
import MarkdownPage from '@/views/MarkdownPage.vue'
import CooperationPage from '@/views/CooperationPage.vue'
const routes = [
{ path: '/', name: 'features', component: FeaturesPage },
{ path: '/markdown', name: 'markdown', component: MarkdownPage },
{ path: '/cooperation', name: 'cooperation', component: CooperationPage },
{ path: '/', name: 'home', component: FeaturesPage },
{ path: '/docs', name: 'docs', component: MarkdownPage },
]
export const router = createRouter({

View File

@ -1,116 +0,0 @@
<template>
<section class="grid gap-6 pt-3 pb-10">
<header class="grid gap-2.5">
<h1 class="m-0 text-[28px] font-extrabold tracking-[-0.01em]">合作流程</h1>
<p class="m-0 text-gray-600">灵活的合作模式满足不同项目需求</p>
</header>
<div class="grid gap-4">
<div class="flex flex-wrap gap-2">
<button
v-for="file in mdFiles"
:key="file"
:class="[
'rounded-full px-4 py-2 text-sm font-semibold transition-colors',
currentFile === file ? 'bg-slate-900 text-white' : 'border border-gray-200 bg-white text-gray-600 hover:bg-gray-50',
]"
@click="loadFile(file)"
>
{{ file.replace('.md', '') }}
</button>
</div>
<div
v-if="htmlContent"
ref="contentRef"
class="prose prose-slate max-w-none rounded-2xl border border-gray-200 bg-white p-6 shadow-[0_14px_26px_rgba(0,0,0,0.06)]"
v-html="htmlContent"
/>
</div>
</section>
</template>
<script setup lang="ts">
import { marked } from 'marked'
import { nextTick, onMounted, ref, watch } from 'vue'
const BASE_URL = import.meta.env.BASE_URL
// 合作流程文件列表
const cooperationFiles = ['按项目.md', '按天.md']
const mdFiles = ref<string[]>([])
const currentFile = ref('')
const htmlContent = ref('')
const contentRef = ref<HTMLElement>()
onMounted(async () => {
mdFiles.value = cooperationFiles
if (mdFiles.value.length > 0) {
await loadFile(mdFiles.value[0])
}
})
const addCopyButtons = () => {
if (!contentRef.value) return
contentRef.value.querySelectorAll('pre').forEach((pre) => {
if (pre.querySelector('.copy-btn')) return
const button = document.createElement('button')
button.className = 'copy-btn'
button.textContent = '复制'
button.onclick = async () => {
const code = pre.querySelector('code')
const text = code?.textContent || ''
try {
await navigator.clipboard.writeText(text)
} catch {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.cssText = 'position:fixed;opacity:0'
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
}
button.textContent = '已复制'
setTimeout(() => (button.textContent = '复制'), 1500)
}
pre.style.position = 'relative'
pre.appendChild(button)
})
}
watch(htmlContent, () => nextTick(addCopyButtons))
const loadFile = async (filename: string) => {
currentFile.value = filename
try {
const res = await fetch(`${BASE_URL}docs/${filename}`)
if (!res.ok) return
const content = await res.text()
htmlContent.value = marked(content) as string
} catch (e) {
console.error('加载文档失败:', e)
}
}
</script>
<style>
.prose h1 { font-size: 1.875rem; font-weight: 800; margin-bottom: 1rem; }
.prose h2 { font-size: 1.5rem; font-weight: 700; margin-top: 1.5rem; margin-bottom: 0.75rem; }
.prose h3 { font-size: 1.25rem; font-weight: 600; margin-top: 1.25rem; margin-bottom: 0.5rem; }
.prose p { margin-bottom: 1rem; line-height: 1.7; color: #4b5563; }
.prose ul, .prose ol { margin-bottom: 1rem; padding-left: 1.5rem; }
.prose li { margin-bottom: 0.25rem; color: #4b5563; }
.prose code { background: #f1f5f9; padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-size: 0.875rem; }
.prose pre { background: #1e293b; color: #e2e8f0; padding: 1rem; padding-top: 2.5rem; border-radius: 0.75rem; overflow-x: auto; margin-bottom: 1rem; position: relative; }
.prose pre::before { content: ''; position: absolute; top: 12px; left: 12px; width: 12px; height: 12px; border-radius: 50%; background: #ff5f56; box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f; }
.prose pre code { background: transparent; padding: 0; }
.prose a { color: #2563eb; text-decoration: underline; }
.prose blockquote { border-left: 4px solid #e5e7eb; padding-left: 1rem; color: #6b7280; font-style: italic; }
.prose table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.prose th, .prose td { border: 1px solid #e5e7eb; padding: 0.5rem 1rem; text-align: left; }
.prose th { background: #f9fafb; font-weight: 600; }
.copy-btn { position: absolute; top: 0.5rem; right: 0.5rem; padding: 0.25rem 0.75rem; font-size: 0.75rem; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); border-radius: 9999px; color: #e2e8f0; cursor: pointer; transition: background 0.2s; }
.copy-btn:hover { background: rgba(255,255,255,0.2); }
</style>

View File

@ -1,19 +1,19 @@
<template>
<section class="grid gap-10 pt-3 pb-12">
<header class="grid gap-3 text-center">
<div class="text-[13px] text-gray-500">能力与服务 / 交付型合作 / 可长期维护</div>
<h1 class="m-0 text-[clamp(28px,4vw,44px)] font-extrabold tracking-[-0.02em]">把需求做成可交付的产品</h1>
<p class="m-0 mx-auto max-w-[680px] leading-[1.7] text-gray-600">
我能做前端全栈Web3DBabylon.js / Three.js3D 建模/渲染PBR官网与后台管理小程序开发等你给目标和素材我负责方案实现联调上线
<div class="text-[13px] text-gray-500">Web3D 场景 SDK · 相机/灯光/环境贴图/热点/模型/材质</div>
<h1 class="m-0 text-[clamp(28px,4vw,44px)] font-extrabold tracking-[-0.02em]">让三维展示可配置可热更新</h1>
<p class="m-0 mx-auto max-w-[760px] leading-[1.7] text-gray-600">
开箱即用的 Web3D SDK内置相机控制灯光与 HDRI配置化热点事件总线模型热加载/销毁/替换与材质切换适用于在线展厅产品配置器互动热点讲解等场景
</p>
<div class="inline-flex justify-center gap-3 max-[640px]:w-full max-[640px]:justify-center">
<Button @click="router.push('/cooperation')">查看报价</Button>
<Button variant="secondary" @click="router.push('/cooperation')">合作流程</Button>
<Button @click="router.push('/docs')">查看 SDK 文档</Button>
<Button variant="secondary" @click="router.push('/docs')">示例与 API</Button>
</div>
</header>
<div class="grid gap-[18px]">
<div class="mt-2 text-center text-[22px] font-bold">覆盖从设计对接到上线交付的全流程</div>
<div class="mt-2 text-center text-[22px] font-bold">核心能力</div>
<div class="grid grid-cols-3 gap-5 max-[1024px]:grid-cols-2 max-[640px]:grid-cols-1">
<Card v-for="(feature, index) in features" :key="feature.title" hoverable class="grid content-start gap-3">
<div
@ -43,7 +43,7 @@
</div>
<div class="grid gap-[18px]">
<div class="text-center font-semibold text-gray-700">合的项目类型</div>
<div class="text-center font-semibold text-gray-700">用场景</div>
<div class="grid grid-cols-2 gap-5 max-[1024px]:grid-cols-1">
<Card v-for="item in scenarios" :key="item" hoverable class="grid grid-cols-[32px_1fr] items-center gap-3">
<div
@ -57,9 +57,9 @@
</div>
<div class="grid gap-[18px]">
<div class="text-center font-semibold text-gray-700">合作优势</div>
<div class="text-center font-semibold text-gray-700">产品指标</div>
<div class="grid grid-cols-3 gap-5 max-[1024px]:grid-cols-2 max-[640px]:grid-cols-1">
<Card v-for="stat in stats" :key="stat.value" class="text-center">
<Card v-for="stat in stats" :key="stat.label" class="text-center">
<div class="text-[38px] font-extrabold tracking-[-0.02em]">{{ stat.value }}</div>
<div class="mt-1.5 text-sm text-gray-600">{{ stat.label }}</div>
</Card>
@ -67,11 +67,16 @@
</div>
<Card hoverable class="text-center">
<div class="text-xl font-bold">想把需求尽快落地</div>
<p class="m-0 text-gray-500">把你的目标参考链接时间节点发我我会给出方案与排期建议</p>
<div class="text-xl font-bold">准备好把 Web3D 能力接入产品了吗</div>
<p class="m-0 text-gray-500">从相机/灯光到热点事件只需按照文档配置即可上线遇到问题可随时邮件联系支持</p>
<div class="mt-4 inline-flex gap-3 max-[640px]:w-full max-[640px]:justify-center">
<Button @click="router.push('/cooperation')">获取报价</Button>
<Button variant="secondary" @click="router.push('/markdown')">查看案例</Button>
<Button @click="router.push('/docs')">立即查看文档</Button>
<a
class="rounded-full border border-gray-200 bg-white px-4 py-2.5 text-sm font-semibold text-slate-900 shadow-[0_8px_18px_rgba(0,0,0,0.06)] transition hover:border-slate-900"
:href="`mailto:${site.contact.email}`"
>
邮件支持
</a>
</div>
</Card>
</section>
@ -80,19 +85,18 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import {
Boxes,
Cloud,
Code2,
Cpu,
Cuboid,
LayoutTemplate,
Camera,
Layers,
Sparkles,
MousePointer2,
Palette,
ShieldCheck,
Sparkles,
SunMedium,
} from 'lucide-vue-next'
import Button from '@/components/Button/index.vue'
import Card from '@/components/Card/index.vue'
import TypeItTerminal, { type TypeItTerminalSegment } from '@/components/TypeItTerminal.vue'
import { site } from '@/config/site'
const router = useRouter()
@ -103,239 +107,139 @@ type Feature = {
}
const features: Feature[] = [
{ title: '前端工程化', description: 'Vue/React + TypeScript + 构建与规范,让项目可维护、可迭代。', icon: Code2 },
{ title: '后台管理', description: '权限、表格、图表、导入导出与业务流程,按习惯做出“顺手”的后台。', icon: LayoutTemplate },
{ title: '全栈开发', description: '接口设计、鉴权、数据库建模与联调,打通前后端的交付链路。', icon: Layers },
{ title: 'Web3D', description: 'Three.js/Babylon.js 场景搭建、交互、性能优化与业务 UI 联动。', icon: Cuboid },
{ title: '官网/落地页', description: '品牌展示 + 动效 + SEO 基础,支持多端适配与上线部署。', icon: Sparkles },
{ title: '小程序开发', description: '微信小程序/uni-app按需从页面到接口联调与发布。', icon: Boxes },
{ title: '性能优化', description: '首屏、图片、缓存、包体与渲染优化,提升体验与转化。', icon: Cpu },
{ title: '部署上线', description: 'Docker/服务器部署(按需),支持环境隔离与灰度发布方案。', icon: Cloud },
{ title: '质量与安全', description: '边界处理、日志与监控建议,交付稳定可靠的线上版本。', icon: ShieldCheck },
{
title: '相机控制与动画',
description: 'set/animateTo 支持位置、目标、FOV、近远裁剪带缓动过渡与回调。',
icon: Camera,
},
{
title: '灯光与环境贴图',
description: '主光/辅光/环境光参数化配置HDRI 切换、曝光、旋转、模糊一键生效。',
icon: SunMedium,
},
{
title: '热点渲染与事件',
description: '配置驱动热点 UIclick/hover/focus 抛出事件;可绑定业务 Payload。',
icon: MousePointer2,
},
{
title: '模型热加载 / 替换',
description: '按 ID 管理模型,支持加载、销毁、替换与并行队列,状态事件可订阅。',
icon: Layers,
},
{
title: '材质切换与预设',
description: '按部件/分组应用材质预设,支持批量切换与回滚默认材质。',
icon: Palette,
},
{
title: '事件总线与调试',
description: '统一事件接口kernel.debug 输出加载、事件、性能日志,便于排障。',
icon: ShieldCheck,
},
]
const featureTerminalScripts: TypeItTerminalSegment[][] = [
[
{
html: [
'<div><span class="text-gray-500">$</span> pnpm create <span class="text-emerald-600">vite</span> my-app</div>',
'<div><span class="text-gray-500">$</span> pnpm i <span class="text-amber-600">eslint</span> <span class="text-amber-600">prettier</span></div>',
'<div><span class="text-gray-500">✓</span> <span class="text-emerald-600">tsconfig</span> + <span class="text-emerald-600">lint</span> ready</div>',
].join(''),
speed: 28,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 20,
},
{
html: [
'<div><span class="text-blue-600">export</span> <span class="text-blue-600">type</span> Use r = { id: <span class="text-blue-600">string</span>; name: <span class="text-blue-600">string</span> }</div>',
'<div><span class="text-blue-600">const</span> state = reactive&lt;{ user?: User }&gt;({})</div>',
].join(''),
speed: 18,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-gray-500">roles</span> → <span class="text-gray-500">menus</span> → <span class="text-gray-500">actions</span></div>',
'<div><span class="text-gray-500">✓</span> route guard + permission check</div>',
].join(''),
speed: 22,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: [
'<div><span class="text-slate-900">columns</span> = [<span class="text-amber-600">"ID"</span>, <span class="text-amber-600">"Name"</span>, <span class="text-amber-600">"Status"</span>]</div>',
'<div><span class="text-gray-500">✓</span> filter · export · batch action</div>',
].join(''),
html: '<div><span class="text-gray-500">kernel.camera.set</span>({ fov: 45, position: [2,1.2,3] })</div>',
speed: 26,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-blue-600">@Get</span>(<span class="text-amber-600">"/users"</span>)</div>',
'<div><span class="text-blue-600">async</span> list(@Query() q) { <span class="text-blue-600">return</span> svc.list(q) }</div>',
].join(''),
speed: 18,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 16,
},
{
html: [
'<div><span class="text-gray-500">POST /auth/login</span> → <span class="text-emerald-600">JWT</span></div>',
'<div><span class="text-gray-500">DB</span>: users · roles · sessions</div>',
].join(''),
speed: 22,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-blue-600">import</span> { Engine, Scene } <span class="text-blue-600">from</span> <span class="text-amber-600">"@babylonjs/core"</span></div>',
'<div><span class="text-blue-600">const</span> engine = <span class="text-blue-600">new</span> Engine(canvas)</div>',
'<div><span class="text-blue-600">const</span> scene = <span class="text-blue-600">new</span> Scene(engine)</div>',
].join(''),
speed: 20,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: [
'<div><span class="text-gray-500">glTF</span> + <span class="text-gray-500">DRACO</span> + <span class="text-gray-500">LOD</span></div>',
'<div><span class="text-gray-500">✓</span> interaction · hotspot · UI sync</div>',
].join(''),
html: '<div><span class="text-gray-500">kernel.camera.animateTo</span>({ target: [0,0.8,0] }, { duration: 0.8 })</div>',
speed: 24,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-gray-500">&lt;title&gt;</span>品牌官网<span class="text-gray-500">&lt;/title&gt;</span></div>',
'<div><span class="text-gray-500">&lt;meta</span> name=<span class="text-amber-600">"description"</span> ... <span class="text-gray-500">/&gt;</span></div>',
].join(''),
speed: 26,
html: '<div><span class="text-gray-500">kernel.lights.update</span>(<span class="text-amber-600">"key"</span>, { intensity: 1.4, castShadow: true })</div>',
speed: 24,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 20,
deleteSpeed: 18,
},
{
html: [
'<div><span class="text-gray-500">hero</span> · <span class="text-gray-500">features</span> · <span class="text-gray-500">pricing</span> · <span class="text-gray-500">contact</span></div>',
'<div><span class="text-gray-500">✓</span> responsive · animation · deploy</div>',
].join(''),
speed: 18,
html: '<div><span class="text-gray-500">kernel.environment.setHDRI</span>("showroom.hdr", { exposure: 1.1, rotation: [0,45,0] })</div>',
speed: 22,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-blue-600">Page</span>({ data })</div>',
'<div>onLoad(() =&gt; fetchList())</div>',
'<div><span class="text-gray-500">✓</span> tab · list · detail</div>',
].join(''),
html: '<div><span class="text-gray-500">kernel.hotspot.render</span>([{ id: "engine", event: "show-engine" }])</div>',
speed: 24,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: '<div><span class="text-gray-500">kernel.on</span>(<span class="text-emerald-600">"hotspot:click"</span>, ({ id }) =&gt; highlight(id))</div>',
speed: 22,
pauseAfter: 1200,
},
],
[
{
html: '<div><span class="text-gray-500">kernel.model.load</span>({ id: "car", url: "/car.glb" })</div>',
speed: 24,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: '<div><span class="text-gray-500">kernel.model.replace</span>("car", { url: "/car-white.glb" })</div>',
speed: 24,
pauseAfter: 1200,
},
],
[
{
html: '<div><span class="text-gray-500">kernel.material.apply</span>({ target: "body", material: "paint/blue" })</div>',
speed: 24,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: '<div><span class="text-gray-500">kernel.material.batch</span>([{ target: "glass", material: "glass/clear" }])</div>',
speed: 22,
pauseAfter: 1200,
},
],
[
{
html: '<div><span class="text-gray-500">kernel.on</span>(<span class="text-emerald-600">"model:loaded"</span>, log)</div>',
speed: 22,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 18,
},
{
html: [
'<div><span class="text-gray-500">subpackages</span> · <span class="text-gray-500">request</span> · <span class="text-gray-500">upload</span></div>',
'<div><span class="text-gray-500">✓</span> publish checklist</div>',
].join(''),
html: '<div><span class="text-gray-500">kernel.debug</span>(<span class="text-amber-600">true</span>)</div>',
speed: 18,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-gray-500">Lighthouse</span>: <span class="text-emerald-600">95+</span></div>',
'<div><span class="text-gray-500">-</span> image optimize (webp/avif)</div>',
'<div><span class="text-gray-500">-</span> code split + cache</div>',
].join(''),
speed: 16,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 14,
},
{
html: [
'<div><span class="text-gray-500">TTFB</span> ↓ · <span class="text-gray-500">LCP</span> ↓ · <span class="text-gray-500">CLS</span> ↓</div>',
'<div><span class="text-gray-500">✓</span> perf budget applied</div>',
].join(''),
speed: 20,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-purple-600">services</span>:</div>',
'<div>&nbsp;&nbsp;<span class="text-slate-900">web</span>: <span class="text-amber-600">nginx</span></div>',
'<div>&nbsp;&nbsp;<span class="text-slate-900">api</span>: <span class="text-amber-600">node</span></div>',
'<div>&nbsp;&nbsp;<span class="text-slate-900">db</span>: <span class="text-amber-600">postgres</span></div>',
].join(''),
speed: 18,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 16,
},
{
html: [
'<div><span class="text-gray-500">env</span>: dev · staging · prod</div>',
'<div><span class="text-gray-500">✓</span> deploy + rollback plan</div>',
].join(''),
speed: 22,
pauseAfter: 1200,
},
],
[
{
html: [
'<div><span class="text-gray-500">fix</span>: edge case for empty list</div>',
'<div><span class="text-gray-500">test</span>: add regression</div>',
'<div><span class="text-gray-500">✓</span> release notes ready</div>',
].join(''),
speed: 20,
pauseAfter: 900,
deleteAfter: true,
deleteSpeed: 16,
},
{
html: [
'<div><span class="text-gray-500">v1.2.0</span> · new feature</div>',
'<div><span class="text-gray-500">v1.2.1</span> · hotfix</div>',
].join(''),
speed: 16,
pauseAfter: 1200,
},
],
]
const featureTerminalAlign: Array<'top' | 'center' | 'bottom'> = [
'bottom',
'top',
'bottom',
'top',
'bottom',
'top',
'bottom',
'top',
'center',
]
const featureTerminalAlign: Array<'top' | 'center' | 'bottom'> = ['bottom', 'top', 'bottom', 'top', 'bottom', 'center']
const featureTerminalMinLines = [4, 3, 3, 4, 3, 3, 4, 4, 3]
const featureTerminalMinLines = [3, 3, 3, 3, 3, 2]
const scenarios = [
'品牌官网/产品官网:高还原 + 动效 + SEO 基础',
'运营活动页:周期紧、改动频繁、注重转化',
'后台管理:权限/表格/导入导出/图表看板',
'全栈业务:接口 + 数据库 + 管理后台一体化交付',
'Web3D 展示:模型加载、交互热点、镜头与动效',
'3D 建模/渲染建模、材质、灯光与出片PBR 流程)',
'小程序:列表/详情/下单/登录/授权等常见场景',
'存量项目:重构、性能优化、修 Bug、继续迭代',
'上线交付:部署方案、环境配置、监控建议(按需)',
'在线产品展示/VR 展厅:相机巡览 + 热点讲解 + 材质切换',
'Web3D 配置器:颜色/部件切换、材质预设与模型替换',
'工业/汽车/家居互动:分部件热点、事件驱动 UI 联动',
'营销与培训页面:按配置渲染热点,引导用户操作或答题',
]
const stats = [
{ value: '', label: '沟通明确后快速推进' },
{ value: '', label: '注重边界与线上稳定' },
{ value: '清晰', label: '按里程碑可验收交付' },
{ value: '可维护', label: '工程化与可读结构' },
{ value: '可扩展', label: '考虑后续迭代成本' },
{ value: '可协作', label: '对接设计/后端/运营' },
{ value: '<10 s', label: '完成初始化并渲染首个模型' },
{ value: '7 APIs', label: '核心高频能力(相机/灯光/热点/模型/材质)' },
{ value: '<3 s', label: '缓存场景下平均热替换耗时' },
]
</script>

View File

@ -1,8 +1,8 @@
<template>
<section class="grid gap-6 pt-3 pb-10">
<header class="grid gap-2.5">
<h1 class="m-0 text-[28px] font-extrabold tracking-[-0.01em]">案例 / </h1>
<p class="m-0 text-gray-600"> Markdown 维护你的案例服务说明与技术文章支持代码复制</p>
<h1 class="m-0 text-[28px] font-extrabold tracking-[-0.01em]">SDK </h1>
<p class="m-0 text-gray-600">Web3D 场景 SDK 的快速入门核心 API 与配置示例</p>
</header>
<div class="grid gap-4">
@ -27,7 +27,7 @@
v-html="htmlContent"
/>
<div v-else class="rounded-2xl border border-gray-200 bg-gray-50 p-6 text-center text-gray-500">
请选择一个文档查看
请选择一个文档查看内容
</div>
</div>
</section>
@ -39,8 +39,12 @@ import { nextTick, onMounted, ref, watch } from 'vue'
const BASE_URL = import.meta.env.BASE_URL
// 案例文件列表,后期可在此添加新文件
const caseFiles = ['web3d.md', '建模与渲染.md', 'services.md', 'case-template.md', 'contact.md']
// SDK 文档列表
const docsFiles = [
'import-guide.md',
'api-reference.md',
'event-listening.md',
]
const mdFiles = ref<string[]>([])
const currentFile = ref('')
@ -48,7 +52,7 @@ const htmlContent = ref('')
const contentRef = ref<HTMLElement>()
onMounted(async () => {
mdFiles.value = caseFiles
mdFiles.value = docsFiles
if (mdFiles.value.length > 0) {
await loadFile(mdFiles.value[0])
}

View File

@ -1,127 +0,0 @@
<template>
<section class="grid gap-10 pt-3 pb-12">
<div class="grid gap-2 text-center">
<div class="inline-flex flex-wrap justify-center gap-3.5 text-xs text-gray-500">
<span>前端开发</span>
<span>全栈开发</span>
<span>后台管理</span>
<span>Web3DThree/Babylon</span>
<span>3D建模/渲染PBR</span>
<span>小程序</span>
</div>
<div class="text-[11px] tracking-[0.3em] text-gray-400">SERVICES</div>
<h1 class="m-0 text-[clamp(26px,4vw,36px)] font-extrabold tracking-[-0.02em]">服务与报价</h1>
<p class="m-0 mx-auto max-w-[680px] leading-relaxed text-gray-500">
按需求评估按里程碑交付可从 0 1 搭建也可接手存量项目重构/优化/继续迭代
</p>
</div>
<div class="grid gap-4">
<h2 class="m-0 text-lg font-bold">常见合作套餐</h2>
<div class="grid grid-cols-3 gap-[18px] max-[1024px]:grid-cols-2 max-[640px]:grid-cols-1">
<PlanCard v-for="plan in projectPlans" :key="plan.subtitle" v-bind="plan" />
</div>
</div>
<div class="grid gap-4">
<h2 class="m-0 text-lg font-bold">长期合作</h2>
<div class="grid grid-cols-2 gap-[18px] max-[1024px]:grid-cols-1">
<PlanCard v-for="plan in retainerPlans" :key="plan.subtitle" v-bind="plan" />
</div>
<div class="grid grid-cols-1 gap-[18px]">
<PlanCard v-bind="customPlan" />
</div>
</div>
</section>
</template>
<script setup lang="ts">
import PlanCard from '@/components/PlanCard/index.vue'
type Plan = {
title: string
subtitle: string
badge?: string
price: string
note?: string
features: string[]
footerNote: string
highlight?: boolean
}
const projectPlans: Plan[] = [
{
title: '企业官网 / 落地页',
subtitle: '品牌展示 · SEO 基础',
badge: '快速交付',
price: '¥ 按需求报价',
note: '适合活动页、产品官网、品牌介绍、营销落地。',
features: ['响应式适配 · 兼容主流浏览器', '高还原 UI + 动效', 'SEO/OG/站点地图(按需)', '表单/埋点/转化链路(按需)'],
footerNote: '交付:源码 + 部署说明',
},
{
title: '后台管理系统',
subtitle: '权限 · 表格 · 图表',
badge: '业务提效',
price: '¥ 按需求报价',
note: '适合数据看板、运营后台、CRM/ERP 子系统。',
features: ['账号/角色/权限模型', '列表/筛选/导出/批处理', '接口联调 + 错误处理', '可维护的组件与路由结构'],
footerNote: '交付:可部署版本 + 使用说明',
highlight: true,
},
{
title: 'Web3D 互动展示',
subtitle: 'Three.js / Babylon.js',
badge: '更强体验',
price: '¥ 按需求报价',
note: '适合产品展示、展厅导览、互动营销、3D 组件开发。',
features: ['模型加载/压缩glTF/DRACO', '交互与镜头控制', '性能优化LOD/合批/纹理)', '与页面业务联动UI/数据)'],
footerNote: '交付:可复用组件 + 性能建议',
},
{
title: '3D建模与渲染',
subtitle: '建模 · 材质 · PBR · 出片',
badge: '可出视频',
price: '¥ 按需求报价',
note: '适合产品/角色/场景资产制作,支持从建模到渲染出片(静帧/视频)。',
features: [
'高模/低模建模 + 拓扑优化(按需)',
'UV 展开与贴图烘焙Normal/AO 等)',
'PBR 材质流程Substance/Blender 等)',
'灯光/渲染/合成与视频输出(按需)',
],
footerNote: '交付:源文件 + 贴图 + 成片',
},
]
const retainerPlans: Plan[] = [
{
title: '长期迭代(按月)',
subtitle: '稳定排期 · 迭代交付',
badge: '长期合作',
price: '¥ 按月报价',
note: '适合长期运营产品、版本迭代、活动频繁的团队。',
features: ['每周同步进度与风险', '按里程碑验收与交付', '代码规范/CI/质量把控', '线上问题响应(按约定)'],
footerNote: '方式:远程协作 · 里程碑结算',
},
{
title: '全栈开发(按需求)',
subtitle: '接口 · 数据库 · 部署',
badge: '从 0 到 1',
price: '¥ 按需求报价',
note: '适合需要后端接口、数据建模、部署上线的一体化项目。',
features: ['API 设计与鉴权JWT/OAuth', '数据库建模与迁移', '日志/监控/告警(按需)', 'Docker/服务器部署(按需)'],
footerNote: '交付:接口文档 + 部署脚本(按需)',
},
]
const customPlan: Plan = {
title: '定制合作',
subtitle: '按需求评估报价',
badge: '欢迎咨询',
price: '¥ 面议',
note: '把你的需求发我:目标、时间、参考风格、已有资料/接口。我会给出排期与报价建议。',
features: ['支持接手存量项目:重构/性能优化/修 Bug', '支持小程序开发:微信小程序/uni-app按需', '支持设计对接Figma/蓝湖/Sketch', '可签 NDA/合同与发票(按需)'],
footerNote: '微信/邮箱咨询 · 先评估再开工',
}
</script>