feat: 龙里小程序第一次上传
This commit is contained in:
commit
f23d598328
59 files changed
+11482
No files matched your search
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 图标生成脚本:微信小程序不支持内联 <svg>,因此把初设图里的 SVG symbol
|
||||
* 编译成 WXSS 的 background-image(base64 data-uri),按「名称 + 色调」生成类名。
|
||||
*
|
||||
* 用法:node scripts/build-icons.mjs
|
||||
* 产出:src/styles/icons.scss
|
||||
*/
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const ROOT = path.resolve(import.meta.dirname, "..");
|
||||
const OUT = path.join(ROOT, "src/styles/icons.scss");
|
||||
|
||||
/** 颜色 token(与 design-token.scss 保持一致) */
|
||||
const TONES = {
|
||||
ink: "#14181C",
|
||||
ink2: "#6B7280",
|
||||
ink3: "#9CA3AF",
|
||||
white: "#FFFFFF",
|
||||
brand: "#00B578",
|
||||
brandDeep: "#009A67",
|
||||
accent: "#FF8A3D",
|
||||
danger: "#E5484D",
|
||||
};
|
||||
|
||||
/** stroke 型图标:24×24 线性图标,stroke-width 1.9 */
|
||||
const STROKE_ICONS = {
|
||||
pin: '<path d="M12 21s7-6.1 7-11a7 7 0 1 0-14 0c0 4.9 7 11 7 11z"/><circle cx="12" cy="10" r="2.4"/>',
|
||||
arrow: '<path d="M4.5 12h15"/><path d="M13.5 6l6 6-6 6"/>',
|
||||
chev: '<path d="M9.5 5.5 16 12l-6.5 6.5"/>',
|
||||
back: '<path d="M14.5 5.5 8 12l6.5 6.5"/>',
|
||||
phone:
|
||||
'<path d="M4.2 4.4h3.9l1.9 4.8-2.4 1.5a12.2 12.2 0 0 0 5.8 5.8l1.5-2.4 4.8 1.9v3.9a1 1 0 0 1-1.1 1A16.8 16.8 0 0 1 3.2 5.5a1 1 0 0 1 1-1.1z"/>',
|
||||
copy: '<rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15.5V5.5a1.5 1.5 0 0 1 1.5-1.5h10"/>',
|
||||
gift: '<path d="M20 12v8.5H4V12"/><path d="M2.5 7.5h19V12h-19z"/><path d="M12 7.5v13"/><path d="M12 7.5H8.6a2.3 2.3 0 1 1 0-4.6C11.6 2.9 12 7.5 12 7.5z"/><path d="M12 7.5h3.4a2.3 2.3 0 1 0 0-4.6C12.4 2.9 12 7.5 12 7.5z"/>',
|
||||
home: '<path d="M4 11.2 12 4.4l8 6.8v8.3a1 1 0 0 1-1 1h-4.2v-6H9.2v6H5a1 1 0 0 1-1-1z"/>',
|
||||
ticket:
|
||||
'<path d="M3.5 9.6a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v1.2a1.4 1.4 0 0 0 0 2.8v1.2a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2v-1.2a1.4 1.4 0 0 0 0-2.8z"/><path d="M13.6 7.6v2M13.6 13v2"/>',
|
||||
user: '<circle cx="12" cy="8.2" r="3.9"/><path d="M4.6 20.6a7.4 7.4 0 0 1 14.8 0"/>',
|
||||
check: '<path d="M5.5 12.6 10 17l8.5-9"/>',
|
||||
close: '<path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/>',
|
||||
doc: '<path d="M6.5 3.5h7.5l4.5 4.5v12.5h-12z"/><path d="M14 3.5V8h4.5"/><path d="M9 13h6M9 16.5h4.5"/>',
|
||||
shield: '<path d="M12 3.5 19.5 6v5.6c0 4.6-3.6 7.6-7.5 8.9-3.9-1.3-7.5-4.3-7.5-8.9V6z"/><path d="M9.2 12.2l2.2 2.2 3.6-3.6"/>',
|
||||
info: '<circle cx="12" cy="12" r="8.6"/><path d="M12 11v5.2"/><path d="M12 7.8h.01"/>',
|
||||
headset:
|
||||
'<path d="M4.5 15v-3a7.5 7.5 0 0 1 15 0v3"/><path d="M4.5 13.6h2.2v5H5.6a1.1 1.1 0 0 1-1.1-1.1z"/><path d="M19.5 13.6h-2.2v5h1.1a1.1 1.1 0 0 0 1.1-1.1z"/><path d="M17.3 18.6v.6a2 2 0 0 1-2 2h-2.8"/>',
|
||||
logout: '<path d="M15 12H4"/><path d="M11.4 8.4 15 12l-3.6 3.6"/><path d="M15.5 4.5h3a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-3"/>',
|
||||
trash:
|
||||
'<path d="M4.5 7h15"/><path d="M9.5 7V4.8h5V7"/><path d="M6.5 7l.9 13h9.2l.9-13"/><path d="M10.5 10.5v6M13.5 10.5v6"/>',
|
||||
share:
|
||||
'<path d="M12 16V3.8"/><path d="M8.2 7.6 12 3.8l3.8 3.8"/><path d="M5 13.6V19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-5.4"/>',
|
||||
clock: '<circle cx="12" cy="12" r="8.6"/><path d="M12 7.4v4.8l3.2 1.9"/>',
|
||||
map: '<path d="M9 4.5 3.5 6.6v13L9 17.4l6 2.1 5.5-2.1v-13L15 6.6z"/><path d="M9 4.5v12.9M15 6.6v12.9"/>',
|
||||
food: '<path d="M6.6 3.6v5M9.4 3.6v5"/><path d="M8 3.6v16.8"/><path d="M6.6 8.6h2.8"/><path d="M16.4 3.6c1.7 0 2.8 1.3 2.8 3.1 0 1.9-1.1 3.1-2.8 3.1s-2.8-1.2-2.8-3.1c0-1.8 1.1-3.1 2.8-3.1z"/><path d="M16.4 9.8v10.6"/>',
|
||||
bed: '<path d="M3.6 18.6V6.4"/><path d="M3.6 15h16.8v3.6"/><path d="M20.4 15v-2.6a1.6 1.6 0 0 0-1.6-1.6h-7V15"/><circle cx="7.6" cy="12.1" r="1.7"/>',
|
||||
peak: '<path d="M2.8 19.2 9 8.4l3.6 6.2 2.2-3.4 6.4 8z"/>',
|
||||
people:
|
||||
'<circle cx="9.2" cy="8.4" r="3.2"/><path d="M3.6 19.4a5.6 5.6 0 0 1 11.2 0"/><path d="M15.8 5.6a3.2 3.2 0 0 1 0 6"/><path d="M17.4 14.8a5.6 5.6 0 0 1 3 4.6"/>',
|
||||
};
|
||||
|
||||
/** fill 型图标(实心) */
|
||||
const FILL_ICONS = {
|
||||
wx: '<path d="M8.9 3.4C5.2 3.4 2.2 5.9 2.2 9c0 1.8 1 3.4 2.6 4.4l-.7 2.4 2.8-1.4c.6.2 1.3.3 2 .3h.5a5.4 5.4 0 0 1-.2-1.5c0-3 3-5.3 6.8-5.3h.5C16 5.3 12.7 3.4 8.9 3.4z"/><path d="M15.9 8.8c-3.4 0-6.1 2-6.1 4.4 0 1.5.9 2.8 2.3 3.6l-.6 1.9 2.3-1.1c.5.1 1.1.2 1.6.2 3.4 0 6.1-2 6.1-4.6s-2.7-4.4-5.6-4.4z"/>',
|
||||
};
|
||||
|
||||
/** 需要生成的「图标 × 色调」组合(只生成用得到的,控制体积) */
|
||||
const MATRIX = {
|
||||
pin: ["ink3", "brand", "white"],
|
||||
arrow: ["white", "brandDeep", "ink"],
|
||||
chev: ["ink3", "white", "brand", "ink2"],
|
||||
back: ["ink", "white", "brand"],
|
||||
phone: ["white", "brandDeep"],
|
||||
copy: ["brandDeep", "brand"],
|
||||
gift: ["white", "brandDeep", "accent"],
|
||||
home: ["ink3", "brand"],
|
||||
ticket: ["ink3", "brand", "accent", "white", "ink2"],
|
||||
user: ["ink3", "brand", "white", "ink2"],
|
||||
check: ["white", "brand"],
|
||||
close: ["ink3", "white"],
|
||||
doc: ["ink2", "brand"],
|
||||
shield: ["ink2", "white", "brand"],
|
||||
info: ["ink2", "brand"],
|
||||
headset: ["ink2", "brand"],
|
||||
logout: ["ink2", "white"],
|
||||
trash: ["ink2", "danger"],
|
||||
share: ["white"],
|
||||
clock: ["brand", "ink3", "white"],
|
||||
map: ["brandDeep", "white"],
|
||||
food: ["brandDeep", "accent", "white", "brand"],
|
||||
bed: ["accent", "brand", "white", "brandDeep"],
|
||||
peak: ["accent", "brand", "white"],
|
||||
people: ["ink3", "brand", "white", "brandDeep"],
|
||||
wx: ["white"],
|
||||
};
|
||||
|
||||
const buildSvg = (name, body, color, type) => {
|
||||
const style =
|
||||
type === "fill"
|
||||
? `fill='${color}' stroke='none'`
|
||||
: `fill='none' stroke='${color}' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'`;
|
||||
return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' ${style}>${body}</svg>`;
|
||||
};
|
||||
|
||||
const toDataUri = (svg) => `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`;
|
||||
|
||||
const lines = [
|
||||
"/* 由 scripts/build-icons.mjs 生成,请勿手改 */",
|
||||
"",
|
||||
".ai{display:block;flex:none;background-repeat:no-repeat;background-position:center;background-size:100% 100%}",
|
||||
"",
|
||||
];
|
||||
|
||||
let count = 0;
|
||||
for (const [name, tones] of Object.entries(MATRIX)) {
|
||||
const type = FILL_ICONS[name] ? "fill" : "stroke";
|
||||
const body = FILL_ICONS[name] || STROKE_ICONS[name];
|
||||
if (!body) throw new Error(`未定义的图标:${name}`);
|
||||
for (const tone of tones) {
|
||||
const color = TONES[tone];
|
||||
if (!color) throw new Error(`未定义的色调:${tone}`);
|
||||
if (type === "stroke") {
|
||||
// stroke 型图标 stroke-width 随字号缩放会变细,统一用 1.9
|
||||
}
|
||||
const uri = toDataUri(buildSvg(name, body, color, type));
|
||||
lines.push(`.ai-${name}.t-${tone}{background-image:url("${uri}")}`);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
lines.push("");
|
||||
fs.writeFileSync(OUT, lines.join("\n"), "utf8");
|
||||
const kb = (fs.statSync(OUT).size / 1024).toFixed(1);
|
||||
console.log(`icons.scss 已生成:${count} 条规则 / ${kb} KB`);
|
||||
Reference in new issue
Block a user