mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
adjust styles on fullscreen player image section
- fix image transition - fix image aspect ratio - adjust text sizes and shadow
This commit is contained in:
parent
0afbe4c0a2
commit
64866c59bd
3 changed files with 65 additions and 35 deletions
|
|
@ -2,7 +2,6 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: var(--theme-image-fit);
|
|
||||||
object-position: 50% 100%;
|
object-position: 50% 100%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
filter: drop-shadow(0 0 5px rgb(0 0 0 / 40%)) drop-shadow(0 0 5px rgb(0 0 0 / 40%));
|
filter: drop-shadow(0 0 5px rgb(0 0 0 / 40%)) drop-shadow(0 0 5px rgb(0 0 0 / 40%));
|
||||||
|
|
@ -24,8 +23,13 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3.5vh;
|
font-size: 3.5vh;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,7 @@ import { Center } from '/@/shared/components/center/center';
|
||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Image } from '/@/shared/components/image/image';
|
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { PlayerData, QueueSong } from '/@/shared/types/domain-types';
|
import { PlayerData, QueueSong } from '/@/shared/types/domain-types';
|
||||||
|
|
||||||
|
|
@ -52,9 +50,14 @@ const scaleImageUrl = (imageSize: number, url?: null | string) => {
|
||||||
.replace(/&height=\d+/, `&height=${imageSize}`);
|
.replace(/&height=\d+/, `&height=${imageSize}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const MotionImage = motion.create(Image);
|
const MotionImage = motion.img;
|
||||||
|
|
||||||
|
const ImageWithPlaceholder = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: HTMLMotionProps<'img'> & { placeholder?: string }) => {
|
||||||
|
const nativeAspectRatio = useSettingsStore((store) => store.general.nativeAspectRatio);
|
||||||
|
|
||||||
const ImageWithPlaceholder = ({ ...props }: HTMLMotionProps<'img'> & { placeholder?: string }) => {
|
|
||||||
if (!props.src) {
|
if (!props.src) {
|
||||||
return (
|
return (
|
||||||
<Center
|
<Center
|
||||||
|
|
@ -76,7 +79,11 @@ const ImageWithPlaceholder = ({ ...props }: HTMLMotionProps<'img'> & { placehold
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MotionImage
|
<MotionImage
|
||||||
className={styles.image}
|
className={clsx(styles.image, className)}
|
||||||
|
style={{
|
||||||
|
objectFit: nativeAspectRatio ? 'contain' : 'cover',
|
||||||
|
width: nativeAspectRatio ? 'auto' : '100%',
|
||||||
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
@ -201,40 +208,32 @@ export const FullScreenPlayerImage = () => {
|
||||||
</div>
|
</div>
|
||||||
<Stack
|
<Stack
|
||||||
className={styles.metadataContainer}
|
className={styles.metadataContainer}
|
||||||
gap="xs"
|
gap="2px"
|
||||||
maw="100%"
|
maw="100%"
|
||||||
>
|
>
|
||||||
<TextTitle
|
<Text
|
||||||
fw={900}
|
fw={900}
|
||||||
order={1}
|
lh="1.2"
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
|
size="4xl"
|
||||||
w="100%"
|
w="100%"
|
||||||
>
|
>
|
||||||
{currentSong?.name}
|
{currentSong?.name}
|
||||||
</TextTitle>
|
</Text>
|
||||||
<TextTitle
|
<Text
|
||||||
component={Link}
|
component={Link}
|
||||||
fw={600}
|
fw={600}
|
||||||
isLink
|
isLink
|
||||||
order={3}
|
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
style={{
|
size="xl"
|
||||||
textShadow: 'var(--theme-fullscreen-player-text-shadow)',
|
|
||||||
}}
|
|
||||||
to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||||
albumId: currentSong?.albumId || '',
|
albumId: currentSong?.albumId || '',
|
||||||
})}
|
})}
|
||||||
w="100%"
|
w="100%"
|
||||||
>
|
>
|
||||||
{currentSong?.album}{' '}
|
{currentSong?.album}
|
||||||
</TextTitle>
|
</Text>
|
||||||
<TextTitle
|
<Text key="fs-artists">
|
||||||
key="fs-artists"
|
|
||||||
order={3}
|
|
||||||
style={{
|
|
||||||
textShadow: 'var(--theme-fullscreen-player-text-shadow)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{currentSong?.artists?.map((artist, index) => (
|
{currentSong?.artists?.map((artist, index) => (
|
||||||
<Fragment key={`fs-artist-${artist.id}`}>
|
<Fragment key={`fs-artist-${artist.id}`}>
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
|
|
@ -253,9 +252,6 @@ export const FullScreenPlayerImage = () => {
|
||||||
fw={600}
|
fw={600}
|
||||||
isLink
|
isLink
|
||||||
isMuted
|
isMuted
|
||||||
style={{
|
|
||||||
textShadow: 'var(--theme-fullscreen-player-text-shadow)',
|
|
||||||
}}
|
|
||||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||||
albumArtistId: artist.id,
|
albumArtistId: artist.id,
|
||||||
})}
|
})}
|
||||||
|
|
@ -264,7 +260,7 @@ export const FullScreenPlayerImage = () => {
|
||||||
</Text>
|
</Text>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</TextTitle>
|
</Text>
|
||||||
<Group
|
<Group
|
||||||
justify="center"
|
justify="center"
|
||||||
mt="sm"
|
mt="sm"
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import type { ImgHTMLAttributes } from 'react';
|
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import { motion, MotionConfigProps } from 'motion/react';
|
||||||
|
import { type ImgHTMLAttributes } from 'react';
|
||||||
import { Img } from 'react-image';
|
import { Img } from 'react-image';
|
||||||
|
|
||||||
import styles from './image.module.css';
|
import styles from './image.module.css';
|
||||||
|
|
||||||
|
import { animationProps } from '/@/shared/components/animations/animation-props';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
|
|
||||||
interface ImageContainerProps {
|
interface ImageContainerProps extends MotionConfigProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
enableAnimation?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImageLoaderProps {
|
interface ImageLoaderProps {
|
||||||
|
|
@ -19,6 +21,8 @@ interface ImageLoaderProps {
|
||||||
|
|
||||||
interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src'> {
|
interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src'> {
|
||||||
containerClassName?: string;
|
containerClassName?: string;
|
||||||
|
enableAnimation?: boolean;
|
||||||
|
imageContainerProps?: Omit<ImageContainerProps, 'children'>;
|
||||||
includeLoader?: boolean;
|
includeLoader?: boolean;
|
||||||
includeUnloader?: boolean;
|
includeUnloader?: boolean;
|
||||||
src: string | string[] | undefined;
|
src: string | string[] | undefined;
|
||||||
|
|
@ -32,6 +36,8 @@ interface ImageUnloaderProps {
|
||||||
export function Image({
|
export function Image({
|
||||||
className,
|
className,
|
||||||
containerClassName,
|
containerClassName,
|
||||||
|
enableAnimation,
|
||||||
|
imageContainerProps,
|
||||||
includeLoader = true,
|
includeLoader = true,
|
||||||
includeUnloader = true,
|
includeUnloader = true,
|
||||||
src,
|
src,
|
||||||
|
|
@ -41,7 +47,13 @@ export function Image({
|
||||||
<Img
|
<Img
|
||||||
className={clsx(styles.image, className)}
|
className={clsx(styles.image, className)}
|
||||||
container={(children) => (
|
container={(children) => (
|
||||||
<ImageContainer className={containerClassName}>{children}</ImageContainer>
|
<ImageContainer
|
||||||
|
className={containerClassName}
|
||||||
|
enableAnimation={enableAnimation}
|
||||||
|
{...imageContainerProps}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ImageContainer>
|
||||||
)}
|
)}
|
||||||
loader={
|
loader={
|
||||||
includeLoader ? (
|
includeLoader ? (
|
||||||
|
|
@ -50,7 +62,6 @@ export function Image({
|
||||||
</ImageContainer>
|
</ImageContainer>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
loading="lazy"
|
|
||||||
src={src}
|
src={src}
|
||||||
unloader={
|
unloader={
|
||||||
includeUnloader ? (
|
includeUnloader ? (
|
||||||
|
|
@ -66,8 +77,27 @@ export function Image({
|
||||||
return <ImageUnloader />;
|
return <ImageUnloader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImageContainer({ children, className }: ImageContainerProps) {
|
function ImageContainer({ children, className, enableAnimation, ...props }: ImageContainerProps) {
|
||||||
return <div className={clsx(styles.imageContainer, className)}>{children}</div>;
|
if (!enableAnimation) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={clsx(styles.imageContainer, className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
className={clsx(styles.imageContainer, className)}
|
||||||
|
{...animationProps.fadeIn}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImageLoader({ className }: ImageLoaderProps) {
|
function ImageLoader({ className }: ImageLoaderProps) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue