y4shiro / uma-card-deck-tools

uma-card-deck-tools.vercel.app
0 stars 0 forks source link

スキルアイテムのレアリティ別背景色を実装 #35

Closed y4shiro closed 2 years ago

y4shiro commented 2 years ago

Todo

y4shiro commented 2 years ago

大まかな機能設計

SkillItem コンポーネント に rarity が props を渡し、この値を基準に背景色を切り換える rarity の値は 1 ~ 5 の数字

1 は 下位スキルもしくは固有スキルの継承版、色は白 2 は 上位スキル、色は金 3 は星 1 / 2 キャラの固有下位スキル、色は白 4 は星 1 / 2 キャラの固有上位スキル、色は虹 5 は星 3 キャラの固有スキル、色は虹

背景色は Card コンポーネントの時同様 Object で管理する 枠線もグラデにしたいが、border-radius を指定している場合は疑似要素などで実装する必要があるので、 時間が掛かりそうなら今回はパス

ついでに font-family の指定やフォントの装飾も行う

y4shiro commented 2 years ago

SkillItem に Props で rarity を渡す

src/features/Support/Skills/SkillItem/index.tsx

type Props = {
  skillName: string;
  rarity: 1 | 2 | 3 | 4 | 5;
  skillPt: number | null;
  cardName: string;
};

const SkillItem: React.FC<Props> = ({ skillName, rarity, skillPt, cardName }) => {
y4shiro commented 2 years ago

レアリティ毎に背景色と枠色を設定

背景はどの色も基本的にグラデーションが掛かっている

  const bgColors = {
    1: 'linear(90deg, #FCF3F2, #D9D7EB 50%, #C8C6DE 75%,#AAA9BE)', // 白
    2: 'linear(90deg, #FFFEEE, #F7D883 50%, #F2BA53)', // 金
    3: 'linear(90deg, #FCF3F2, #D9D7EB 50%, #C8C6DE 75%,#AAA9BE)', // 白
    4: 'linear(90deg, #E0FDD7, #BDF2F8 25%, #B4CEF7 50%, #E4B7ED 75%, #EFABE7)', // 虹
    5: 'linear(90deg, #E0FDD7, #BDF2F8 25%, #B4CEF7 50%, #E4B7ED 75%, #EFABE7)', // 虹
  };
  const borderColors = {
    1: '#9290B2',
    2: '#EEA348',
    3: '#9290B2',
    4: '#E45DAD',
    5: '#E45DAD',
  };
// ...
  return (
    <HStack
      w='100%'
      px='4'
      py='2'
      gap={{ base: '2', md: '4' }}
      borderRadius='8'
      border='1px'
      borderColor={borderColors[rarity]}
      bgGradient={bgColors[rarity]}
      shadow='md'
    >

枠色を指定した結果は次の通り サポカからh 2022/10 現在、虹色枠の高レアスキルは取得できないが、今後実装される可能性を考慮して用意した

スクリーンショット 2022-10-31 18 34 25 スクリーンショット 2022-10-31 18 34 39

y4shiro commented 2 years ago

スキル説明のフォントと色を設定

フォント自体の指定 / フォントの色 / フォント weight / フォントの影か枠線の指定を行いたい

フォント自体の指定

https://chakra-ui.com/community/recipes/using-fonts Chakra UI では theme.ts にフォント指定を記述して index.tsx などで読み込む

src/styles/theme.ts

import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  fonts: {
    heading: `"Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif`,
    body: `"Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif`,
  },
});

export default theme;

src/pages/_app.tsx

import theme from '@/styles/theme';

function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout || ((page) => page);

  return (
    <Provider store={store}>
      <ChakraProvider theme={theme}>{getLayout(<Component {...pageProps} />)}</ChakraProvider>
    </Provider>
  );
}

フォントの装飾

フォントカラー / Weight / フォントの影などを設定

