Use individual images in emoji picker rather than a spritesheet
This commit is contained in:
parent
cc7b9da0cf
commit
dcf6a5f59c
5 changed files with 80 additions and 36 deletions
|
@ -276,8 +276,7 @@
|
|||
"!node_modules/emoji-datasource/emoji_pretty.json",
|
||||
"!node_modules/emoji-datasource/*.png",
|
||||
"!node_modules/emoji-datasource-apple/emoji_pretty.json",
|
||||
"!node_modules/emoji-datasource-apple/img/apple/{sheets,sheets-128}/*.png",
|
||||
"!node_modules/emoji-datasource-apple/img/apple/sheets-256/{16,20,32}.png",
|
||||
"!node_modules/emoji-datasource-apple/img/apple/sheets*",
|
||||
"!node_modules/spellchecker/vendor/hunspell/**/*",
|
||||
"!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme,test,__tests__,tests,powered-test,example,examples,*.d.ts}",
|
||||
"!**/node_modules/.bin",
|
||||
|
|
|
@ -4424,17 +4424,20 @@
|
|||
}
|
||||
|
||||
// Module: Emoji
|
||||
@mixin emoji-size($size, $emoji-sheet-columns: 52) {
|
||||
@mixin emoji-size($size) {
|
||||
&--#{$size} {
|
||||
width: $size;
|
||||
height: $size;
|
||||
background-size: $emoji-sheet-columns * $size;
|
||||
}
|
||||
&__image--#{$size} {
|
||||
width: $size;
|
||||
height: $size;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.module-emoji {
|
||||
display: block;
|
||||
background-image: url('../node_modules/emoji-datasource-apple/img/apple/sheets-256/64.png');
|
||||
|
||||
@include emoji-size(16px);
|
||||
@include emoji-size(20px);
|
||||
|
|
|
@ -28,12 +28,19 @@ function getImageTag({
|
|||
const result = getReplacementData(match[0], match[1], match[2]);
|
||||
|
||||
if (is.string(result)) {
|
||||
return <span key={key}>{match[0]}</span>;
|
||||
return match[0];
|
||||
}
|
||||
|
||||
const img = findImage(result.value, result.variation);
|
||||
const title = getTitle(result.value);
|
||||
|
||||
if (
|
||||
!img.path ||
|
||||
!img.path.startsWith('node_modules/emoji-datasource-apple')
|
||||
) {
|
||||
return match[0];
|
||||
}
|
||||
|
||||
return (
|
||||
// tslint:disable-next-line react-a11y-img-has-alt
|
||||
<img
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { getSheetCoordinates, SkinToneKey } from './lib';
|
||||
import { getImagePath, SkinToneKey } from './lib';
|
||||
|
||||
export type OwnProps = {
|
||||
inline?: boolean;
|
||||
|
@ -18,9 +18,7 @@ export const Emoji = React.memo(
|
|||
{ style = {}, size = 28, shortName, skinTone, inline, className }: Props,
|
||||
ref
|
||||
) => {
|
||||
const [sheetX, sheetY] = getSheetCoordinates(shortName, skinTone);
|
||||
const x = -(size * sheetX);
|
||||
const y = -(size * sheetY);
|
||||
const image = getImagePath(shortName, skinTone);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -31,12 +29,14 @@ export const Emoji = React.memo(
|
|||
inline ? 'module-emoji--inline' : null,
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
...style,
|
||||
backgroundPositionX: `${x}px`,
|
||||
backgroundPositionY: `${y}px`,
|
||||
}}
|
||||
/>
|
||||
style={style}
|
||||
>
|
||||
<img
|
||||
className={`module-emoji__image--${size}px`}
|
||||
src={image}
|
||||
alt={shortName}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
|
|
|
@ -18,6 +18,21 @@ export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
|||
|
||||
export type SkinToneKey = '1F3FB' | '1F3FC' | '1F3FD' | '1F3FE' | '1F3FF';
|
||||
|
||||
export type EmojiSkinVariation = {
|
||||
unified: string;
|
||||
non_qualified: null;
|
||||
image: string;
|
||||
sheet_x: number;
|
||||
sheet_y: number;
|
||||
added_in: string;
|
||||
has_img_apple: boolean;
|
||||
has_img_google: boolean;
|
||||
has_img_twitter: boolean;
|
||||
has_img_emojione: boolean;
|
||||
has_img_facebook: boolean;
|
||||
has_img_messenger: boolean;
|
||||
};
|
||||
|
||||
export type EmojiData = {
|
||||
name: string;
|
||||
unified: string;
|
||||
|
@ -43,24 +58,36 @@ export type EmojiData = {
|
|||
has_img_facebook: boolean;
|
||||
has_img_messenger: boolean;
|
||||
skin_variations?: {
|
||||
[key: string]: {
|
||||
unified: string;
|
||||
non_qualified: null;
|
||||
image: string;
|
||||
sheet_x: number;
|
||||
sheet_y: number;
|
||||
added_in: string;
|
||||
has_img_apple: boolean;
|
||||
has_img_google: boolean;
|
||||
has_img_twitter: boolean;
|
||||
has_img_emojione: boolean;
|
||||
has_img_facebook: boolean;
|
||||
has_img_messenger: boolean;
|
||||
};
|
||||
[key: string]: EmojiSkinVariation;
|
||||
};
|
||||
};
|
||||
|
||||
const data: Array<EmojiData> = untypedData;
|
||||
const data = (untypedData as Array<EmojiData>).filter(
|
||||
emoji => emoji.has_img_apple
|
||||
);
|
||||
|
||||
const makeImagePath = (src: string) => {
|
||||
return `node_modules/emoji-datasource-apple/img/apple/64/${src}`;
|
||||
};
|
||||
|
||||
export const images = new Set();
|
||||
|
||||
// Preload images
|
||||
const preload = (src: string) => {
|
||||
const img = new Image();
|
||||
img.src = src;
|
||||
images.add(img);
|
||||
};
|
||||
|
||||
data.forEach(emoji => {
|
||||
preload(makeImagePath(emoji.image));
|
||||
|
||||
if (emoji.skin_variations) {
|
||||
Object.values(emoji.skin_variations).forEach(variation => {
|
||||
preload(makeImagePath(variation.image));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const dataByShortName = keyBy(data, 'short_name');
|
||||
|
||||
|
@ -112,20 +139,28 @@ export const dataByCategory = mapValues(
|
|||
arr => sortBy(arr, 'sort_order')
|
||||
);
|
||||
|
||||
export function getSheetCoordinates(
|
||||
export function getEmojiData(
|
||||
shortName: keyof typeof dataByShortName,
|
||||
skinTone?: SkinToneKey | number
|
||||
): [number, number] {
|
||||
): EmojiData | EmojiSkinVariation {
|
||||
const base = dataByShortName[shortName];
|
||||
|
||||
if (skinTone && base.skin_variations) {
|
||||
const variation = isNumber(skinTone) ? skinTones[skinTone - 1] : skinTone;
|
||||
const { sheet_x, sheet_y } = base.skin_variations[variation];
|
||||
|
||||
return [sheet_x, sheet_y];
|
||||
return base.skin_variations[variation];
|
||||
}
|
||||
|
||||
return [base.sheet_x, base.sheet_y];
|
||||
return base;
|
||||
}
|
||||
|
||||
export function getImagePath(
|
||||
shortName: keyof typeof dataByShortName,
|
||||
skinTone?: SkinToneKey | number
|
||||
): string {
|
||||
const { image } = getEmojiData(shortName, skinTone);
|
||||
|
||||
return makeImagePath(image);
|
||||
}
|
||||
|
||||
const fuse = new Fuse(data, {
|
||||
|
|
Loading…
Add table
Reference in a new issue