mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import { useMemo, useRef, useState } from 'react';
|
|
|
|
interface Props {
|
|
width: number;
|
|
height: number;
|
|
emoji: string;
|
|
}
|
|
|
|
const fontSizeCache_: Record<string, number> = {};
|
|
|
|
export default (props: Props) => {
|
|
const containerRef = useRef(null);
|
|
const [containerReady, setContainerReady] = useState(false);
|
|
|
|
const fontSize = useMemo(() => {
|
|
if (!containerReady) return props.height;
|
|
|
|
const cacheKey = [props.width, props.height, props.emoji].join('-');
|
|
if (fontSizeCache_[cacheKey]) {
|
|
return fontSizeCache_[cacheKey];
|
|
}
|
|
|
|
// Set the emoji font size so that it fits within the specified width
|
|
// and height. In fact, currently it only looks at the height.
|
|
|
|
let spanFontSize = props.height;
|
|
|
|
const span = document.createElement('span');
|
|
span.innerText = props.emoji;
|
|
span.style.fontSize = `${spanFontSize}px`;
|
|
containerRef.current.appendChild(span);
|
|
|
|
let rect = span.getBoundingClientRect();
|
|
|
|
while (rect.height > props.height) {
|
|
spanFontSize -= .5;
|
|
span.style.fontSize = `${spanFontSize}px`;
|
|
rect = span.getBoundingClientRect();
|
|
}
|
|
|
|
span.remove();
|
|
|
|
fontSizeCache_[cacheKey] = spanFontSize;
|
|
return spanFontSize;
|
|
}, [props.width, props.height, props.emoji, containerReady, containerRef]);
|
|
|
|
return <div className="emoji-box" ref={el => { containerRef.current = el; setContainerReady(true); }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: props.width, height: props.height, fontSize }}>{props.emoji}</div>;
|
|
};
|