225 lines
17 KiB
JavaScript
225 lines
17 KiB
JavaScript
// 临时生成脚本:20 款底部导航图标方案(发房=新增加号)(勿提交)
|
||
const fs = require('fs');
|
||
const path = 'js/data/sources/';
|
||
global.window = {};
|
||
|
||
const RED = '#FF6700';
|
||
const GRAY = '#999999';
|
||
|
||
function load(sid) { eval(fs.readFileSync(path + sid + '.js', 'utf8')); return window['HGB_Source_' + sid]; }
|
||
function findIcon(data, ref) {
|
||
const namePart = ref.includes(':') ? ref.split(':')[1] : ref;
|
||
return (data.icons || []).find(i => i.id === ref || i.name === namePart) || null;
|
||
}
|
||
|
||
// style: native(path用currentColor) / fill(根fill) / stroke(根stroke) / color(自带颜色)
|
||
const SOURCES = {
|
||
fluent: { style: 'native' },
|
||
'material-symbols': { style: 'native' },
|
||
remix: { style: 'fill' },
|
||
lucide: { style: 'stroke' },
|
||
ionicons: { style: 'fill' },
|
||
mingcute: { style: 'native' },
|
||
tabler: { style: 'stroke' },
|
||
phosphor: { style: 'native' },
|
||
carbon: { style: 'native' },
|
||
boxicons: { style: 'fill' },
|
||
heroicons: { style: 'fill' },
|
||
feather: { style: 'stroke' },
|
||
twemoji: { style: 'color' },
|
||
emojione: { style: 'color' },
|
||
'fluent-emoji': { style: 'color' },
|
||
'fluent-color': { style: 'color' },
|
||
'flat-color-icons': { style: 'color' },
|
||
pixelarticons: { style: 'native' },
|
||
'icon-park': { style: 'color' },
|
||
openmoji: { style: 'color' }
|
||
};
|
||
|
||
function renderSVG(ic, style, color) {
|
||
let attrs = 'xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"';
|
||
if (style === 'stroke') attrs += ' fill="none" stroke="' + color + '" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"';
|
||
else if (style === 'fill') attrs += ' fill="' + color + '"';
|
||
else if (style === 'native') attrs += ' style="color:' + color + '"';
|
||
return '<svg ' + attrs + '>' + ic.svg + '</svg>';
|
||
}
|
||
|
||
const M = (label, n, a) => ({ label, n, a });
|
||
|
||
const SOLUTIONS = [
|
||
{ key:'01', title:'Fluent 微软圆润', desc:'微软现代风格,描边/实心双态', source:'fluent', pub:'fluent:add-circle-24-filled',
|
||
items:[M('首页','fluent:apps-24-regular','fluent:apps-24-filled'),M('租房','fluent:building-24-regular','fluent:building-24-filled'),M('消息','fluent:chat-24-regular','fluent:chat-24-filled'),M('我的','fluent:person-24-regular','fluent:person-24-filled')] },
|
||
{ key:'02', title:'Material Symbols 谷歌', desc:'Material Design,圆角厚重实心', source:'material-symbols', pub:'material-symbols:add-circle-rounded',
|
||
items:[M('首页','material-symbols:apps-outline-rounded','material-symbols:apps-rounded'),M('租房','material-symbols:apartment-outline-rounded','material-symbols:apartment-rounded'),M('消息','material-symbols:chat-outline-rounded','material-symbols:chat-rounded'),M('我的','material-symbols:person-outline-rounded','material-symbols:person-rounded')] },
|
||
{ key:'03', title:'Remix 锐克思', desc:'国内产品最常用,线条/实心双态', source:'remix', pub:'remix:add-circle-fill',
|
||
items:[M('首页','remix:dashboard-line','remix:dashboard-fill'),M('租房','remix:building-4-line','remix:building-4-fill'),M('消息','remix:message-3-line','remix:message-3-fill'),M('我的','remix:user-3-line','remix:user-3-fill')] },
|
||
{ key:'04', title:'Lucide 轻细线条', desc:'精致细线条,极简优雅', source:'lucide', pub:'lucide:circle-plus',
|
||
items:[M('首页','lucide:layout-dashboard','lucide:layout-dashboard'),M('租房','lucide:building-2','lucide:building-2'),M('消息','lucide:message-square','lucide:message-square'),M('我的','lucide:user','lucide:user')] },
|
||
{ key:'05', title:'Ionicons iOS 经典', desc:'iOS 同源,实心/描边双态', source:'ionicons', pub:'ionicons:add-circle',
|
||
items:[M('首页','ionicons:grid-outline','ionicons:grid'),M('租房','ionicons:business-outline','ionicons:business'),M('消息','ionicons:chatbox-ellipses-outline','ionicons:chatbox-ellipses'),M('我的','ionicons:person-outline','ionicons:person')] },
|
||
{ key:'06', title:'Mingcute 圆润可爱', desc:'圆头线条/实心双态,年轻活泼', source:'mingcute', pub:'mingcute:add-circle-fill',
|
||
items:[M('首页','mingcute:layout-grid-line','mingcute:layout-grid-fill'),M('租房','mingcute:building-1-line','mingcute:building-1-fill'),M('消息','mingcute:chat-1-line','mingcute:chat-1-fill'),M('我的','mingcute:user-3-line','mingcute:user-3-fill')] },
|
||
{ key:'07', title:'Tabler 现代线条', desc:'通用线条图标,简洁清晰', source:'tabler', pub:'tabler:circle-plus',
|
||
items:[M('首页','tabler:layout-dashboard','tabler:layout-dashboard'),M('租房','tabler:building-community','tabler:building-community'),M('消息','tabler:message-2','tabler:message-2'),M('我的','tabler:user','tabler:user')] },
|
||
{ key:'08', title:'Phosphor 多权重', desc:'可调粗细,四宫格/楼宇双态', source:'phosphor', pub:'phosphor:plus-circle-fill',
|
||
items:[M('首页','phosphor:squares-four','phosphor:squares-four-fill'),M('租房','phosphor:buildings','phosphor:buildings-fill'),M('消息','phosphor:chat','phosphor:chat-fill'),M('我的','phosphor:user','phosphor:user-fill')] },
|
||
{ key:'09', title:'Carbon IBM', desc:'IBM 设计语言,沉稳规范', source:'carbon', pub:'carbon:add-filled',
|
||
items:[M('首页','carbon:dashboard','carbon:dashboard'),M('租房','carbon:building','carbon:building'),M('消息','carbon:chat','carbon:chat'),M('我的','carbon:user','carbon:user')] },
|
||
{ key:'10', title:'Boxicons 简洁', desc:'经典简洁,圆润饱满', source:'boxicons', pub:'boxicons:bx-plus-circle',
|
||
items:[M('首页','boxicons:bx-grid-alt','boxicons:bx-grid-alt'),M('租房','boxicons:bx-buildings','boxicons:bx-buildings'),M('消息','boxicons:bx-chat','boxicons:bx-chat'),M('我的','boxicons:bx-user','boxicons:bx-user')] },
|
||
{ key:'11', title:'Heroicons Tailwind', desc:'Tailwind 官方,粗实心醒目', source:'heroicons', pub:'heroicons:plus-solid',
|
||
items:[M('首页','heroicons:squares-2x2-solid','heroicons:squares-2x2-solid'),M('租房','heroicons:building-office-solid','heroicons:building-office-solid'),M('消息','heroicons:chat-bubble-left-right-solid','heroicons:chat-bubble-left-right-solid'),M('我的','heroicons:user-solid','heroicons:user-solid')] },
|
||
{ key:'12', title:'Feather 轻盈线条', desc:'经典极简线条,干净利落', source:'feather', pub:'feather:plus-circle',
|
||
items:[M('首页','feather:grid','feather:grid'),M('租房','feather:home','feather:home'),M('消息','feather:message-square','feather:message-square'),M('我的','feather:user','feather:user')] },
|
||
{ key:'13', title:'Twemoji 多彩扁平', desc:'Twitter 同款扁平表情,彩色生动', source:'twemoji', pub:'twemoji:plus',
|
||
items:[M('首页','twemoji:bar-chart','twemoji:bar-chart'),M('租房','twemoji:office-building','twemoji:office-building'),M('消息','twemoji:speech-balloon','twemoji:speech-balloon'),M('我的','twemoji:bust-in-silhouette','twemoji:bust-in-silhouette')] },
|
||
{ key:'14', title:'EmojiOne 3D 立体', desc:'3D 渲染表情,立体质感色彩饱和', source:'emojione', pub:'emojione:heavy-plus-sign',
|
||
items:[M('首页','emojione:bar-chart','emojione:bar-chart'),M('租房','emojione:office-building','emojione:office-building'),M('消息','emojione:speech-balloon','emojione:speech-balloon'),M('我的','emojione:bust-in-silhouette','emojione:bust-in-silhouette')] },
|
||
{ key:'15', title:'Fluent Emoji 微软 3D', desc:'微软 Fluent 3D,圆润软萌', source:'fluent-emoji', pub:'fluent-emoji:plus',
|
||
items:[M('首页','fluent-emoji:bar-chart','fluent-emoji:bar-chart'),M('租房','fluent-emoji:office-building','fluent-emoji:office-building'),M('消息','fluent-emoji:speech-balloon','fluent-emoji:speech-balloon'),M('我的','fluent-emoji:bust-in-silhouette','fluent-emoji:bust-in-silhouette')] },
|
||
{ key:'16', title:'Fluent Color 彩色微软', desc:'微软彩色描边,蓝紫渐变', source:'fluent-color', pub:'fluent-color:add-circle-24',
|
||
items:[M('首页','fluent-color:board-24','fluent-color:board-24'),M('租房','fluent-color:building-24','fluent-color:building-24'),M('消息','fluent-color:chat-24','fluent-color:chat-24'),M('我的','fluent-color:person-24','fluent-color:person-24')] },
|
||
{ key:'17', title:'Flat Color 多彩玻璃', desc:'半透明玻璃质感,多彩扁平', source:'flat-color-icons', pub:'flat-color-icons:plus',
|
||
items:[M('首页','flat-color-icons:grid','flat-color-icons:grid'),M('租房','flat-color-icons:home','flat-color-icons:home'),M('消息','flat-color-icons:comments','flat-color-icons:comments'),M('我的','flat-color-icons:businessman','flat-color-icons:businessman')] },
|
||
{ key:'18', title:'Pixel 像素风', desc:'8-bit 像素,个性醒目', source:'pixelarticons', pub:'pixelarticons:add-box',
|
||
items:[M('首页','pixelarticons:grid','pixelarticons:grid'),M('租房','pixelarticons:building','pixelarticons:building'),M('消息','pixelarticons:message','pixelarticons:message'),M('我的','pixelarticons:user','pixelarticons:user')] },
|
||
{ key:'19', title:'Icon Park 双色', desc:'字节跳动,蓝黑双色描边', source:'icon-park', pub:'icon-park:add-one',
|
||
items:[M('首页','icon-park:dashboard','icon-park:dashboard'),M('租房','icon-park:building-two','icon-park:building-two'),M('消息','icon-park:message','icon-park:message'),M('我的','icon-park:user','icon-park:user')] },
|
||
{ key:'20', title:'OpenMoji 开源表情', desc:'开源 emoji,扁平简洁', source:'openmoji', pub:'openmoji:plus',
|
||
items:[M('首页','openmoji:bar-chart','openmoji:bar-chart'),M('租房','openmoji:office-building','openmoji:office-building'),M('消息','openmoji:speech-balloon','openmoji:speech-balloon'),M('我的','openmoji:bust-in-silhouette','openmoji:bust-in-silhouette')] }
|
||
];
|
||
|
||
const dataCache = {};
|
||
for (const sid of Object.keys(SOURCES)) {
|
||
try { dataCache[sid] = load(sid); } catch (e) { console.error('加载失败 ' + sid); process.exit(1); }
|
||
}
|
||
|
||
let cards = '';
|
||
const missList = [];
|
||
|
||
function pubBtn(sol) {
|
||
const style = SOURCES[sol.source].style;
|
||
const ic = findIcon(dataCache[sol.source], sol.pub);
|
||
if (!ic) {
|
||
missList.push(sol.pub);
|
||
return { normal: '<div class="plus gray"><span>+</span></div>', active: '<div class="plus"><span>+</span></div>' };
|
||
}
|
||
if (style === 'color') {
|
||
return {
|
||
normal: '<div class="plus-colored gray">' + renderSVG(ic, 'color', '') + '</div>',
|
||
active: '<div class="plus-colored">' + renderSVG(ic, 'color', '') + '</div>'
|
||
};
|
||
}
|
||
return {
|
||
normal: '<div class="plus gray">' + renderSVG(ic, style, '#ffffff') + '</div>',
|
||
active: '<div class="plus">' + renderSVG(ic, style, '#ffffff') + '</div>'
|
||
};
|
||
}
|
||
|
||
for (const sol of SOLUTIONS) {
|
||
const style = SOURCES[sol.source].style;
|
||
const isColor = style === 'color';
|
||
const res = [];
|
||
for (const it of sol.items) {
|
||
const nIc = findIcon(dataCache[sol.source], it.n);
|
||
const aIc = findIcon(dataCache[sol.source], it.a);
|
||
if (!nIc) missList.push(it.n);
|
||
if (!aIc) missList.push(it.a);
|
||
res.push({ label: it.label, normal: nIc ? renderSVG(nIc, style, GRAY) : '', active: aIc ? renderSVG(aIc, style, RED) : '' });
|
||
}
|
||
const plus = pubBtn(sol);
|
||
const icCls = (r, active) => {
|
||
if (isColor) return `<div class="ic${active ? '' : ' gray'}">${active ? r.active : r.normal}</div>`;
|
||
return `<div class="ic${active ? ' active' : ''}">${active ? r.active : r.normal}</div>`;
|
||
};
|
||
const arr = [res[0], res[1], null, res[2], res[3]];
|
||
const barNormal = `<div class="tabbar">${arr.map(r => r
|
||
? `<div class="tabitem">${icCls(r, false)}<div class="lb">${r.label}</div></div>`
|
||
: `<div class="tabitem"><div class="ic">${plus.active}</div><div class="lb">发房</div></div>`).join('')}</div>`;
|
||
const barActive = `<div class="tabbar">${arr.map((r, i) => r
|
||
? `<div class="tabitem${i === 0 ? ' active' : ''}">${icCls(r, i === 0)}<div class="lb">${r.label}</div></div>`
|
||
: `<div class="tabitem"><div class="ic">${plus.active}</div><div class="lb">发房</div></div>`).join('')}</div>`;
|
||
const strip = res.map(r => `<div class="state-cell">
|
||
<div class="state-ic${isColor ? ' gray' : ''}">${r.normal}</div><div class="state-lb">${r.label}·未选</div>
|
||
<div class="state-ic${isColor ? '' : ' active'}">${r.active}</div><div class="state-lb${isColor ? '' : ' active'}">${r.label}·选中</div>
|
||
</div>`).join('') +
|
||
`<div class="state-cell">
|
||
<div class="state-ic">${plus.normal}</div><div class="state-lb">发房·未选</div>
|
||
<div class="state-ic">${plus.active}</div><div class="state-lb active">发房·选中</div>
|
||
</div>`;
|
||
cards += `
|
||
<div class="card">
|
||
<div class="card-head">
|
||
<div class="card-title"><span class="tag">方案 ${sol.key}</span>${sol.title}</div>
|
||
<div class="card-desc">${sol.desc}</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="mock-wrap">
|
||
<div class="mock-col"><div class="mock-title">常规态(全部未选)</div><div class="phone">${barNormal}</div></div>
|
||
<div class="mock-col"><div class="mock-title">选中态(首页高亮)</div><div class="phone">${barActive}</div></div>
|
||
</div>
|
||
<div class="state-strip">${strip}</div>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
const html = `<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>小虎租房 · 底部导航图标方案(20 款)</title>
|
||
<style>
|
||
* { margin:0; padding:0; box-sizing:border-box; }
|
||
body { font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif; background:#f5f5f7; color:#333; padding:36px 28px 80px; }
|
||
h1 { font-size:24px; margin-bottom:6px; }
|
||
.sub { color:#888; font-size:13px; margin-bottom:10px; }
|
||
.legend { font-size:12px; color:#aaa; margin-bottom:30px; line-height:1.7; }
|
||
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(560px,1fr)); gap:24px; }
|
||
.card { background:#fff; border-radius:16px; padding:22px 24px; box-shadow:0 1px 4px rgba(0,0,0,.06); }
|
||
.card-head { margin-bottom:16px; }
|
||
.card-title { font-size:17px; font-weight:700; display:flex; align-items:center; gap:10px; }
|
||
.tag { display:inline-block; background:#FF6700; color:#fff; font-size:12px; font-weight:600; border-radius:6px; padding:2px 8px; }
|
||
.card-desc { font-size:12px; color:#999; margin-top:6px; }
|
||
.card-body { display:flex; flex-wrap:wrap; gap:20px; align-items:flex-start; }
|
||
.mock-wrap { display:flex; gap:16px; }
|
||
.mock-col { text-align:center; }
|
||
.mock-title { font-size:11px; color:#999; margin-bottom:8px; }
|
||
.phone { width:270px; border-radius:18px; border:6px solid #222; background:#fff; overflow:hidden; }
|
||
.phone::before { content:""; display:block; height:6px; }
|
||
.tabbar { display:flex; height:52px; background:#fff; border-top:1px solid #f0f0f0; }
|
||
.tabitem { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; }
|
||
.tabitem .ic { width:23px; height:23px; color:#999; display:flex; align-items:center; justify-content:center; }
|
||
.tabitem .ic svg { width:23px; height:23px; display:block; }
|
||
.tabitem .ic.active { color:#FF6700; }
|
||
.tabitem .lb { font-size:10px; color:#999; line-height:14px; }
|
||
.tabitem.active .lb { color:#FF6700; }
|
||
.gray { filter:grayscale(1); opacity:.62; }
|
||
.plus { width:25px; height:25px; border-radius:50%; background:linear-gradient(135deg,#ff8a00,#FF6700); box-shadow:0 1px 3px rgba(255,103,0,.3); display:flex; align-items:center; justify-content:center; color:#fff; }
|
||
.plus svg { width:17px; height:17px; display:block; }
|
||
.plus-colored { width:32px; height:32px; margin-top:-3px; margin-left:-4px; filter:drop-shadow(0 2px 4px rgba(0,0,0,.18)); }
|
||
.plus-colored svg { width:32px; height:32px; display:block; }
|
||
.state-strip { display:flex; gap:14px; flex-wrap:wrap; }
|
||
.state-cell { display:flex; flex-direction:column; align-items:center; gap:5px; background:#fafafa; border:1px solid #f0f0f0; border-radius:12px; padding:10px 8px; min-width:70px; }
|
||
.state-ic { width:26px; height:26px; color:#999; display:flex; align-items:center; justify-content:center; }
|
||
.state-ic svg { width:26px; height:26px; display:block; }
|
||
.state-ic.active { color:#FF6700; }
|
||
.state-ic .plus, .state-ic .plus-colored { margin:0; }
|
||
.state-lb { font-size:10px; color:#aaa; }
|
||
.state-lb.active { color:#FF6700; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>小虎租房 · 底部导航图标方案(20 款)</h1>
|
||
<div class="sub">数据来自「画个标」内置图标库 · 未选中 #999999 / 选中 ${RED}(小米橙)· 菜单:首页=工作台、租房=楼宇、发房=新增、消息、我的</div>
|
||
<div class="legend">「发房」= 新增(加号)语义:单色方案为橙圆内置白色加号,彩色方案为大号彩色加号。彩色方案未选置灰、选中全彩;单色方案未选灰、选中橙。每卡含常规态 + 首页选中态两个手机框,以及 5 菜单双态对比格(含发房)。</div>
|
||
<div class="grid">
|
||
${cards}
|
||
</div>
|
||
</body>
|
||
</html>`;
|
||
|
||
fs.writeFileSync('D:/SGP_KF3/ruyizu_web/docs/tabbar-icons.html', html, 'utf8');
|
||
if (missList.length) console.log('缺失图标(' + missList.length + '): ' + missList.join(', '));
|
||
else console.log('OK,已生成 docs/tabbar-icons.html(' + SOLUTIONS.length + ' 款方案,全部图标命中)');
|