
如何制作不规则进度条
问题描述:
-
给定一个水塔的svg图像,需要实现如下效果:
- 水面根据进度上升或下降
- 进度低于20%时显示红色,其余显示绿色
- 尺寸根据父布局大小动态调整
思路:
方案 1:切图法
将水塔图像根据进度切成 10 张图片,然后根据进度动态显示。
优点: 简单直观。
缺点:
- 增加包体积。
- 对于复杂的图像,切图可能比较粗糙。
方案 2:蒙版法
使用两张svg图像,将上面的水塔用clip-path根据进度切除。
优点:
- 可以实现精确的进度控制。
- 无需切图,对包体积没有影响。
缺点:
- svg的path是固定的,无法实现动态尺寸调整。
解决思路:
小程序不支持直接操作svg的path路径,但可以读取svg文件,查找替换高度和颜色部位的值,再转为 base64 加载到小程序中。
代码实现:
// 读取svg文件
const fs = require('fs');
const svg = fs.readFileSync('water_tower.svg', 'utf-8');
// 获取进度
const progress = 50;
// 查找替换高度
const heightRegex = /height="([0-9]+)"/;
const newHeight = progress * 104 / 100;
const heightMatch = svg.match(heightRegex);
if (heightMatch) {
svg = svg.replace(heightRegex, `height="${newHeight}"`);
}
// 查找替换颜色
const colorRegex = /fill="#([0-9a-f]+)"/;
const colorMatch = svg.match(colorRegex);
let color;
if (colorMatch) {
if (progress < 20) {
color = '#FF0000';
} else {
color = '#06CB60';
}
svg = svg.replace(colorRegex, `fill="${color}"`);
}
// 转换base64
const base64 = Buffer.from(svg).toString('base64');
// 加载到小程序中
wx.createSelectorQuery().select('#my-svg').fields({
properties: ['src'],
computedStyle: [],
context: this
}).exec((res) => {
this.setData({
'my-svg-src': `data:image/svg+xml;base64,${base64}`
})
});效果:
水塔水面会根据进度动态调整高度和颜色,整体尺寸也会随着父布局大小变化而调整。