src/features/Support/Skills/SkillItem/index.tsx

  return (
    <HStack
      w='100%'
      px='4'
      py='2'
      gap={{ base: '2', md: '4' }}
      borderRadius='8'
      border='1px'
      borderColor={borderColors[rarity]}
      bgGradient={bgColors[rarity]}
      fontWeight='bold'
      textColor={fontColor}
      textShadow='0 0 1px #fff, 0 0 1px #fff, 0 0 1px #fff'
      shadow='md'
    >
      <Box boxSize='48px' bgColor='gray.300'>
        icon
      </Box>

      <VStack w='100%' divider={<Divider borderColor={fontColor} />}>
        <HStack w='100%'>
          <Text>{skillName}</Text>
          <Spacer />
          {skillPt && <Text>{skillPt}Pt</Text>}
        </HStack>

        <Text w='100%'>{cardName}</Text>
      </VStack>
    </HStack>
  );
};

ゲームの表示になるべく寄せた スクリーンショット 2022-10-31 18 42 03 スクリーンショット 2022-10-31 18 42 20

y4shiro commented 2 years ago

(オプション) SkillItem の枠線にグラデーションを掛ける

ゲームの方は枠線にグラデーションが設定されている スクリーンショット 2022-11-02 17 35 02

CSS で実現する場合、borderRadius が掛かっていなければ border-image に linear-gradient() を指定するだけなので簡単 borderRaidus と併用する場合は、before 疑似要素などを組み合わせる必要があり、結構手間がかかるので本当に必要か検討する

CSS で角丸グラデを設定する方法が複数提示されている ベストアンサーでは CSS mask の使用が推奨されている

background / border プロパティで角丸グラデを設定する方法 コードが一番シンプルになるのはこの方法だった

mask の方は -webkit のベンダープレフィックスが必要である、コード量が多くなるという点があったため、 今回は background / border で表現する方法を採用した

src/features/Support/Skills/SkillItem/index.tsx

  const bgColors = {
    1: 'linear-gradient(90deg, #FCF3F2, #D9D7EB 50%, #C8C6DE 75%,#AAA9BE)', // 白
    2: 'linear-gradient(90deg, #FFFEEE, #F7D883 50%, #F2BA53)', // 金
    3: 'linear-gradient(90deg, #FCF3F2, #D9D7EB 50%, #C8C6DE 75%,#AAA9BE)', // 白
    4: 'linear-gradient(90deg, #E0FDD7, #BDF2F8 25%, #B4CEF7 50%, #E4B7ED 75%, #EFABE7)', // 虹
    5: 'linear-gradient(90deg, #E0FDD7, #BDF2F8 25%, #B4CEF7 50%, #E4B7ED 75%, #EFABE7)', // 虹
  };
  const borderColors = {
    1: 'linear-gradient(90deg, #d1c6dc, #8d8aae)',
    2: 'linear-gradient(90deg, #F7DB81, #EEA146)',
    3: 'linear-gradient(90deg, #d1c6dc, #8d8aae)',
    4: 'linear-gradient(90deg, #88F180, #A2CDE1 25%, #969FF2 50%, #B68BEC 75%, #EA88CE)',
    5: 'linear-gradient(90deg, #88F180, #A2CDE1 25%, #969FF2 50%, #B68BEC 75%, #EA88CE)',
  };

  return (
    <HStack
      w='100%'
      px='4'
      py='2'
      gap={{ base: '2', md: '4' }}
      borderRadius='16'
      background={`${bgColors[rarity]} padding-box, ${borderColors[rarity]} border-box`}
      border='2px solid transparent'
      fontWeight='extrabold'
      textColor={fontColor}
      textShadow='0 0 1px #fff, 0 0 1px #fff, 0 0 1px #fff'
      shadow='md'
    >

スクリーンショット 2022-11-02 17 43 13 スクリーンショット 2022-11-02 17 43 27

フォント weight をもっと太いものに指定したかったが、Win / Mac / iOS / Android の各デフォルトフォントを調査する必要があるので今回はパス Web Font はダウンロードサイズが膨れ上がるので採用したくない