Created
July 5, 2020 06:03
-
-
Save flpms/ea41319c723a22d68a77550c2a00a33b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
const getPercent = (percent, value) => | |
(value * percent) / 100; | |
const colorTypes = new Map([ | |
['r', 'rgb'], | |
['#', 'hex'], | |
['h', 'hsla'] | |
]); | |
const getColorType = color => colorTypes.get(color[0]); | |
const getArrayValuesFromString = color => | |
color.replace(/\W/gi, '').split(''); | |
const reverseHexShort = color => | |
color.reduce((acc, num) => { | |
acc.push(num); | |
acc.push(num); | |
return acc; | |
}, []); | |
const transformHexValues = color => | |
color.reduce((acc, value, index) => { | |
if (!(index % 2)) return acc; | |
const decimalValue = | |
parseInt(`${color[index - 1]}${value}`, 16); | |
return (acc.push(decimalValue), acc); | |
}, []); | |
const convertColorHexToRGBArray = color => { | |
let normalizedHexColor; | |
const hexColorArray = getArrayValuesFromString(color); | |
if (hexColorArray.length <= 4) { | |
normalizedHexColor = reverseHexShort(hexColorArray); | |
} | |
return transformHexValues(normalizedHexColor || hexColorArray); | |
} | |
const isOpacityTransparent = opacity => { | |
if (!opacity) return false; | |
let opacityValue = opacity; | |
if (Math.floor(opacity) === 0) { | |
opacityValue = Math.floor(opacity * 254); | |
} | |
return opacityValue > 70; | |
} | |
const getContrastRatio = rgbColorArray => Math.round(( | |
(parseInt(rgbColorArray[0]) * 299) + | |
(parseInt(rgbColorArray[1]) * 587) + | |
(parseInt(rgbColorArray[2]) * 114) | |
) / 1000); | |
const getTextColor = color => { | |
let rgbColorArray; | |
const colorType = getColorType(color); | |
if (!colorType || colorType === 'hsla') { | |
console.warn(new Error(`Unssuported color: | |
if you are using a hsla color, is not supported due contrast ratio. | |
also be careful with gradient background not suported by svgs. | |
`)); | |
return 'black'; | |
} | |
if (colorType === 'hex') { | |
rgbColorArray = convertColorHexToRGBArray(color); | |
} | |
if (colorType === 'rgb') { | |
rgbColorArray = color.replace(/((rgb|a)|(\(|\)))/g, '') | |
.split(',') | |
.map(str => +str.trim()); | |
} | |
if (isOpacityTransparent(rgbColorArray[3])) { | |
return 'black'; | |
} | |
return (getContrastRatio(rgbColorArray) > 128) ? 'black' : 'white'; | |
} | |
export default props => { | |
const size = getPercent(48, props.size); | |
const textColor = getTextColor(props.bgColor); | |
return ( | |
<svg height={props.size} width={props.size}> | |
<circle cx={size} cy={size} r={size} fill={props.bgColor} /> | |
<text | |
fontFamily="Arial, Helvetica, sans-serif" | |
fontSize={size} | |
textAnchor="middle" | |
fill={textColor || props.textColor} | |
x={size} | |
y={getPercent(66, props.size)} | |
> | |
{props.children} | |
</text> | |
</svg> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment