Files
fitness-coach/miniprogram/components/fc-icon/index.js
wm a0894837bd ux: 动作收藏按钮从顶部浮窗移到底部,与加入计划并排 + 图标美化
- detail 顶部 favbtn 浮窗(需避让胶囊、丑)移除,改为底部 addbar 内与 CTA 并排的方形按钮
- fc-icon 新增 filled 属性:收藏态实心心形(Lucide 描边图标默认 fill=none,filled=true 时 fill=stroke 变实心)
- 收藏按钮美化:圆角 24rpx 方形 + 发丝边框,未收藏描边(text-2)、已收藏实心(accent)+ accent-soft 底色 + accent-ring 边框 + 点按 scale 反馈
- detail.js 清理 favRight/favTop 胶囊避让逻辑(不再需要)
2026-07-22 23:25:17 +08:00

60 lines
2.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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: '' },
// 是否实心填充(如收藏后实心心形)。默认描边
filled: { type: Boolean, value: false },
},
data: { src: '' },
observers: {
name() { this._build(); },
color() { this._build(); },
filled() { this._build(); },
},
lifetimes: {
attached() { this._build(); },
},
methods: {
_build() {
const { name, color, filled } = this.data;
const inner = iconSvg[name];
if (!inner) { this.setData({ src: '' }); return; }
const stroke = resolveColor(color);
const fill = filled ? stroke : 'none';
const body = inner.replace(/__C__/g, stroke);
const svg =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="' + fill + '" ' +
'stroke="' + stroke + '" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
body + '</svg>';
this.setData({ src: 'data:image/svg+xml,' + encodeURIComponent(svg) });
},
},
});