Radial Pattern Background: Simplify styling (#6405)

This commit is contained in:
zubiden 2025-11-06 11:36:46 +01:00 committed by Alexander Zinchuk
parent cf8a933b4c
commit 5e68196c0c
16 changed files with 47 additions and 46 deletions

View File

@ -39,6 +39,9 @@ const GiftTransferPreview = ({
className={styles.backdrop}
backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]}
patternIcon={giftAttributes.pattern?.sticker}
ringsCount={1}
ovalFactor={1}
patternSize={12}
/>
<AnimatedIconFromSticker
className={styles.sticker}

View File

@ -141,6 +141,7 @@ const SavedGift = ({
patternSize={14}
ringsCount={1}
ovalFactor={1}
withAdaptiveHeight
/>
);
}, [backdrop, pattern]);

View File

@ -98,6 +98,7 @@ type StateProps = {
theme: ThemeKey;
isPlain?: boolean;
savedGifts?: ApiSavedGifts;
hasAvatar?: boolean;
};
const EMOJI_STATUS_SIZE = 24;
@ -130,6 +131,7 @@ const ProfileInfo = ({
theme,
isPlain,
savedGifts,
hasAvatar,
onExpand,
}: OwnProps & StateProps) => {
const {
@ -286,7 +288,7 @@ const ProfileInfo = ({
return;
}
onExpand?.();
if (hasAvatar) onExpand?.();
});
function handleSelectFallbackPhoto() {
@ -576,7 +578,7 @@ const ProfileInfo = ({
size="jumbo"
peer={peer}
style={createVtnStyle('avatar', true)}
onClick={handleMinimizedAvatarClick}
onClick={hasAvatar ? handleMinimizedAvatarClick : undefined}
/>
)}
@ -627,6 +629,7 @@ export default memo(withGlobal<OwnProps>(
const hasBackground = selectPeerHasProfileBackground(global, peerId);
const savedGifts = selectPeerSavedGifts(global, peerId);
const hasAvatar = Boolean(peer?.avatarPhotoId);
return {
user,
@ -646,6 +649,7 @@ export default memo(withGlobal<OwnProps>(
theme,
isPlain: !hasBackground,
savedGifts,
hasAvatar,
};
},
)(ProfileInfo));

View File

@ -29,6 +29,7 @@ type OwnProps = {
className?: string;
clearBottomSector?: boolean;
yPosition?: number;
withAdaptiveHeight?: boolean;
};
const BASE_RING_ITEM_COUNT = 8;
@ -40,7 +41,7 @@ const DARK_LUMA_THRESHOLD = 255 * 0.2;
const DEFAULT_PATTERN_SIZE = 20;
const DEFAULT_RINGS_COUNT = 3;
const DEFAULT_OVAL_FACTOR = 1.4;
const DEFAULT_OVAL_FACTOR = 1.61;
const RadialPatternBackground = ({
backgroundColors,
@ -53,6 +54,7 @@ const RadialPatternBackground = ({
clearBottomSector,
className,
yPosition,
withAdaptiveHeight,
}: OwnProps) => {
const containerRef = useRef<HTMLDivElement>();
const canvasRef = useRef<HTMLCanvasElement>();
@ -125,7 +127,8 @@ const RadialPatternBackground = ({
if (!width || !height) return;
const centerX = width / 2;
const centerY = yPosition !== undefined ? yPosition * dpr : height / 2;
const centerY = withAdaptiveHeight ? height / 2
: yPosition !== undefined ? yPosition * dpr : width / 2;
ctx.clearRect(0, 0, width, height);
@ -133,8 +136,7 @@ const RadialPatternBackground = ({
x, y, sizeFactor,
}) => {
const renderX = x * Math.max(width, MIN_SIZE * dpr) + centerX;
const renderY = yPosition !== undefined ? y * Math.max(width, MIN_SIZE * dpr) + centerY
: y * Math.max(height, MIN_SIZE * dpr) + centerY;
const renderY = y * Math.max(withAdaptiveHeight ? height : width, MIN_SIZE * dpr) + centerY;
const size = patternSize * dpr * sizeFactor;
ctx.drawImage(emojiImage, renderX - size / 2, renderY - size / 2, size, size);

View File

@ -196,7 +196,7 @@
.uniqueBackground {
position: absolute;
inset: -6rem 0 0 0;
inset: 0;
}
.uniqueValue {

View File

@ -17,16 +17,10 @@
font-weight: var(--font-weight-semibold);
}
.backgroundWrapper {
position: absolute;
inset: 0;
overflow: hidden;
border-radius: inherit;
}
.background {
position: absolute;
inset: -1rem 0 0 0;
inset: 0;
border-radius: inherit;
}
.stickerWrapper {

View File

@ -45,16 +45,15 @@ const WebPageUniqueGift = ({
onMouseEnter={!IS_TOUCH_ENV ? markHover : undefined}
onMouseLeave={!IS_TOUCH_ENV ? unmarkHover : undefined}
>
<div className={styles.backgroundWrapper}>
<RadialPatternBackground
className={styles.background}
backgroundColors={backgroundColors}
patternIcon={pattern!.sticker}
centerEmptiness={0.15}
ringsCount={2}
ovalFactor={1.2}
/>
</div>
<RadialPatternBackground
className={styles.background}
backgroundColors={backgroundColors}
patternIcon={pattern!.sticker}
centerEmptiness={0.15}
ringsCount={2}
ovalFactor={1.2}
withAdaptiveHeight
/>
<div ref={stickerRef} className={styles.stickerWrapper}>
<StickerView
containerRef={stickerRef}

View File

@ -99,7 +99,7 @@ const StarGiftAction = ({
backgroundColors={backgroundColors}
patternIcon={pattern.sticker}
patternSize={14}
yPosition={9.5 * REM}
yPosition={5 * REM}
clearBottomSector
/>
</div>

View File

@ -26,10 +26,10 @@ import styles from './GiftItem.module.scss';
export type OwnProps = {
gift: ApiStarGift;
observeIntersection?: ObserveFn;
onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void;
isResale?: boolean;
withTransferBadge?: boolean;
observeIntersection?: ObserveFn;
onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void;
};
type StateProps = {
@ -39,7 +39,7 @@ type StateProps = {
const GIFT_STICKER_SIZE = 90;
function GiftItemStar({
gift, observeIntersection, onClick, isResale, isCurrentUserPremium, withTransferBadge,
gift, isResale, isCurrentUserPremium, withTransferBadge, observeIntersection, onClick,
}: OwnProps & StateProps) {
const { openGiftInfoModal, openPremiumModal, showNotification, checkCanSendGift } = getActions();

View File

@ -14,10 +14,6 @@
&.withManageButtons {
--_height: 18.5rem;
.radialPattern {
inset: -8rem -5% -5% -5%;
}
.sticker {
margin-top: 2.5rem;
}
@ -52,8 +48,7 @@
.radialPattern {
position: absolute;
z-index: -1;
inset: -5rem -5% -5% -5%;
height: calc(var(--height) * 1.05);
inset: 0;
}
.amount {

View File

@ -14,6 +14,7 @@ import {
import { IS_TOUCH_ENV } from '../../../util/browser/windowEnvironment.ts';
import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle';
import { REM } from '../../common/helpers/mediaDimensions.ts';
import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey';
import useFlag from '../../../hooks/useFlag';
@ -72,6 +73,7 @@ const UniqueGiftHeader = ({
className={styles.radialPattern}
backgroundColors={backdropColors}
patternIcon={patternAttribute.sticker}
yPosition={6.5 * REM}
/>
);
}, [backdropAttribute, patternAttribute]);

View File

@ -19,11 +19,11 @@
.radialPattern {
position: absolute;
z-index: -1;
top: -3rem;
top: -1rem;
inset-inline-start: -1.5rem;
width: calc(100% + 3rem);
height: calc(100% + 2rem);
height: calc(100% + 1rem);
}
.lockIcon {

View File

@ -9,6 +9,7 @@ import type { TabState } from '../../../../global/types';
import { selectIsCurrentUserPremium, selectUser } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName';
import buildStyle from '../../../../util/buildStyle';
import { REM } from '../../../common/helpers/mediaDimensions';
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
import useLang from '../../../../hooks/useLang';
@ -73,6 +74,7 @@ const GiftStatusInfoModal = ({
className={styles.radialPattern}
backgroundColors={backdropColors}
patternIcon={patternIcon.customEmoji}
yPosition={6.5 * REM}
/>
);
}, [emojiStatus, isOpen, patternIcon]);

View File

@ -87,6 +87,7 @@ const GiftWithdrawModal = ({ modal, hasPassword, passwordHint }: OwnProps & Stat
<Modal
isOpen={isOpen}
title={lang('GiftWithdrawTitle')}
isCondensedHeader
hasCloseButton
isSlim
onClose={handleClose}
@ -99,6 +100,9 @@ const GiftWithdrawModal = ({ modal, hasPassword, passwordHint }: OwnProps & Stat
className={styles.backdrop}
backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]}
patternIcon={giftAttributes.pattern?.sticker}
ringsCount={1}
ovalFactor={1}
patternSize={12}
/>
<AnimatedIconFromSticker
className={styles.sticker}

View File

@ -74,15 +74,10 @@
.uniqueGiftBackground {
position: absolute;
top: 0;
right: 0;
left: 0;
aspect-ratio: 1 / 1;
inset: 0;
border-radius: 0.25rem;
}
.giftSticker {
margin-top: 0.25rem;
margin-inline: 0.25rem;
margin: 0.25rem;
}

View File

@ -193,7 +193,7 @@ export function selectPeerProfileColor<T extends GlobalState>(global: T, peer: A
const profileColor = !isCustomPeer ? peer.profileColor : undefined;
if (profileColor?.type === 'collectible') return undefined;
const key = profileColor?.color || peerColorId;
if (!key) return undefined;
const key = profileColor?.color ?? peerColorId;
if (key === undefined) return undefined;
return global.peerColors?.profile?.[key];
}