提示词
使用Three.js的SpriteMaterial和Canvas API创建3D场景中的城市名称标签,实现动态文本标签的随机分布和颜色变化效果。
效果拆解
| 效果 |
实现方式 |
| 城市数据加载 |
使用fetch API获取JSON格式的城市数据 |
| Canvas文本渲染 |
创建Canvas元素并使用2D上下文绘制文本 |
| 纹理生成 |
将Canvas转换为DataURL并创建Three.js纹理 |
| Sprite标签 |
使用SpriteMaterial和Sprite创建3D文本标签 |
| 随机分布 |
在3D空间中随机设置标签位置 |
| 颜色变化 |
为每个标签生成随机颜色 |
核心技术点
1. Canvas文本创建函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const createCanvasText = ({ dpr = 1 } = {}) => {
return ({ text = '', color = '#ffffff' } = {}) => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 512 * dpr
canvas.height = 128 * dpr
ctx.fillStyle = color
ctx.font = `${64 * dpr}px Arial`
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillText(text, canvas.width / 2, canvas.height / 2)
return canvas
}
}
2. 随机颜色生成
const getColor = () => '#' + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0')
3. 城市标签创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const citys = await fetch(FILE_HOST+'files/json/city.json').then(res => res.json())
const updateCanvasText = createCanvasText({ dpr: 1.4 })
for (const key in citys) {
const canvas = updateCanvasText({ text: key, color: getColor() })
const texture = new THREE.TextureLoader().load(canvas.toDataURL())
const material = new THREE.SpriteMaterial({ map: texture })
const sprite = new THREE.Sprite(material)
sprite.scale.set(canvas.width / canvas.height, 1, 1)
sprite.position.set(
Math.random() * 20 - 10,
Math.random() * 20 - 10,
Math.random() * 20 - 10
)
scene.add(sprite)
}
调试技巧
- Canvas尺寸调整:通过dpr参数调整Canvas的清晰度
- 字体大小:根据Canvas尺寸调整字体大小以获得最佳显示效果
- 标签缩放:根据文本长度调整Sprite的scale属性
- 颜色对比度:确保文本颜色与背景有足够的对比度
扩展思路
- 交互效果:添加鼠标悬停高亮效果
- 动画效果:实现标签的浮动或旋转动画
- 数据可视化:根据城市数据改变标签大小或颜色
- 点击事件:添加点击标签显示详细信息的功能
- 性能优化:使用对象池管理大量标签
- 样式定制:支持自定义字体、边框、阴影等样式
💬 评论区
评论功能即将上线,敬请期待!