Commit 41a262fd authored by timel's avatar timel

feat: background and some styles

parent 79f28027
Pipeline #22870 failed with stages
in 11 minutes and 52 seconds
......@@ -114,4 +114,5 @@ nav {
body {
--theme-font: "Electrolize", sans-serif;
--nav-height: 48px;
}
.navbar {
--height: 48px;
width: 100%;
height: var(--height);
height: var(--nav-height);
display: flex;
flex-wrap: wrap;
align-items: center;
......@@ -18,7 +17,7 @@
font-family: sans-serif;
text-decoration: none;
font-size: 0.825rem;
line-height: var(--height);
line-height: var(--nav-height);
transition: 0.3s;
&:hover {
opacity: 0.8;
......
.main {
position: fixed;
top: var(--nav-height);
height: calc(100% - var(--nav-height));
width: 100%;
display: flex;
justify-content: center;
align-items: center;
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: 75px;
}
}
// 奇奇怪怪的bug
:global(.ant-select .ant-select-selection-item) {
flex: initial;
}
.custom-select {
display: flex;
align-items: center;
.prefix {
height: 40px;
line-height: 40px;
border: 1px solid #424242;
padding: 0 1rem;
border-radius: 6px;
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
background-color: rgba(255, 255, 255, 0.08);
}
.select :global(.ant-select-selector) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
background: none;
}
:global(.ant-select-open .ant-select-selector) {
background: rgba(0, 0, 0, 0.3);
}
}
.mode-select {
display: grid;
grid-template-columns: 1fr 1fr 1.75fr; /* 三列 */
grid-template-rows: auto; /* 自动调整行高 */
gap: 40px 34px; /* 行和列的间隔 */
width: 1000px;
height: 414px;
.rank {
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.fun {
grid-column: 2 / 3;
grid-row: 1 / 3;
}
.solo {
grid-column: 3 / 4;
}
.custom {
grid-column: 3 / 4;
}
.mode {
height: -webkit-fill-available;
border-radius: 20px;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.05) 100%
);
border: 1px solid rgba(255, 255, 255, 0.2);
}
}
import { Link, type LoaderFunction } from "react-router-dom";
import { accountStore, type User } from "@/stores";
import { setCookie, CookieKeys } from "@/ui/Shared";
import { setCookie, CookieKeys, Background } from "@/ui/Shared";
import styles from "./index.module.scss";
import { Select, Space } from "antd";
import classNames from "classnames";
export const loader: LoaderFunction = () => {
const sso = new URLSearchParams(location.search).get("sso");
......@@ -12,15 +15,68 @@ export const loader: LoaderFunction = () => {
return null;
};
export const Component: React.FC = () => (
<>
new match
<Link to="/waitroom/1/2/3">waitroom</Link>
</>
);
export const Component: React.FC = () => {
return (
<>
<Background />
<main className={styles.main}>
<div className={styles.container}>
<Space size={16}>
<CustomSelect
title="服务器"
defaultValue="lucy"
style={{ width: 370 }}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
<CustomSelect
title="卡组"
showSearch
defaultValue="lucy"
style={{ width: 370 }}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</Space>
<div className={styles["mode-select"]}>
<div className={classNames(styles.mode, styles.rank)}>竞技匹配</div>
<div className={classNames(styles.mode, styles.fun)}>娱乐匹配</div>
<div className={classNames(styles.mode, styles.solo)}>单人模式</div>
<div className={classNames(styles.mode, styles.custom)}>
自定义房间
</div>
</div>
</div>
</main>
</>
);
};
Component.displayName = "Match";
/** 从SSO跳转回的URL之中,解析用户信息 */
function getSSOUser(searchParams: URLSearchParams): User {
return Object.fromEntries(searchParams) as unknown as User;
}
const CustomSelect: React.FC<
React.ComponentProps<typeof Select> & { title: string }
> = ({ title, className, ...rest }) => {
return (
<div className={styles["custom-select"]}>
<span className={styles.prefix}>{title}</span>
<Select
className={classNames(styles.select, className)}
size="large"
{...rest}
/>
</div>
);
};
.background {
position: fixed;
left: 0;
top: 0;
height: 100%;
max-height: 100%;
overflow: hidden;
width: 100%;
background-color: #010514;
z-index: -1;
display: flex;
justify-content: center;
align-items: center;
}
.inner {
width: 90vw;
height: 50vh;
background: rgba(72, 0, 255, 0.6);
filter: blur(582px);
}
import { useEffect } from "react";
import styles from "./index.module.scss";
import { render, unmountComponentAtNode } from "react-dom";
const _Background: React.FC<{
style?: React.CSSProperties;
innerStyle?: React.CSSProperties;
}> = ({ style, innerStyle }) => {
return (
<div className={styles.background} style={style}>
<div className={styles.inner} style={innerStyle}></div>
</div>
);
};
/** HOC: 将组件发射到body下 */
const withPortalToBody = <P extends object>(
WrappedComponent: React.ComponentType<P>
) => {
return (props: P) => {
useEffect(() => {
// 创建一个新的容器元素
const portalRoot = document.body;
const firstChild = portalRoot.firstChild;
const newNode = document.createElement("div");
portalRoot.insertBefore(newNode, firstChild);
// 渲染组件到新的容器中
render(<WrappedComponent {...props} />, newNode);
return () => {
// 卸载组件并且移除容器
unmountComponentAtNode(newNode);
portalRoot.removeChild(newNode);
};
}, []);
return null; // 返回null,避免在原来的位置渲染任何东西
};
};
export const Background = withPortalToBody(_Background);
......@@ -2,3 +2,4 @@ export * from "./css";
export * from "./IconFont";
export * from "./YgoCard";
export * from "./cookies";
export * from "./Background";
import { RightOutlined } from "@ant-design/icons";
import React from "react";
import { useNavigate } from "react-router-dom";
import { accountStore } from "@/stores";
import { useConfig } from "@/config";
import styles from "./index.module.scss";
import { useSnapshot } from "valtio";
import { Background } from "@/ui/Shared";
const NeosConfig = useConfig();
......@@ -13,6 +13,7 @@ export const Component: React.FC = () => {
const { user } = useSnapshot(accountStore);
return (
<>
<Background />
<div className={styles.wrapper}>
{/* <div className={styles["particles-container"]}>
{Array.from({ length: 100 }).map((_, key) => (
......
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