The JS code to detect emojis (in the usual sense of the term "emoji") is simply:
let str = "...";
if(/\p{Extended_Pictographic}/u.test(str)) {
// do something
}
Is there some equivalently simple way to detect emojis that can have skin tone modifiers validly added to them?
A key requirement is that I don't have to update the regex over the years as more emojis are added, or existing emojis become skin-tone-able. Basically I'm wondering if there's something like a Skin Unicode property escape, or some other elegant and future-proof solution.
Notes:
πΆ (doesn't have skin tone modifier, but it is valid to add one to it).You can use Fitzpatrick scale to detect a skin-toned emoji. An emoji with a skin tone will contain any one of the six Fitzpatrick scale unicodes.
EDIT:
This solution uses Element.getBoundingClientRect() to determine whether an emoji will have the same width and height after having concatenated the Fitzpatrick skin tone emoji.
function isEmojiSkinToneAdaptable(emoji) {
const SKIN_TONES = [
'\u{1f3fb}', // skin tone 1 & 2
'\u{1f3fc}', // skin tone 3
'\u{1f3fd}', // skin tone 4
'\u{1f3fe}', // skin tone 5
'\u{1f3ff}', // skin tone 6
];
function getRemovedSkinToneEmoji(emoji) {
let emojiCopy = ' '.concat(emoji).slice(1);
SKIN_TONES.forEach(skinTone => {
emojiCopy = emojiCopy.replace(skinTone, '');
})
return emojiCopy;
}
function getEmojiRects(emoji) {
let span = document.createElement('span');
span.style.position = 'fixed';
span.style.top = '-99999px';
span.textContent = emoji;
document.body.append(span);
let emojiRects = span.getBoundingClientRect();
span.remove();
return emojiRects;
}
let baseEmoji = getRemovedSkinToneEmoji(emoji);
let skinToneEmoji = baseEmoji + SKIN_TONES[1];
let baseEmojiRects = getEmojiRects(baseEmoji);
let skinToneEmojiRects = getEmojiRects(skinToneEmoji);
return baseEmojiRects.width === skinToneEmojiRects.width
&& baseEmojiRects.height === skinToneEmojiRects.height;
}
console.log(`Human with skin tone: ${isEmojiSkinToneAdaptable('πΆπ½')}`); // true
console.log(`Thumbs up without skin tone: ${isEmojiSkinToneAdaptable('π')}`); // true
console.log(`Animal: ${isEmojiSkinToneAdaptable('π¦')}`); // false
The relevant Unicode character property is called Emoji_Modifier_Base. /\p{Emoji_Modifier_Base}/u.test() will return true for every emoji character that can take a skin tone modifier.