Files
jiang13-bbs/frontend/lib/responsiveImage.ts
freefire ff2ab286fb feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等
新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
2026-10-01 03:06:05 +08:00

53 lines
2.0 KiB
TypeScript
Raw Permalink 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.
// 自适应图片:统一生成后端变体地址(GET /api/img?u=&w=)。
// 宽度白名单与后端 backend/service/image_variants.go 同值,约 1.5x 步进。
// 源内容不可变(随机哈希文件名),变体可被浏览器/CDN 长期 immutable 缓存。
/** 宽度白名单(48~1920) */
export const VARIANT_WIDTHS = [48, 96, 160, 256, 384, 512, 768, 1080, 1536, 1920] as const;
/**
* pickVariantWidth 选「≥ 需求」的最小白名单档(保证清晰度);
* 需求超过最大档时回落最大档(源图不够大时后端会原样透传,不会放大)。
*/
export function pickVariantWidth(cssPx: number, dpr = 1): number {
const need = Math.max(1, Math.round(cssPx * dpr));
for (const w of VARIANT_WIDTHS) {
if (w >= need) return w;
}
return VARIANT_WIDTHS[VARIANT_WIDTHS.length - 1];
}
/** variantURL 指定宽度的变体地址 */
export function variantURL(src: string, w: number): string {
return `/api/img?u=${encodeURIComponent(src)}&w=${w}`;
}
/** isOwnImage 是否本站图片(/uploads 本地文件或 /api/media 对象),只有本站图能走变体端点 */
export function isOwnImage(src: string): boolean {
return src.startsWith("/uploads/") || src.startsWith("/api/media/");
}
/**
* densitySrcSet 固定尺寸位的密度 srcset(如头像、固定广告位):
* 返回 "url 1x, url 2x";不同 DPR 选中同档时自动去重。
*/
export function densitySrcSet(src: string, cssPx: number, dprs: number[] = [1, 2]): string {
const seen = new Set<number>();
const parts: string[] = [];
for (const dpr of dprs) {
const w = pickVariantWidth(cssPx, dpr);
if (seen.has(w)) continue;
seen.add(w);
parts.push(`${variantURL(src, w)} ${dpr}x`);
}
return parts.join(", ");
}
/**
* widthSrcSet 可变宽度位的宽度 srcset(如封面、正文图),配合 sizes 使用。
* widths 请直接传白名单档位。
*/
export function widthSrcSet(src: string, widths: readonly number[]): string {
return widths.map((w) => `${variantURL(src, w)} ${w}w`).join(", ");
}