Files
frontend/src/utils/imageHelper.ts

102 lines
2.5 KiB
TypeScript
Raw Normal View History

/**
*
* 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';
}