上节实现了 T 恤印花:

这节加上颜色切换、图案切换功能。
安装下 antd:
pnpm install --save antd
加上调节颜色的表单:

<div id="operate">
<div className='ope-item'>
<div>颜色</div>
<div>
<ColorPicker defaultValue={'#ffffff'}/>
</div>
</div>
</div>
写下样式:
这里我们用 sass 来写:
pnpm install --save-dev sass
把 App.css 改成 App.scss


#main {
position: relative;
}
#operate {
position: absolute;
left: 100px;
top: 200px;
color: white;
.ope-item {
display: flex;
width: 100px;
>div:first-child {
padding-right: 20px;
}
}
}
#main 相对定位,#operate 绝对定位在左边。
每个表单项都是水平的 flex 布局。

然后切换颜色的时候我们要修改下T恤颜色:
首先我们写下切换T恤颜色的代码:

gltf.scene.traverse(obj => {
if(obj.isMesh) {
console.log(obj.name, obj);
}
})
打印下模型里的 mesh:

只有这一个。

function changeTShirtColor(color) {
const tshirt = scene.getObjectByName('tshirt');
if(tshirt) {
tshirt.material.color.set(color);
}
}
return {
scene,
renderer,
controls,
changeTShirtColor
}
就是找到这个 mesh,修改材质颜色就行。
ColorPicker 选择颜色的时候调用下:


const changeTShirtColorRef = useRef();
const { scene,changeTShirtColor } = init(dom);
changeTShirtColorRef.current = changeTShirtColor;
<ColorPicker defaultValue={'#ffffff'} onChange={(color) => {
changeTShirtColorRef.current(color.toRgbString());
}}/>
用 useRef 保存函数引用,切换颜色的时候调用下。
看下效果:

这样,T恤颜色切换就完成了。
然后是印花图案的切换
默认没有图案:

let texture = null;
if(!texture) {
return;
}
加一个切换图案的函数:

function changeTexture(url) {
texture = loader.load(url);
texture.colorSpace = THREE.SRGBColorSpace;
}
我们在表单修改了图案的 url 的时候调用这个方法来切换:
加个表单:

<div className='ope-item'>
<div>图案</div>
<div>
<Radio.Group>
<Radio value={'./xiaoxin.png'}>小新</Radio>
<Radio value={'./heart.png'}>爱心</Radio>
</Radio.Group>
</div>
</div>
小新还是之前那个图片:


改下样式:

.ant-radio-label{
color: white;
}
.ope-item {
padding: 10px 0;
}

切换表单值的时候,调用下我们封装的 changeTexture 方法:


const changeTextureRef = useRef();
changeTextureRef.current = changeTexture;
<Radio.Group onChange={e => {
changeTextureRef.current(e.target.value);
}}>
试下效果:

这样我们切换T恤印花图案的功能就完成了。
整体测试下:


案例代码上传了小册仓库。
总结
这节我们实现了切换T恤颜色、印花图案的功能。
用 react + antd 写了切换颜色、图案的表单,然后表单值变化的时候,调用 threejs 代码的方法来修改材质颜色、颜色贴图就好了。
这样,我们的T恤在线设计就完成了。