feat: Kinetic Dark 设计语言 + Lucide 图标迁移 + 首页轻量个性化
- 建立 Lucide 子集 iconfont(49 字形),全站 emoji 替换为 fc-icon 组件 - 重塑 Design Token(冷中性近黑底 + Volt 荧光绿 #B6F24E),消除硬编码颜色 - 首页登录后个性化:我的计划 / 我的收藏 / 今日推荐(纯前端复用现有 API) - 后端 DEFAULT_EMOJI→Lucide 名,PALETTE 对齐 Kinetic Dark 语义色板 - 修复 person-standing 缺失字形;14 个官方组合 seed emoji 全部映射到现有字形
This commit is contained in:
@@ -1,17 +1,28 @@
|
||||
// 头像组件:纯 emoji 圆形头像(无二进制图片)。
|
||||
// props: avatar(emoji 字符串), size(rpx, 默认 120), bg(背景色, 默认 gold-soft)
|
||||
const { iconName } = require('../../utils/icon-name');
|
||||
|
||||
// 头像组件:圆形 Lucide 图标头像(无二进制图片)。
|
||||
// props: avatar(lucide 图标名 或 历史 emoji), size(rpx, 默认 120), bg(背景色)
|
||||
Component({
|
||||
properties: {
|
||||
avatar: { type: String, value: '💪' },
|
||||
avatar: { type: String, value: 'user' },
|
||||
size: { type: Number, value: 120 },
|
||||
bg: { type: String, value: 'rgba(217,179,108,0.12)' }
|
||||
bg: { type: String, value: 'rgba(182,242,78,0.12)' }
|
||||
},
|
||||
data: {
|
||||
fontSize: 60
|
||||
glyph: 'user',
|
||||
iconSize: 60
|
||||
},
|
||||
observers: {
|
||||
size: function (size) {
|
||||
this.setData({ fontSize: Math.round(size * 0.5) });
|
||||
avatar(v) {
|
||||
this.setData({ glyph: iconName(v, 'user') });
|
||||
},
|
||||
size(s) {
|
||||
this.setData({ iconSize: Math.round(s * 0.5) });
|
||||
}
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.setData({ glyph: iconName(this.data.avatar, 'user'), iconSize: Math.round(this.data.size * 0.5) });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
"usingComponents": {
|
||||
"fc-icon": "/components/fc-icon/index"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<view
|
||||
class="avatar"
|
||||
style="width: {{size}}rpx; height: {{size}}rpx; background: {{bg}}; font-size: {{fontSize}}rpx;">
|
||||
{{avatar || '💪'}}
|
||||
style="width: {{size}}rpx; height: {{size}}rpx; background: {{bg}};">
|
||||
<fc-icon name="{{glyph}}" size="{{iconSize}}" color="var(--accent)" />
|
||||
</view>
|
||||
|
||||
@@ -4,10 +4,10 @@ Component({
|
||||
},
|
||||
data: {
|
||||
items: [
|
||||
{ key: 'home', label: '首页', emoji: '🏠', page: '/pages/index/index' },
|
||||
{ key: 'category', label: '分类', emoji: '📚', page: '/pages/category/category' },
|
||||
{ key: 'plans', label: '计划', emoji: '📋', page: '/pages/my-plans/my-plans' },
|
||||
{ key: 'mine', label: '我的', emoji: '👤', page: '/pages/profile/profile' }
|
||||
{ key: 'home', label: '首页', icon: 'home', page: '/pages/index/index' },
|
||||
{ key: 'category', label: '分类', icon: 'layout-grid', page: '/pages/category/category' },
|
||||
{ key: 'plans', label: '计划', icon: 'clipboard-list', page: '/pages/my-plans/my-plans' },
|
||||
{ key: 'mine', label: '我的', icon: 'user', page: '/pages/profile/profile' }
|
||||
]
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
"usingComponents": {
|
||||
"fc-icon": "/components/fc-icon/index"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class="bn__item {{active === item.key ? 'bn__item--active' : ''}}"
|
||||
data-page="{{item.page}}"
|
||||
bindtap="onTap">
|
||||
<text class="bn__emoji">{{item.emoji}}</text>
|
||||
<fc-icon name="{{item.icon}}" size="40" color="{{active === item.key ? 'var(--accent)' : 'var(--text-3)'}}" />
|
||||
<text class="bn__label">{{item.label}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
background: linear-gradient(90deg, var(--gold), var(--gold-2));
|
||||
}
|
||||
.bn__item--active { color: var(--gold); }
|
||||
.bn__emoji { font-size: 40rpx; line-height: 1; }
|
||||
.bn__emoji { line-height: 1; }
|
||||
.bn__label { font-size: 22rpx; margin-top: 6rpx; }
|
||||
.bn__item--active .bn__label { color: var(--gold-2); }
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
"usingComponents": {
|
||||
"fc-icon": "/components/fc-icon/index"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
mode="aspectFill"
|
||||
lazy-load="true"
|
||||
binderror="onImgError" />
|
||||
<view wx:else class="ex-card__ph">🏋️</view>
|
||||
<view wx:else class="ex-card__ph"><fc-icon name="dumbbell" size="64" color="var(--text-3)" /></view>
|
||||
<view wx:if="{{exercise.typeLabel}}" class="ex-card__type">{{exercise.typeLabel}}</view>
|
||||
<view wx:if="{{score > 0}}" class="ex-card__score">匹配 {{score}}</view>
|
||||
</view>
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
.ex-card__type {
|
||||
position: absolute; left: 12rpx; top: 12rpx;
|
||||
font-size: 20rpx; color: var(--text-2);
|
||||
background: rgba(0,0,0,0.45); padding: 4rpx 14rpx; border-radius: 999rpx;
|
||||
background: var(--scrim); padding: 4rpx 14rpx; border-radius: 999rpx;
|
||||
}
|
||||
.ex-card__score {
|
||||
position: absolute; right: 12rpx; top: 12rpx;
|
||||
font-size: 20rpx; color: #0E1110; font-weight: 700;
|
||||
font-size: 20rpx; color: var(--accent-on); font-weight: 700;
|
||||
background: var(--gold); padding: 4rpx 14rpx; border-radius: 999rpx;
|
||||
}
|
||||
.ex-card__body { padding: 16rpx 18rpx 20rpx; }
|
||||
|
||||
23
miniprogram/components/fc-icon/index.js
Normal file
23
miniprogram/components/fc-icon/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const iconMap = require('../../utils/icon-map');
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
// Lucide 图标名,如 search / dumbbell / heart
|
||||
name: { type: String, value: '' },
|
||||
// 字号(rpx)
|
||||
size: { type: Number, value: 20 },
|
||||
// 颜色,默认跟随当前文字色(currentColor 在 iconfont 下用具体色)
|
||||
color: { type: String, value: '' },
|
||||
},
|
||||
data: { glyph: '' },
|
||||
observers: {
|
||||
name(n) {
|
||||
this.setData({ glyph: (iconMap[n] || '') });
|
||||
},
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.setData({ glyph: (iconMap[this.data.name] || '') });
|
||||
},
|
||||
},
|
||||
});
|
||||
4
miniprogram/components/fc-icon/index.json
Normal file
4
miniprogram/components/fc-icon/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
1
miniprogram/components/fc-icon/index.wxml
Normal file
1
miniprogram/components/fc-icon/index.wxml
Normal file
@@ -0,0 +1 @@
|
||||
<text class="fc-icon" style="font-size:{{size}}rpx;{{color ? 'color:' + color + ';' : ''}}">{{glyph}}</text>
|
||||
10
miniprogram/components/fc-icon/index.wxss
Normal file
10
miniprogram/components/fc-icon/index.wxss
Normal file
@@ -0,0 +1,10 @@
|
||||
.fc-icon {
|
||||
font-family: "fc-icon";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
.gif-loading__dot {
|
||||
width: 18rpx; height: 18rpx; border-radius: 999rpx;
|
||||
background: var(--gold, #c9a24b);
|
||||
background: var(--accent);
|
||||
animation: gif-pulse 1s ease-in-out infinite;
|
||||
}
|
||||
.gif-loading__txt {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.navbar {
|
||||
background: linear-gradient(180deg, rgba(22,32,27,0.96) 0%, rgba(14,17,16,0.55) 100%);
|
||||
background: linear-gradient(180deg, var(--bar-bg) 0%, var(--float-bg) 100%);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
|
||||
Reference in New Issue
Block a user