mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(guild): fit text icon initials to the icon by measured width (#3310)
This commit is contained in:
1 parent
89fa895a0a
commit
abfaff16c2
8 files changed
+100
-48
No files matched your search
@@ -206,6 +206,7 @@
|
|||||||
color 70ms ease-out;
|
color 70ms ease-out;
|
||||||
container-type: size;
|
container-type: size;
|
||||||
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
||||||
|
--initials-fit-inline-size: 92cqi;
|
||||||
--initials-letter-spacing: 0px;
|
--initials-letter-spacing: 0px;
|
||||||
--initials-scale: 1;
|
--initials-scale: 1;
|
||||||
}
|
}
|
||||||
@@ -259,7 +260,10 @@
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: var(--initials-font-size);
|
font-size: min(
|
||||||
|
var(--initials-font-size),
|
||||||
|
calc(var(--initials-fit-inline-size) / (var(--initials-width-em, 0.01) * var(--initials-scale)))
|
||||||
|
);
|
||||||
letter-spacing: var(--initials-letter-spacing);
|
letter-spacing: var(--initials-letter-spacing);
|
||||||
transform: scale(var(--initials-scale));
|
transform: scale(var(--initials-scale));
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
@@ -271,12 +275,6 @@
|
|||||||
--initials-scale: 0.92;
|
--initials-scale: 0.92;
|
||||||
}
|
}
|
||||||
|
|
||||||
.guildIcon[data-initials-length='long'] .guildIconInitials {
|
|
||||||
--initials-font-size: clamp(0.85rem, 32cqi, 0.87rem);
|
|
||||||
--initials-letter-spacing: 0px;
|
|
||||||
--initials-scale: 0.78;
|
|
||||||
}
|
|
||||||
|
|
||||||
.guildIndicator {
|
.guildIndicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: var(--guild-list-indicator-inset);
|
left: var(--guild-list-indicator-inset);
|
||||||
|
|||||||
+8
-6
@@ -14,6 +14,7 @@ import Guilds from '@app/features/guild/state/Guilds';
|
|||||||
import {
|
import {
|
||||||
type GuildInitialsLength,
|
type GuildInitialsLength,
|
||||||
getGuildIconDisplayInitials,
|
getGuildIconDisplayInitials,
|
||||||
|
getGuildInitialsFitStyle,
|
||||||
getInitialsFromName,
|
getInitialsFromName,
|
||||||
getInitialsLength,
|
getInitialsLength,
|
||||||
truncateInitials,
|
truncateInitials,
|
||||||
@@ -57,11 +58,11 @@ function resolveGuildListItemMotion(useReducedMotion: boolean): GuildListItemMot
|
|||||||
return STANDARD_GUILD_LIST_ITEM_MOTION;
|
return STANDARD_GUILD_LIST_ITEM_MOTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveInitialsLength(rawInitials: string): GuildInitialsLength | null {
|
function resolveInitialsLength(displayInitials: string): GuildInitialsLength | null {
|
||||||
if (rawInitials.length === 0) {
|
if (displayInitials.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getInitialsLength(rawInitials);
|
return getInitialsLength(displayInitials);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveDraggingCursor(dragAndDrop: GuildListItemDragAndDrop | null): 'grabbing' | null {
|
function resolveDraggingCursor(dragAndDrop: GuildListItemDragAndDrop | null): 'grabbing' | null {
|
||||||
@@ -303,8 +304,8 @@ export const GuildListItemPresentation = forwardRef<
|
|||||||
forwardedRef,
|
forwardedRef,
|
||||||
) {
|
) {
|
||||||
const rootRef = useMergeRefs([surfaceRef, forwardedRef]);
|
const rootRef = useMergeRefs([surfaceRef, forwardedRef]);
|
||||||
const rawInitials = getInitialsFromName(guild.name);
|
const displayInitials = getGuildIconDisplayInitials(getInitialsFromName(guild.name));
|
||||||
const initialsLength = resolveInitialsLength(rawInitials);
|
const initialsLength = resolveInitialsLength(displayInitials);
|
||||||
const dropIndicator = resolveDropIndicator(dragAndDrop);
|
const dropIndicator = resolveDropIndicator(dragAndDrop);
|
||||||
const motion = resolveGuildListItemMotion(Accessibility.useReducedMotion);
|
const motion = resolveGuildListItemMotion(Accessibility.useReducedMotion);
|
||||||
const draggingCursor = resolveDraggingCursor(dragAndDrop);
|
const draggingCursor = resolveDraggingCursor(dragAndDrop);
|
||||||
@@ -378,9 +379,10 @@ export const GuildListItemPresentation = forwardRef<
|
|||||||
{!hasPaintedIcon && (
|
{!hasPaintedIcon && (
|
||||||
<span
|
<span
|
||||||
className={styles.guildIconInitials}
|
className={styles.guildIconInitials}
|
||||||
|
style={getGuildInitialsFitStyle(displayInitials)}
|
||||||
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon-initials"
|
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon-initials"
|
||||||
>
|
>
|
||||||
{getGuildIconDisplayInitials(rawInitials)}
|
{displayInitials}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</GuildListItemIcon>
|
</GuildListItemIcon>
|
||||||
|
|||||||
@@ -133,6 +133,7 @@
|
|||||||
background: var(--background-tertiary);
|
background: var(--background-tertiary);
|
||||||
container-type: size;
|
container-type: size;
|
||||||
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
||||||
|
--initials-fit-inline-size: 92cqi;
|
||||||
--initials-letter-spacing: 0px;
|
--initials-letter-spacing: 0px;
|
||||||
--initials-scale: 1;
|
--initials-scale: 1;
|
||||||
}
|
}
|
||||||
@@ -146,7 +147,10 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--initials-font-size);
|
font-size: min(
|
||||||
|
var(--initials-font-size),
|
||||||
|
calc(var(--initials-fit-inline-size) / (var(--initials-width-em, 0.01) * var(--initials-scale)))
|
||||||
|
);
|
||||||
letter-spacing: var(--initials-letter-spacing);
|
letter-spacing: var(--initials-letter-spacing);
|
||||||
transform: scale(var(--initials-scale));
|
transform: scale(var(--initials-scale));
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
@@ -158,12 +162,6 @@
|
|||||||
--initials-scale: 0.92;
|
--initials-scale: 0.92;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconPlaceholder[data-initials-length='long'] .iconInitials {
|
|
||||||
--initials-font-size: clamp(0.85rem, 32cqi, 0.87rem);
|
|
||||||
--initials-letter-spacing: 0px;
|
|
||||||
--initials-scale: 0.78;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconActions {
|
.iconActions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ import {
|
|||||||
ICON_FILE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR,
|
ICON_FILE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR,
|
||||||
ModalFooterContext,
|
ModalFooterContext,
|
||||||
} from '@app/features/guild/components/modals/add_guild_modal/shared';
|
} from '@app/features/guild/components/modals/add_guild_modal/shared';
|
||||||
import {getGuildIconDisplayInitials, getInitialsLength} from '@app/features/guild/utils/GuildInitialsUtils';
|
import {
|
||||||
|
getGuildIconDisplayInitials,
|
||||||
|
getGuildInitialsFitStyle,
|
||||||
|
getInitialsLength,
|
||||||
|
} from '@app/features/guild/utils/GuildInitialsUtils';
|
||||||
import {
|
import {
|
||||||
CREATE_COMMUNITY_DESCRIPTOR,
|
CREATE_COMMUNITY_DESCRIPTOR,
|
||||||
FAILED_TO_PROCESS_CROPPED_IMAGE_DESCRIPTOR,
|
FAILED_TO_PROCESS_CROPPED_IMAGE_DESCRIPTOR,
|
||||||
@@ -75,13 +79,12 @@ export const GuildCreateForm = observer(() => {
|
|||||||
const currentUser = Users.currentUser;
|
const currentUser = Users.currentUser;
|
||||||
const shouldRequireClaimedAccount = currentUser != null && !currentUser.isClaimed();
|
const shouldRequireClaimedAccount = currentUser != null && !currentUser.isClaimed();
|
||||||
const nameValue = form.watch('name');
|
const nameValue = form.watch('name');
|
||||||
const rawInitials = useMemo(() => {
|
const initials = useMemo(() => {
|
||||||
const raw = (nameValue || '').trim();
|
const raw = (nameValue || '').trim();
|
||||||
if (!raw) return '';
|
if (!raw) return '';
|
||||||
return StringUtils.getInitialsFromName(raw);
|
return getGuildIconDisplayInitials(StringUtils.getInitialsFromName(raw));
|
||||||
}, [nameValue]);
|
}, [nameValue]);
|
||||||
const initials = useMemo(() => getGuildIconDisplayInitials(rawInitials), [rawInitials]);
|
const initialsLength = initials ? getInitialsLength(initials) : null;
|
||||||
const initialsLength = useMemo(() => (rawInitials ? getInitialsLength(rawInitials) : null), [rawInitials]);
|
|
||||||
const showIconUploadErrorModal = useCallback(
|
const showIconUploadErrorModal = useCallback(
|
||||||
(message: string) => {
|
(message: string) => {
|
||||||
showGuildErrorModal({
|
showGuildErrorModal({
|
||||||
@@ -289,6 +292,7 @@ export const GuildCreateForm = observer(() => {
|
|||||||
{initials ? (
|
{initials ? (
|
||||||
<span
|
<span
|
||||||
className={styles.iconInitials}
|
className={styles.iconInitials}
|
||||||
|
style={getGuildInitialsFitStyle(initials)}
|
||||||
data-flx="guild.add-guild-modal.guild-create-form.icon-initials"
|
data-flx="guild.add-guild-modal.guild-create-form.icon-initials"
|
||||||
>
|
>
|
||||||
{initials}
|
{initials}
|
||||||
|
|||||||
+9
-5
@@ -44,7 +44,11 @@ import {
|
|||||||
type TemplateJsonFormInputs,
|
type TemplateJsonFormInputs,
|
||||||
THIS_DOESN_T_LOOK_LIKE_A_VALID_TEMPLATE_DESCRIPTOR,
|
THIS_DOESN_T_LOOK_LIKE_A_VALID_TEMPLATE_DESCRIPTOR,
|
||||||
} from '@app/features/guild/components/modals/add_guild_modal/shared';
|
} from '@app/features/guild/components/modals/add_guild_modal/shared';
|
||||||
import {getGuildIconDisplayInitials, getInitialsLength} from '@app/features/guild/utils/GuildInitialsUtils';
|
import {
|
||||||
|
getGuildIconDisplayInitials,
|
||||||
|
getGuildInitialsFitStyle,
|
||||||
|
getInitialsLength,
|
||||||
|
} from '@app/features/guild/utils/GuildInitialsUtils';
|
||||||
import {
|
import {
|
||||||
CREATE_COMMUNITY_DESCRIPTOR,
|
CREATE_COMMUNITY_DESCRIPTOR,
|
||||||
FAILED_TO_PROCESS_CROPPED_IMAGE_DESCRIPTOR,
|
FAILED_TO_PROCESS_CROPPED_IMAGE_DESCRIPTOR,
|
||||||
@@ -245,13 +249,12 @@ export const TemplateImportForm = observer(() => {
|
|||||||
const nameValue = createForm.watch('name');
|
const nameValue = createForm.watch('name');
|
||||||
const urlValue = urlForm.watch('url');
|
const urlValue = urlForm.watch('url');
|
||||||
const jsonValue = jsonForm.watch('json');
|
const jsonValue = jsonForm.watch('json');
|
||||||
const rawInitials = useMemo(() => {
|
const initials = useMemo(() => {
|
||||||
const raw = (nameValue || '').trim();
|
const raw = (nameValue || '').trim();
|
||||||
if (!raw) return '';
|
if (!raw) return '';
|
||||||
return StringUtils.getInitialsFromName(raw);
|
return getGuildIconDisplayInitials(StringUtils.getInitialsFromName(raw));
|
||||||
}, [nameValue]);
|
}, [nameValue]);
|
||||||
const initials = useMemo(() => getGuildIconDisplayInitials(rawInitials), [rawInitials]);
|
const initialsLength = initials ? getInitialsLength(initials) : null;
|
||||||
const initialsLength = useMemo(() => (rawInitials ? getInitialsLength(rawInitials) : null), [rawInitials]);
|
|
||||||
const showIconUploadErrorModal = useCallback(
|
const showIconUploadErrorModal = useCallback(
|
||||||
(message: string) => {
|
(message: string) => {
|
||||||
showGuildErrorModal({
|
showGuildErrorModal({
|
||||||
@@ -612,6 +615,7 @@ export const TemplateImportForm = observer(() => {
|
|||||||
{initials ? (
|
{initials ? (
|
||||||
<span
|
<span
|
||||||
className={styles.iconInitials}
|
className={styles.iconInitials}
|
||||||
|
style={getGuildInitialsFitStyle(initials)}
|
||||||
data-flx="guild.add-guild-modal.template-import-form.icon-initials"
|
data-flx="guild.add-guild-modal.template-import-form.icon-initials"
|
||||||
>
|
>
|
||||||
{initials}
|
{initials}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
--initials-font-size: clamp(0.85rem, 45cqi, 1.35rem);
|
||||||
|
--initials-fit-inline-size: 92cqi;
|
||||||
--initials-letter-spacing: 0px;
|
--initials-letter-spacing: 0px;
|
||||||
--initials-scale: 1;
|
--initials-scale: 1;
|
||||||
--initials-scale-cap: 1;
|
--initials-scale-cap: 1;
|
||||||
@@ -35,7 +36,10 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--initials-font-size);
|
font-size: min(
|
||||||
|
var(--initials-font-size),
|
||||||
|
calc(var(--initials-fit-inline-size) / (var(--initials-width-em, 0.01) * var(--initials-scale)))
|
||||||
|
);
|
||||||
letter-spacing: var(--initials-letter-spacing);
|
letter-spacing: var(--initials-letter-spacing);
|
||||||
transform: scale(calc(var(--initials-scale) * var(--initials-scale-cap)));
|
transform: scale(calc(var(--initials-scale) * var(--initials-scale-cap)));
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
@@ -47,12 +51,6 @@
|
|||||||
--initials-letter-spacing: 0px;
|
--initials-letter-spacing: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container[data-initials-length='long'] .initials {
|
|
||||||
--initials-font-size: clamp(0.85rem, 32cqi, 0.87rem);
|
|
||||||
--initials-scale: 0.78;
|
|
||||||
--initials-letter-spacing: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@container (max-width: 32px) {
|
@container (max-width: 32px) {
|
||||||
.initials {
|
.initials {
|
||||||
--initials-scale-cap: 0.88;
|
--initials-scale-cap: 0.88;
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
import {useHover} from '@app/features/app/hooks/useHover';
|
import {useHover} from '@app/features/app/hooks/useHover';
|
||||||
import {useShouldAnimate} from '@app/features/app/hooks/useShouldAnimate';
|
import {useShouldAnimate} from '@app/features/app/hooks/useShouldAnimate';
|
||||||
import styles from '@app/features/guild/components/popouts/GuildIcon.module.css';
|
import styles from '@app/features/guild/components/popouts/GuildIcon.module.css';
|
||||||
import {getGuildIconDisplayInitials, getInitialsLength} from '@app/features/guild/utils/GuildInitialsUtils';
|
import {
|
||||||
|
getGuildIconDisplayInitials,
|
||||||
|
getGuildInitialsFitStyle,
|
||||||
|
getInitialsLength,
|
||||||
|
} from '@app/features/guild/utils/GuildInitialsUtils';
|
||||||
import {useRecoveringBackgroundImageURL} from '@app/features/messaging/hooks/useImageRecovery';
|
import {useRecoveringBackgroundImageURL} from '@app/features/messaging/hooks/useImageRecovery';
|
||||||
import * as ImageCacheUtils from '@app/features/messaging/utils/ImageCacheUtils';
|
import * as ImageCacheUtils from '@app/features/messaging/utils/ImageCacheUtils';
|
||||||
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
|
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
|
||||||
@@ -39,9 +43,8 @@ export const GuildIcon = observer(function GuildIcon({
|
|||||||
sizePx,
|
sizePx,
|
||||||
containerProps,
|
containerProps,
|
||||||
}: GuildIconProps) {
|
}: GuildIconProps) {
|
||||||
const rawInitials = useMemo(() => StringUtils.getInitialsFromName(name), [name]);
|
const initials = useMemo(() => getGuildIconDisplayInitials(StringUtils.getInitialsFromName(name)), [name]);
|
||||||
const initials = useMemo(() => getGuildIconDisplayInitials(rawInitials), [rawInitials]);
|
const initialsLength = getInitialsLength(initials);
|
||||||
const initialsLength = useMemo(() => getInitialsLength(rawInitials), [rawInitials]);
|
|
||||||
const [hoverRef, isHovering] = useHover();
|
const [hoverRef, isHovering] = useHover();
|
||||||
const iconUrl = icon ? AvatarUtils.getGuildIconURL({id, icon}) : null;
|
const iconUrl = icon ? AvatarUtils.getGuildIconURL({id, icon}) : null;
|
||||||
const hoverIconUrl = icon ? AvatarUtils.getGuildIconURL({id, icon}, true) : null;
|
const hoverIconUrl = icon ? AvatarUtils.getGuildIconURL({id, icon}, true) : null;
|
||||||
@@ -73,7 +76,11 @@ export const GuildIcon = observer(function GuildIcon({
|
|||||||
style={styleVars}
|
style={styleVars}
|
||||||
>
|
>
|
||||||
{paintedUrl == null && (
|
{paintedUrl == null && (
|
||||||
<span className={styles.initials} data-flx="guild.guild-icon.initials">
|
<span
|
||||||
|
className={styles.initials}
|
||||||
|
style={getGuildInitialsFitStyle(initials)}
|
||||||
|
data-flx="guild.guild-icon.initials"
|
||||||
|
>
|
||||||
{initials}
|
{initials}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import type React from 'react';
|
||||||
|
|
||||||
const GUILD_ICON_INITIALS_MAX_LENGTH = 4;
|
const GUILD_ICON_INITIALS_MAX_LENGTH = 4;
|
||||||
|
const MEASURE_FONT_SIZES_PX = [10, 12, 14, 16, 20, 24];
|
||||||
|
const MEASURE_FONT_WEIGHT = 600;
|
||||||
|
|
||||||
export const GuildInitialsLength = Object.freeze({
|
export const GuildInitialsLength = Object.freeze({
|
||||||
SHORT: 'short',
|
SHORT: 'short',
|
||||||
MEDIUM: 'medium',
|
MEDIUM: 'medium',
|
||||||
LONG: 'long',
|
|
||||||
} as const);
|
} as const);
|
||||||
|
|
||||||
export type GuildInitialsLength = (typeof GuildInitialsLength)[keyof typeof GuildInitialsLength];
|
export type GuildInitialsLength = (typeof GuildInitialsLength)[keyof typeof GuildInitialsLength];
|
||||||
|
|
||||||
|
export type GuildInitialsFitStyle = React.CSSProperties & {
|
||||||
|
'--initials-width-em'?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const measuredWidthsEm = new Map<string, number>();
|
||||||
|
let measureContext: OffscreenCanvasRenderingContext2D | null | undefined;
|
||||||
|
|
||||||
export function getInitialsFromName(name: string): string {
|
export function getInitialsFromName(name: string): string {
|
||||||
const words = name.split(/\s+/u).filter(Boolean);
|
const words = name.split(/\s+/u).filter(Boolean);
|
||||||
return words
|
return words
|
||||||
@@ -27,9 +37,40 @@ export function getGuildIconDisplayInitials(initials: string): string {
|
|||||||
return truncateInitials(initials, GUILD_ICON_INITIALS_MAX_LENGTH);
|
return truncateInitials(initials, GUILD_ICON_INITIALS_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInitialsLength(initials: string): GuildInitialsLength {
|
export function getInitialsLength(displayInitials: string): GuildInitialsLength {
|
||||||
const length = Array.from(initials).length;
|
return Array.from(displayInitials).length <= 2 ? GuildInitialsLength.SHORT : GuildInitialsLength.MEDIUM;
|
||||||
if (length <= 2) return GuildInitialsLength.SHORT;
|
}
|
||||||
if (length <= 4) return GuildInitialsLength.MEDIUM;
|
|
||||||
return GuildInitialsLength.LONG;
|
function getMeasureContext(): OffscreenCanvasRenderingContext2D | null {
|
||||||
|
if (measureContext !== undefined) return measureContext;
|
||||||
|
if (typeof document === 'undefined' || typeof OffscreenCanvas === 'undefined') {
|
||||||
|
measureContext = null;
|
||||||
|
return measureContext;
|
||||||
|
}
|
||||||
|
measureContext = new OffscreenCanvas(1, 1).getContext('2d');
|
||||||
|
document.fonts?.addEventListener('loadingdone', () => measuredWidthsEm.clear());
|
||||||
|
return measureContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
function measureInitialsWidthEm(initials: string): number | null {
|
||||||
|
const context = getMeasureContext();
|
||||||
|
if (context == null || document.body == null) return null;
|
||||||
|
const fontFamily = getComputedStyle(document.body).fontFamily;
|
||||||
|
const key = `${fontFamily}\u0000${initials}`;
|
||||||
|
const cached = measuredWidthsEm.get(key);
|
||||||
|
if (cached !== undefined) return cached;
|
||||||
|
let widthEm = 0;
|
||||||
|
for (const fontSize of MEASURE_FONT_SIZES_PX) {
|
||||||
|
context.font = `${MEASURE_FONT_WEIGHT} ${fontSize}px ${fontFamily}`;
|
||||||
|
widthEm = Math.max(widthEm, context.measureText(initials).width / fontSize);
|
||||||
|
}
|
||||||
|
measuredWidthsEm.set(key, widthEm);
|
||||||
|
return widthEm;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGuildInitialsFitStyle(displayInitials: string): GuildInitialsFitStyle | undefined {
|
||||||
|
if (!displayInitials) return undefined;
|
||||||
|
const widthEm = measureInitialsWidthEm(displayInitials);
|
||||||
|
if (widthEm == null || widthEm <= 0) return undefined;
|
||||||
|
return {'--initials-width-em': widthEm.toFixed(3)};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user