深灰背景中央挂着一件白色卫衣,页面两侧各有一组沿弧线排开的圆形色卡,像挂在衣架旁边的布料样本。点任意一张,衣服立刻换上那种花纹——樱花枝、条纹、彩点、几何图案,图案严丝合缝地贴在衣身范围内,袖口、下摆、领口的边界都不会溢出,而且衣服原有的褶皱与阴影仍然透过图案显现,像是布料本身就是这个花色。点最上面那颗白色的空色卡则恢复纯白。切换时旧图案先淡出、新图案再淡入,不会硬切。
这里没有任何 3D 建模,也没有服务端合成:三张图叠出来就是全部——衣服底图、一张只有衣身形状的遮罩、一张只有明暗的阴影图。
这套花色预览的四个关键
形状靠遮罩图裁出来。花纹是一块平铺的背景,套上一张与衣服等大的遮罩图后,只有衣身对应的区域可见,边缘随衣服轮廓自然收边。
立体感靠混合模式。阴影图用正片叠底叠在花纹之上,衣服的褶皱、垂坠和暗部会把花纹一起压暗,图案因此“跟着布料起伏”,而不是平贴上去的一张纸。
色卡是弧形排布的。每颗色卡用同一个变换原点加不同的旋转角,就沿着一段圆弧摆开了,不需要逐个算坐标,响应式下只要改原点距离即可整体缩放。
切换有正确的两种路径。脚本区分“当前没有花纹”和“已有花纹”两种情况:前者直接设好图案再整体淡入,后者先把旧图案淡出、在回调里换图再淡入——省掉这一步就会看到两种花纹重叠的一帧。
三个让效果显得真实的做法
其一,遮罩用 contain 而不是 cover。遮罩尺寸设为等比包含,保证它与底图的缩放行为一致;如果用铺满,衣服在不同窗口比例下会与遮罩错位,边缘就会露出花纹的直角。同理,花纹容器的宽度和左偏移是按底图比例算的固定百分比,改衣服图时这两个值需要一起校准。
其二,阴影图必须是中性灰的明暗信息。正片叠底会把下层与上层相乘,纯白区域不改变下层,越暗压得越狠。所以这张图只保留衣服的光影、去掉固有色,才能既保留立体感又不影响花纹的颜色。做自家素材时,把服装照片去色并提高一点对比度就能得到可用的阴影层。
其三,切换逻辑很短但顺序讲究。核心就这一句取图:
const pattern = $(this).find("img").attr("src");色卡的预览图直接就是花纹的平铺图源,所以不需要额外维护一份映射表——你新增一颗色卡,只要放一张可无缝平铺的图,功能就自动生效。这种"数据即视图"的取巧,在小型演示里非常实用。
拿到源码后能改什么
换服装需要准备三张对齐的图:底图(纯色成衣)、遮罩图(衣身形状的黑白剪影)、阴影图(去色的明暗层)。三张图必须同尺寸同构图,这是效果成立的前提。准备好后替换路径,并微调花纹容器的宽度与偏移即可。
加花色就是加一颗按钮并放一张平铺图。注意两点:图案必须能四方连续无缝拼接,否则衣身上会看到明显的接缝;预览图的尺寸决定了花纹在衣服上的密度,同一张图放大会显得稀疏,缩小则更密。
色卡的弧形布局由变换原点与每颗的旋转角控制,两组分别在页面左上和右下。想改成直排或网格,把旋转规则删掉换成常规布局即可,功能不受影响。选中态是一圈红色描边,改颜色在悬停与选中的那条规则上。
运行提示:遮罩与混合模式在主流浏览器近年版本均已支持,部分旧版本需要带前缀的遮罩属性,源码中已同时写了两种写法。页面依赖 jQuery(从 CDN 加载),离线环境请先下载到本地。建议用本地服务器打开以避免个别浏览器对本地文件加载遮罩图的限制。详细运行方法请参见压缩包内的帮助文档。
关于服装花色预览的常见问题
能换成帽子、杯子、手机壳吗?
能。原理与商品品类无关,只要能提供底图、遮罩、阴影三张对齐的图就行。曲面商品(如杯子)建议在阴影层里把高光也保留下来,立体感会更强。
可以让用户上传自己的图案吗?
可以。把设置背景图的那一行改成读取用户选择的文件并生成本地地址即可。要注意上传的图通常不是无缝平铺的,可以改成单张居中显示而不是平铺。
手机上好用吗?
做了两档媒体查询:窄屏和矮屏下色卡会缩小、弧形半径收紧。触摸点击正常,只是色卡较小时建议再加大一点点击热区。
为什么我换了衣服图后花纹跑到外面去了?
说明遮罩图与底图没有对齐,或者花纹容器的宽度与偏移还是旧值。先确保三张图同尺寸导出,再按新衣服的实际占比调整那两个百分比。
它适合什么场景
最直接的是服装定制与周边商城的花色选择、印花预览、企业工服选样;也可以用在家纺(床品、窗帘)、箱包、文具等需要"同一款式多种花色"的商品页上。因为不依赖 3D 与服务端渲染,接进现有商城几乎零成本。遮罩裁形、混合模式叠影与切换过渡的完整写法都在源码里,下载后可查看。