首页 > 解决方案 > React Material UI - 自定义 CardMedia 的渲染

问题描述

我想知道如何调整React Material UI 的CardMedia来生成类似的东西:

预期的

如您所见,我期望的结果中有 3 项:

目前,我将所有平台 SVG 都存储在一个文件中:

    export default {
        "PC": `
            M4.539062 7.515625 L 4.539062 13.886719 L 7.6875 13.886719 L 7.695312 11.738281 L 7.707031 9.597656 L 8.625 9.585938 L 9.542969 9.578125 L 10.546875 8.589844 L 11.550781 7.605469 L 11.550781 3.148438 L 10.527344 2.144531 L 9.507812 1.140625 L 4.539062 1.140625 Z 
            M8.28125 5.410156 L 8.289062 7.113281 L 8 7.101562 L 7.707031 7.089844 L 7.695312 5.40625 L 7.6875 3.722656 L 7.9375 3.714844 C 8.082031 3.707031 8.210938 3.703125 8.230469 3.703125 C 8.253906 3.707031 8.273438 4.308594 8.28125 5.410156 Z 
            M8.28125 5.410156 
            M13.09375 2.148438 L 12.074219 3.148438 L 12.074219 11.917969 L 13.078125 12.902344 L 14.085938 13.886719 L 17.457031 13.886719 L 18.460938 12.898438 L 19.460938 11.917969 L 19.445312 8.417969 L 16.144531 8.417969 L 16.132812 9.878906 L 16.125 11.347656 L 15.601562 11.347656 L 15.601562 3.71875 L 16.125 3.71875 L 16.132812 4.925781 L 16.144531 6.132812 L 19.445312 6.132812 L 19.460938 3.148438 L 18.441406 2.148438 L 17.417969 1.140625 L 14.117188 1.140625 Z 
            M13.09375 2.148438
        `
    }

我们可以调用:

import iconsSVG from "./PlatformIcons";
import SvgIcon from '@material-ui/core/SvgIcon';

//...
let platform = "PC";
<SvgIcon titleAccess={platform}>
     <path d={iconsSVG[platform]} />
</SvgIcon>
//...

提前致谢

编辑:如果需要,这是我的完整 Card 组件实现:

    import React from "react";
    import {useTranslation} from "react-i18next";
    
    import { makeStyles } from '@material-ui/core/styles';
    
    import {Link} from 'react-router-dom';
    
    import Card from "@material-ui/core/Card";
    import CardMedia from "@material-ui/core/CardMedia";
    import CardActions from "@material-ui/core/CardActions";
    
    import IconButton from "@material-ui/core/IconButton";
    import YouTubeIcon from '@material-ui/icons/YouTube';
    import PlayArrowIcon from '@material-ui/icons/PlayArrow';
    
    import Tooltip from '@material-ui/core/Tooltip';
    
    const useStyles = makeStyles((theme) => ({
        localVideoPlayerButton : {
            [theme.breakpoints.down('sm')]: {
                display: "none"
            }
        },
        gameCover: {
            [theme.breakpoints.between('xs', 'md')]: {
                height: 200
            },
            [theme.breakpoints.up('md')]: {
                height: 150
            },
        },
        gameControls : {
            display: 'flex',
            justifyContent: 'center',
            paddingLeft: theme.spacing(1),
            paddingBottom: theme.spacing(1),
        }
    }));
    
    function CardEntry(props) {
    
        const {game} = props;
        const { t } = useTranslation('common');
        const classes = useStyles(props);
    
        return (
            <Card>
    
                <CardMedia
                    component="img"
                    className={classes.gameCover}
                    image={game.imagePath}
                    title={game.title}
                />
    
                <CardActions className={classes.gameControls}>
    
                    <Tooltip title={t("gamesLibrary.actionsButton.watchHere", { "gameName": game.title})} aria-label="Watch" className={classes.localVideoPlayerButton}>
                        <IconButton
                            aria-label="play"
                            component={Link}
                            to={
                                game.url_type === "PLAYLIST" ? "/playlist/" + game.playlistId : "/video/" + game.videoId
                            }
                        >
                            <PlayArrowIcon/>
                        </IconButton>
                    </Tooltip>            
    
                    <Tooltip title={t("gamesLibrary.actionsButton.watchOnYt", { "gameName": game.title})} aria-label="WatchOnYoutube">
                        <IconButton
                            aria-label="share"
                            href={game.url}
                        >
                            <YouTubeIcon/>
                        </IconButton>
                    </Tooltip>
                </CardActions>
    
            </Card>
        );
    }
    
    export default CardEntry;

通过我可以提供给该内容的数据示例:

    {
      "title": "Mafia: Definitive Edition",
      "playlistId": "PLRfhDHeBTBJ6SEXdQnTM4OHRH9mDIRocv",
      "releaseDate": "2020-09-24T22:00:00.000Z",
      "duration": "06:59:14",
      "genres": [
        "Action",
        "Adventure",
        "Shooter"
      ],
      "platform": "PC",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ6SEXdQnTM4OHRH9mDIRocv/cover.webp",
      "url": "https://www.youtube.com/playlist?list=PLRfhDHeBTBJ6SEXdQnTM4OHRH9mDIRocv",
      "url_type": "PLAYLIST",
      "durationAsInt": 65914
    }

标签: cssreactjsimagematerial-uifrontend

解决方案


使用这个布局:

<Card className={classes.root}>// with position releative
  <IconButton
    aria-label="console"
    className={classes.rightChip}// with absolute position and z-index
    onClick={handleConsole}// ur console button for showing all pc games
  >
    // ur pc icon
  </IconButton>
  <Typography variant="body2" color="textSecondary" 
     component="p"className={classes.timer}>//also with absolute position and z-index
    {//ur timer}
  </Typography>
  <CardActionArea onClick={clickHandler}>
    <CardMedia
      component="img"
      className={classes.gameCover}
      image={game.imagePath}
      title={game.title}
    />
  </CardActionArea>
</Card>

代码沙盒


推荐阅读