40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
import { colors } from 'quasar'
|
|
|
|
function getColorWithOpacity(
|
|
color: string,
|
|
background: string = '#ffffff',
|
|
alpha: number = 0.8
|
|
): string {
|
|
const clampedAlpha = Math.max(0.01, Math.min(1, alpha))
|
|
|
|
const hexColor = color.startsWith('#') ? color : colors.getPaletteColor(color)
|
|
const hexBackground = background.startsWith('#') ? background : colors.getPaletteColor(background)
|
|
|
|
if (!hexColor || !hexColor.startsWith('#') || !hexBackground || !hexBackground.startsWith('#')) {
|
|
return color
|
|
}
|
|
|
|
const { r: rColor, g: gColor, b: bColor } = colors.hexToRgb(hexColor)
|
|
const { r: rBg, g: gBg, b: bBg } = colors.hexToRgb(hexBackground)
|
|
|
|
const calculateTargetChannel = (colorChannel: number, bgChannel: number): number => {
|
|
const target = (colorChannel - bgChannel * (1 - clampedAlpha)) / clampedAlpha
|
|
return Math.max(0, Math.min(255, Math.round(target)))
|
|
}
|
|
|
|
const targetChannels = [
|
|
calculateTargetChannel(rColor, rBg),
|
|
calculateTargetChannel(gColor, gBg),
|
|
calculateTargetChannel(bColor, bBg)
|
|
]
|
|
|
|
if (targetChannels.every(channel => channel === 0)) {
|
|
return `rgba(${rColor}, ${gColor}, ${bColor}, ${clampedAlpha})`
|
|
}
|
|
|
|
return `rgba(${targetChannels.join(', ')}, ${clampedAlpha})`
|
|
}
|
|
|
|
export {
|
|
getColorWithOpacity
|
|
} |