- 微信小程序 <text> 对 @font-face 自定义字体支持不可靠(开发者工具/真机均可能不渲染),图标回退成字符 - 改用 <image> 渲染 Lucide SVG 矢量图(data:image/svg+xml),彻底绕开字体加载限制,矢量/可上色 - 新增 utils/icon-svg.js(49 图标内层 SVG,stroke/fill 用 __C__ 占位),fc-icon 按 color 动态拼色 - 内置设计 token→色值映射,调用方传 var(--xxx) 自动解析为具体色值 - 移除 app.wxss 中已无用的 @font-face(字体方案废弃)
55 lines
1.9 KiB
JavaScript
55 lines
1.9 KiB
JavaScript
const iconSvg = require('../../utils/icon-svg');
|
||
|
||
// 设计 token 色值映射:调用方常传 var(--xxx),但 SVG data URI 内无法解析 CSS 变量,需转成具体色值
|
||
const CSS_VARS = {
|
||
'--accent': '#B6F24E',
|
||
'--accent-hover': '#C7F56E',
|
||
'--accent-active': '#9EDB3A',
|
||
'--text': '#ECF1EF',
|
||
'--text-2': '#9BA7A1',
|
||
'--text-3': '#6B7670',
|
||
'--danger': '#FF5C5C',
|
||
'--success': '#2BD9A6',
|
||
'--warn': '#F2B53D',
|
||
'--info': '#4FA8FF',
|
||
};
|
||
function resolveColor(c) {
|
||
if (!c) return '#ECF1EF';
|
||
const m = /^var\((--[\w-]+)\)$/.exec(String(c).trim());
|
||
if (m) return CSS_VARS[m[1]] || '#ECF1EF';
|
||
return c; // 已是具体色值(hex)
|
||
}
|
||
|
||
// 用 <image> 渲染 Lucide SVG 矢量图(微信小程序 <text> 自定义字体不可靠,改用此方案 100% 稳定)
|
||
Component({
|
||
properties: {
|
||
// Lucide 图标名,如 search / dumbbell / heart
|
||
name: { type: String, value: '' },
|
||
// 字号(rpx),同时作为图标宽高
|
||
size: { type: Number, value: 20 },
|
||
// 颜色:可传具体 hex,或 var(--xxx)(自动解析为对应 token 色值)
|
||
color: { type: String, value: '' },
|
||
},
|
||
data: { src: '' },
|
||
observers: {
|
||
name(n) { this._build(n, this.data.color); },
|
||
color(c) { this._build(this.data.name, c); },
|
||
},
|
||
lifetimes: {
|
||
attached() { this._build(this.data.name, this.data.color); },
|
||
},
|
||
methods: {
|
||
_build(name, color) {
|
||
const inner = iconSvg[name];
|
||
if (!inner) { this.setData({ src: '' }); return; }
|
||
const stroke = resolveColor(color);
|
||
const body = inner.replace(/__C__/g, stroke);
|
||
const svg =
|
||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" ' +
|
||
'stroke="' + stroke + '" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
|
||
body + '</svg>';
|
||
this.setData({ src: 'data:image/svg+xml,' + encodeURIComponent(svg) });
|
||
},
|
||
},
|
||
});
|