mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 00:36:41 +08:00
fix(glass): port material accents to v3 (#660)
This commit is contained in:
+41
-22
@@ -4,7 +4,8 @@ export { preloadCorsImage } from './corsImage'
|
||||
const DEFAULT_DOMINANT_COLOR = '#28A9E1'
|
||||
const DOMINANT_COLOR_CACHE_LIMIT = 100
|
||||
const colorThief = new ColorThief()
|
||||
const dominantColorCache = new Map<string, Promise<string>>()
|
||||
const dominantColorCache = new Map<string, string>()
|
||||
const pendingDominantColorRequests = new Map<string, Promise<string | undefined>>()
|
||||
|
||||
interface DominantColorOptions {
|
||||
fallback?: string
|
||||
@@ -29,42 +30,60 @@ function getImageCacheKey(image: HTMLImageElement) {
|
||||
return image.currentSrc || image.src || ''
|
||||
}
|
||||
|
||||
function rememberDominantColor(key: string, colorPromise: Promise<string>) {
|
||||
if (!key) return colorPromise
|
||||
function rememberDominantColor(key: string, color: string) {
|
||||
if (!key) return
|
||||
|
||||
if (dominantColorCache.size >= DOMINANT_COLOR_CACHE_LIMIT) {
|
||||
const firstKey = dominantColorCache.keys().next().value
|
||||
if (firstKey) dominantColorCache.delete(firstKey)
|
||||
}
|
||||
|
||||
dominantColorCache.set(key, colorPromise)
|
||||
dominantColorCache.set(key, color)
|
||||
}
|
||||
|
||||
/** 提取真实主色;失败不写入成功缓存,允许后续请求重试。 */
|
||||
export async function extractDominantColor(
|
||||
image: HTMLImageElement | undefined | null,
|
||||
options: Pick<DominantColorOptions, 'quality'> = {},
|
||||
): Promise<string | undefined> {
|
||||
if (!image) return undefined
|
||||
|
||||
const cacheKey = getImageCacheKey(image)
|
||||
const cachedColor = cacheKey ? dominantColorCache.get(cacheKey) : undefined
|
||||
if (cachedColor) return cachedColor
|
||||
|
||||
const pendingRequest = cacheKey ? pendingDominantColorRequests.get(cacheKey) : undefined
|
||||
if (pendingRequest) return pendingRequest
|
||||
|
||||
const colorPromise = Promise.resolve()
|
||||
.then(() => {
|
||||
const dominantColor = colorThief.getColor(image, options.quality ?? 20)
|
||||
const color = rgbStringToHex(dominantColor)
|
||||
rememberDominantColor(cacheKey, color)
|
||||
|
||||
return color
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('Failed to extract dominant color:', error)
|
||||
return undefined
|
||||
})
|
||||
.finally(() => {
|
||||
if (cacheKey) pendingDominantColorRequests.delete(cacheKey)
|
||||
})
|
||||
|
||||
if (cacheKey) pendingDominantColorRequests.set(cacheKey, colorPromise)
|
||||
|
||||
return colorPromise
|
||||
}
|
||||
|
||||
// 提取主要颜色
|
||||
/** 提取主色并在失败时解析调用方 fallback,保持既有调用合同。 */
|
||||
export async function getDominantColor(
|
||||
image: HTMLImageElement | undefined | null,
|
||||
options: DominantColorOptions = {},
|
||||
): Promise<string> {
|
||||
const fallback = options.fallback ?? DEFAULT_DOMINANT_COLOR
|
||||
|
||||
if (!image) return fallback
|
||||
|
||||
const cacheKey = getImageCacheKey(image)
|
||||
const cachedColor = cacheKey ? dominantColorCache.get(cacheKey) : undefined
|
||||
if (cachedColor) return cachedColor
|
||||
|
||||
const colorPromise = Promise.resolve()
|
||||
.then(() => {
|
||||
const dominantColor = colorThief.getColor(image, options.quality ?? 20)
|
||||
return rgbStringToHex(dominantColor)
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('Failed to extract dominant color:', error)
|
||||
return fallback
|
||||
})
|
||||
|
||||
return rememberDominantColor(cacheKey, colorPromise)
|
||||
return (await extractDominantColor(image, options)) ?? fallback
|
||||
}
|
||||
|
||||
// 预加载图片
|
||||
|
||||
Reference in New Issue
Block a user