Files
frontend/src/utils/imageHelper.ts
lan 592167e667 feat: 优化图片加载和展示功能
- 新增 SmartImage 组件优化图片加载体验
- 新增 ImageGrid 组件支持多图布局展示
- 新增 imageHelper 工具函数
- 优化 PostCard 帖子卡片图片展示
- 优化消息页面 SegmentRenderer
- 优化日程页面 ScheduleScreen
- 优化上传服务 uploadService
2026-03-15 02:25:55 +08:00

102 lines
2.5 KiB
TypeScript
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.
/**
* 图片工具函数
* 提供图片 URL 选择、格式检测等实用功能
*/
import { PostImageDTO } from '../types';
/**
* 图片显示模式
*/
export type ImageDisplayMode = 'list' | 'grid' | 'detail';
/**
* 根据显示模式获取预览图 URL
* @param image 图片对象
* @param mode 显示模式
* @returns 图片 URL
*/
export function getPreviewImageUrl(image: PostImageDTO, mode: ImageDisplayMode): string {
// 如果没有预览图,返回原图
if (!image) {
return '';
}
switch (mode) {
case 'list':
case 'grid':
// 列表和网格模式使用普通预览图
return image.preview_url || image.url || '';
case 'detail':
// 详情页使用大预览图
return image.preview_url_large || image.preview_url || image.url || '';
default:
return image.url || '';
}
}
/**
* 检测 WebP 支持并构建 Accept header
* @returns Accept header 字符串
*/
export function getImageAcceptHeader(): string {
// 检测浏览器是否支持 WebP
// 如果支持,优先请求 WebP
return 'image/webp,image/apng,image/*,*/*;q=0.8';
}
/**
* 判断是否应该使用预览图
* @param mode 显示模式
* @param hasPreview 是否有预览图
* @returns 是否使用预览图
*/
export function shouldUsePreview(mode: ImageDisplayMode, hasPreview: boolean): boolean {
// 列表和网格模式优先使用预览图
if (mode === 'list' || mode === 'grid') {
return hasPreview;
}
// 详情页也使用预览图,但点击后加载原图
if (mode === 'detail') {
return hasPreview;
}
return false;
}
/**
* 从图片 URL 提取文件扩展名
* @param url 图片 URL
* @returns 文件扩展名(如 '.jpg'
*/
export function getImageExtension(url: string): string {
if (!url) return '';
try {
const urlObj = new URL(url);
const pathname = urlObj.pathname;
const ext = pathname.match(/\.[0-9a-z]+$/i);
return ext ? ext[0].toLowerCase() : '';
} catch {
// 如果 URL 解析失败,直接从字符串匹配
const match = url.match(/\.[0-9a-z]+$/i);
return match ? match[0].toLowerCase() : '';
}
}
/**
* 判断是否是 GIF 图片
* @param url 图片 URL
* @returns 是否是 GIF
*/
export function isGifImage(url: string): boolean {
return getImageExtension(url) === '.gif';
}
/**
* 判断是否是 WebP 图片
* @param url 图片 URL
* @returns 是否是 WebP
*/
export function isWebPImage(url: string): boolean {
return getImageExtension(url) === '.webp';
}