Commit b0ba8861 authored by timel's avatar timel Committed by Chunchi Che

feat: update style2

parent dc06b81c
.card-modal {
position: fixed;
display: flex;
left: 5%;
top: 20%;
border-style: groove;
border-radius: 8px;
width: 200px;
flex-wrap: wrap;
background-color: #303030;
padding: 1%;
--visibility: hidden;
visibility: var(--visibility);
--opacity: 0;
opacity: var(--opacity);
transition:visibility 0.3s linear, opacity 0.3s linear;
}
// .card-modal {
// position: fixed;
// display: flex;
// left: 5%;
// top: 20%;
// border-style: groove;
// border-radius: 8px;
// width: 200px;
// flex-wrap: wrap;
// background-color: #303030;
// padding: 1%;
// --visibility: hidden;
// visibility: var(--visibility);
// --opacity: 0;
// opacity: var(--opacity);
// transition:visibility 0.3s linear, opacity 0.3s linear;
// }
.card-modal-container {
display: flex;
flex-direction: column;
gap: 5px;
}
// .card-modal-container {
// display: flex;
// flex-direction: column;
// gap: 5px;
// }
.card-modal-name {
font-weight: bold;
}
// .card-modal-name {
// font-weight: bold;
// }
.card-modal-attribute {
font-weight: bold;
}
// .card-modal-attribute {
// font-weight: bold;
// }
.card-modal-atk {
font-weight: bold;
}
// .card-modal-atk {
// font-weight: bold;
// }
.card-modal-counter {
font-weight: bold;
}
// .card-modal-counter {
// font-weight: bold;
// }
.card-modal-effect {
font-weight: lighter;
text-align: left;
max-height: 200px;
overflow: auto;
}
// .card-modal-effect {
// font-weight: lighter;
// text-align: left;
// max-height: 200px;
// overflow: auto;
// }
.card-modal-btn {
margin: 1px 5px;
font-size: 80%;
border-color: yellow;
}
// .card-modal-btn {
// margin: 1px 5px;
// font-size: 80%;
// border-color: yellow;
// }
......@@ -33,7 +33,7 @@ table {
body {
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #202022;
background-color: #141414;
font: 87.5%/1.5em "Open Sans", sans-serif;
display: flex;
margin: 0;
......
.card-modal-desc {
line-height: 1.6;
font-size: 15px;
font-family: var(--theme-font);
max-height: calc(100% - 237px);
overflow-y: overlay;
&:hover {
&::-webkit-scrollbar-thumb {
background: #535353;
}
}
& > div {
margin-bottom: 6px;
}
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background: #5353533b;
cursor: pointer;
}
.maro-item {
display: flex;
gap: 8px;
}
}
import "./Desc.scss";
import { Fragment } from "react";
export const Desc: React.FC<{ desc?: string }> = ({ desc = "" }) => {
if (!desc) return <></>;
return (
<div className="card-modal-desc">
{/* https://125naroom.com/web/2877 */}
{/* 牛逼的丸文字css教程 */}
<RegexWrapper
text={addSpaces(desc)}
re={/(①|②|③|④|⑤|⑥|⑦|⑧|⑨|⑩):.+?(?=((①|②|③|④|⑤|⑥|⑦|⑧|⑨|⑩):|$))/gs}
Wrapper={MaroListItem}
/>
</div>
);
};
const RegexWrapper: React.FC<{
text: string;
re: RegExp;
Wrapper: React.FunctionComponent<any>;
}> = ({ text, re, Wrapper }) => {
const matches = text.match(re);
if (!matches) return <>{text}</>;
const sepRe = new RegExp(
matches?.reduce((acc, cur) => `${acc}|${cur}`) ?? ""
);
const parts = text.split(sepRe);
return (
<>
{parts.map((part, index) => (
<Fragment key={`${part}-${index}`}>
<div>{part}</div>
{index !== parts.length - 1 && <Wrapper>{matches?.[index]}</Wrapper>}
</Fragment>
))}
</>
);
};
const MaroListItem: React.FC<{ children: string }> = ({ children }) => {
return (
<div className="maro-item">
<span>{children[0]}</span>
<span>
<RegexWrapper
text={children.slice(2)}
re={/●.+?(?=(●|$))/gs}
Wrapper={CircleListItem}
/>
</span>
</div>
);
};
const CircleListItem: React.FC<{ children: string }> = ({ children }) => {
return children ? (
<div className="maro-item">
<span>{children[0]}</span>
<span>{children.slice(1)}</span>
</div>
) : (
<></>
);
};
function addSpaces(str: string): string {
const regex = /\d+/g;
return str.replace(regex, (match) => ` ${match} `);
}
@import url("https://fonts.googleapis.com/css2?family=Electrolize&display=swap");
.card-modal-root {
--theme-font: "Electrolize", sans-serif;
.ant-drawer-content-wrapper {
box-shadow: none;
}
.card-modal-drawer {
width: 90%;
left: 10%;
--height: 640px;
top: calc((100% - var(--height)) / 2);
height: var(--height);
position: relative;
border-radius: 6px;
background: #242424;
.ant-drawer-header {
padding: 10px 0;
button {
margin-right: 0;
}
.ant-drawer-header-title {
flex-direction: row-reverse;
padding-left: 24px;
}
}
}
.card-modal-container {
position: relative;
height: 100%;
}
}
.card-modal-name {
font-weight: bold;
font-size: 1.2rem;
}
.atkLine {
.title,
.number {
font-family: var(--theme-font);
}
.number {
font-size: 30px;
line-height: 36px;
}
}
.attline {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
}
.card-modal-info {
justify-content: space-between;
position: relative;
height: 204px; // TODO - fix this
}
import "@/styles/card-modal.scss";
import classnames from "classnames";
import React from "react";
import React, { FC } from "react";
import { useSnapshot } from "valtio";
import { fetchStrings, sendSelectIdleCmdResponse } from "@/api";
......@@ -13,12 +13,21 @@ import {
extraCardTypes,
Race2StringCodeMap,
Type2StringCodeMap,
} from "../../../common";
import { EffectButton } from "./EffectButton";
} from "../../../../common";
import { EffectButton } from "../EffectButton";
import { Drawer, Space, Tag, Divider, Timeline, Typography } from "antd";
import { LeftOutlined } from "@ant-design/icons";
import "./index.scss";
import { YgoCard } from "@/ui/Shared";
import { Desc } from "./Desc";
const { cardModal } = messageStore;
const NeosConfig = useConfig();
const CARD_WIDTH = 200;
const CARD_WIDTH = 140;
const { Title, Paragraph, Text, Link } = Typography;
export const CardModal = () => {
const snap = useSnapshot(cardModal);
......@@ -35,9 +44,6 @@ export const CardModal = () => {
const def = meta?.data.def;
const counters = snap.counters;
const imgUrl = meta?.id
? `${NeosConfig.cardImgUrl}/${meta.id}.jpg`
: undefined;
const nonEffectInteractivies = snap.interactivies.filter(
(item) => item.desc != "发动效果"
);
......@@ -46,27 +52,43 @@ export const CardModal = () => {
);
return (
<div
className={classnames("card-modal")}
style={
{
"--visibility": isOpen ? "visible" : "hidden",
"--opacity": isOpen ? 1 : 0,
} as any
}
// TODO: 宽度要好好设置 根据屏幕宽度
<Drawer
open={isOpen}
placement="left"
onClose={() => (cardModal.isOpen = false)}
rootClassName="card-modal-root"
className="card-modal-drawer"
headerStyle={{}}
mask={false}
title={name}
closeIcon={<LeftOutlined />}
>
<div className="card-modal-container">
<img src={imgUrl} width={CARD_WIDTH} />
<div className="card-modal-name">{name}</div>
<AttLine
types={extraCardTypes(types || 0)}
race={race}
attribute={attribute}
/>
<AtkLine atk={atk} def={def} />
<CounterLine counters={counters} />
<div className="card-modal-effect">{desc}</div>
{nonEffectInteractivies.map((interactive, idx) => {
<Space
align="start"
size={18}
style={{ position: "relative", display: "flex" }}
>
<YgoCard
code={meta?.id}
width={CARD_WIDTH}
style={{ borderRadius: 4 }}
/>
<Space direction="vertical" className="card-modal-info">
<AtkLine atk={atk} def={def} />
<AttLine
types={extraCardTypes(types || 0)}
race={race}
attribute={attribute}
/>
{/* TODO: 只有怪兽卡需要展示攻击防御 */}
{/* <CounterLine counters={counters} /> */}
</Space>
</Space>
<Divider style={{ margin: "14px 0" }}></Divider>
<Desc desc={desc} />
{/* {nonEffectInteractivies.map((interactive, idx) => {
return (
<button
key={idx}
......@@ -85,9 +107,9 @@ export const CardModal = () => {
</button>
);
})}
<EffectButton meta={meta} effectInteractivies={effectInteractivies} />
<EffectButton meta={meta} effectInteractivies={effectInteractivies} /> */}
</div>
</div>
</Drawer>
);
};
......@@ -98,24 +120,36 @@ const AttLine = (props: {
}) => {
const race = props.race
? fetchStrings("!system", Race2StringCodeMap.get(props.race) || 0)
: "?";
: undefined;
const attribute = props.attribute
? fetchStrings("!system", Attribute2StringCodeMap.get(props.attribute) || 0)
: "?";
: undefined;
const types = props.types
.map((t) => fetchStrings("!system", Type2StringCodeMap.get(t) || 0))
.join("|");
.join("/");
return (
<div className="card-modal-attribute">{`【 ${race} / ${types} 】【 ${attribute} 】`}</div>
<div className="attline">
{attribute && <Tag>{attribute}</Tag>}
{race && <Tag>{race}</Tag>}
{types && <Tag>{types}</Tag>}
</div>
);
};
const AtkLine = (props: { atk?: number; def?: number }) => (
<div className="card-modal-atk">{`ATK/${
props.atk !== undefined ? props.atk : "?"
} DEF/${props.def !== undefined ? props.def : "?"}`}</div>
<Space size={10} className="atkLine" direction="vertical">
<div>
<div className="title">ATK</div>
<div className="number">{props.atk ?? "?"}</div>
</div>
<div>
<div className="title">DEF</div>
<div className="number">{props.def ?? "?"}</div>
</div>
</Space>
);
// TODO: 未完成
const CounterLine = (props: { counters: { [type: number]: number } }) => {
const counters = [];
for (const counterType in props.counters) {
......
......@@ -186,7 +186,18 @@ export const NewSelectActionsModal: FC = () => {
<Tooltip title={card.effectDesc} placement="bottom" key={j}>
<div>
<CheckCard
cover={<YgoCard code={card.meta.id} />}
cover={
<YgoCard
code={card.meta.id}
style={{
width: "100%",
height: "100%",
position: "absolute",
left: 0,
top: 0,
}}
/>
}
style={{
width: 100,
aspectRatio: 5.9 / 8.6,
......
......@@ -19,7 +19,7 @@ section#mat {
height: var(--block-height-m);
width: var(--block-width);
// background-color: rgba(128, 128, 128, 0.447);
background: radial-gradient(#262626, #303030);
background: radial-gradient(#1d1d1d, #222);
// box-shadow: 0 0 0 1px purple;
position: relative;
&.extra {
......@@ -39,8 +39,8 @@ section#mat {
.triangle {
width: 0;
height: 0;
--color: #444444;
border-width: 5px;
--color: #333;
border-width: 4px;
border-style: solid;
position: absolute;
&:nth-of-type(1) {
......
section#mat {
.mat-card {
position: absolute;
// left: 50%;
// top: 50%;
--card-height: 100px;
width: auto !important;
height: var(--card-height);
aspect-ratio: var(--card-ratio);
transform-style: preserve-3d;
......@@ -16,9 +15,14 @@ section#mat {
width: 96%;
transform: translateZ(calc(var(--z) * 1px + 0.1px))
rotateY(calc(var(--ry) * 1deg));
transition: 0.2s scale;
cursor: pointer;
&:hover {
scale: 1.05;
}
.card-cover,
.card-back {
width: 100%;
width: 100% !important;
height: 100%;
position: absolute;
left: 0;
......
......@@ -44,7 +44,7 @@ export const moveToHand = async (props: { card: CardType; api: SpringApi }) => {
const negativeX = Math.sin(angle) * r;
const negativeY = Math.cos(angle) * r + HAND_CARD_HEIGHT.value / 2;
const x = hand_circle_center_x + negativeX * (isMe(controller) ? 1 : -1);
const y = hand_circle_center_y - negativeY + 130; // 常量 是手动调的 这里肯定有问题 有空来修
const y = hand_circle_center_y - negativeY + 140; // 常量 是手动调的 这里肯定有问题 有空来修
const _rz = (angle * 180) / Math.PI;
......
......@@ -61,7 +61,7 @@ export const matConfig = {
unit: UNIT.PX,
},
HAND_CARD_HEIGHT: {
value: 120,
value: 140,
unit: UNIT.PX,
},
DECK_OFFSET_X: {
......
.skeleton-cover {
background-color: gray;
}
.ygo-card {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
......@@ -10,23 +10,30 @@ interface Props {
isBack?: boolean;
code?: number;
style?: CSSProperties;
width?: number;
}
export const YgoCard: FC<Props> = (props) => {
const { className, code: cardCode = 0, isBack = false, style } = props;
const {
className,
code: cardCode = 0,
isBack = false,
width = 80,
style,
} = props;
return useMemo(
() => (
<>
{cardCode === 0 && !isBack ? (
<div
className={classNames("ygo-card", "skeleton-cover")}
style={style}
style={{ width, ...style }}
/>
) : (
<img
className={classNames("ygo-card", className)}
src={getCardImgUrl(cardCode, isBack)}
style={style}
style={{ width, ...style }}
/>
)}
</>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment