mirror of
https://ghproxy.com/https://github.com/StreakingMan/solvable-sheep-game
synced 2025-05-24 03:36:09 +08:00
chore: 提示面板封装
This commit is contained in:
parent
557a6a705a
commit
84fa8483d9
|
@ -9,4 +9,7 @@ module.exports = {
|
|||
'stylelint-config-standard-scss',
|
||||
'stylelint-config-prettier-scss',
|
||||
],
|
||||
rules: {
|
||||
'selector-class-pattern': '^[a-z][a-zA-Z0-9]+$',
|
||||
},
|
||||
};
|
||||
|
|
63
src/components/FixedAnimateScalePanel.module.scss
Normal file
63
src/components/FixedAnimateScalePanel.module.scss
Normal file
|
@ -0,0 +1,63 @@
|
|||
.panel {
|
||||
position: fixed;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
transition: 0.3s;
|
||||
padding: 16px;
|
||||
background-color: rgb(0 0 0/ 50%);
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(8px);
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
|
||||
> * {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&.leftBottom {
|
||||
left: 8px;
|
||||
bottom: 8px;
|
||||
}
|
||||
|
||||
.closeBtn {
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
background-color: rgb(0 0 0/20%);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: scale(0);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&.open {
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
cursor: default;
|
||||
z-index: 5 !important;
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 16px);
|
||||
}
|
||||
@media screen and (min-width: 501px) {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
> * {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.closeBtn {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
48
src/components/FixedAnimateScalePanel.tsx
Normal file
48
src/components/FixedAnimateScalePanel.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React, { FC, ReactNode, useState } from 'react';
|
||||
import style from './FixedAnimateScalePanel.module.scss';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export const FixedAnimateScalePanel: FC<{
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
openClassName?: string;
|
||||
closeClassName?: string;
|
||||
initOpen?: boolean;
|
||||
}> = ({
|
||||
children,
|
||||
className,
|
||||
openClassName,
|
||||
closeClassName,
|
||||
initOpen = false,
|
||||
}) => {
|
||||
const [open, setOpen] = useState<boolean>(initOpen);
|
||||
return (
|
||||
<div
|
||||
onClick={() => !open && setOpen(true)}
|
||||
className={classNames(
|
||||
style.panel,
|
||||
open && style.open,
|
||||
className,
|
||||
open ? openClassName : closeClassName
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
<div className={style.closeBtn} onClick={() => setOpen(false)}>
|
||||
<svg
|
||||
width="13"
|
||||
height="14"
|
||||
viewBox="0 0 13 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.9498 7.04945L0 11.9993L1.41421 13.4135L6.36401 8.46367L11.3138 13.4135L12.728 11.9993L7.77823 7.04945L12.7279 2.09976L11.3137 0.685547L6.36401 5.63524L1.41432 0.685547L0.0001055 2.09976L4.9498 7.04945Z"
|
||||
fill="#888888"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,24 +1,9 @@
|
|||
/* 可封装 */
|
||||
.info {
|
||||
position: fixed;
|
||||
left: 8px;
|
||||
bottom: 8px;
|
||||
transition: 0.3s;
|
||||
padding: 16px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
background: rgb(0 0 0/ 50%);
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(8px);
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
transition: 0.6s;
|
||||
}
|
||||
|
||||
|
@ -33,41 +18,12 @@
|
|||
font-size: 24px;
|
||||
font-weight: 900;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
background-color: rgb(0 0 0/20%);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
transform: scale(0);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&.open {
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
@media screen and (min-width: 501px) {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
p {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.close {
|
||||
transform: scale(1);
|
||||
&.open {
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import React, { CSSProperties, FC, useState } from 'react';
|
||||
import React, { FC } from 'react';
|
||||
import style from './Info.module.scss';
|
||||
import classNames from 'classnames';
|
||||
import { FixedAnimateScalePanel } from './FixedAnimateScalePanel';
|
||||
export const Info: FC = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<div
|
||||
onClick={() => !open && setOpen(true)}
|
||||
className={classNames(style.info, open && style.open)}
|
||||
<FixedAnimateScalePanel
|
||||
className={style.info}
|
||||
openClassName={style.open}
|
||||
>
|
||||
<div className={style.icon}>i</div>
|
||||
<p>
|
||||
|
@ -16,11 +15,27 @@ export const Info: FC = () => {
|
|||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
洛天依,言和原创《普通DISCO》
|
||||
普通DISCO(言洛版)
|
||||
</a>
|
||||
、
|
||||
<a
|
||||
href="https://music.163.com/#/song?id=135022"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
贫民百万歌星
|
||||
</a>
|
||||
、
|
||||
<a
|
||||
href="https://y.qq.com/n/ryqq/songDetail/0020Nusb3QJGn9"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
只因你太美
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
玩法来源➡️羊了个羊➡️
|
||||
玩法来源-{'>'}羊了个羊-{'>'}
|
||||
<a
|
||||
href="https://play.google.com/store/apps/details?id=tile.master.connect.matching.game"
|
||||
target="_blank"
|
||||
|
@ -28,11 +43,16 @@ export const Info: FC = () => {
|
|||
>
|
||||
3 Tiles
|
||||
</a>
|
||||
-{'>'}
|
||||
<a
|
||||
href="https://www.bilibili.com/video/BV1zT411N7RT"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
中国龙
|
||||
</a>
|
||||
</p>
|
||||
<p>仅供交流,禁止商用</p>
|
||||
<div className={style.close} onClick={() => setOpen(false)}>
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
</FixedAnimateScalePanel>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,14 +12,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
position: fixed;
|
||||
.personalInfo {
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
padding: 4px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
animation: gradient 4s ease infinite;
|
||||
background-image: linear-gradient(
|
||||
-45deg,
|
||||
|
@ -30,12 +25,8 @@
|
|||
);
|
||||
background-size: 400% 400%;
|
||||
background-position: 0 0;
|
||||
box-sizing: border-box;
|
||||
transition: 0.4s;
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 9;
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
|
||||
* {
|
||||
transition: 0.6s;
|
||||
|
@ -47,28 +38,13 @@
|
|||
font-weight: 900;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
background-color: rgb(0 0 0/20%);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
transform: scale(0);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.github {
|
||||
&Icon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
cursor: pointer;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
&Link {
|
||||
|
@ -93,18 +69,8 @@
|
|||
}
|
||||
|
||||
&.open {
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 16px);
|
||||
}
|
||||
@media screen and (min-width: 501px) {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.close {
|
||||
transform: scale(1);
|
||||
width: calc(100% - 60px) !important;
|
||||
}
|
||||
|
||||
.github {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { FC, useState } from 'react';
|
||||
import style from './PersonalInfo.module.scss';
|
||||
import classNames from 'classnames';
|
||||
import { FixedAnimateScalePanel } from './FixedAnimateScalePanel';
|
||||
|
||||
const GithubIcon: FC = () => {
|
||||
return (
|
||||
|
@ -63,19 +64,15 @@ export const BiliBiliLink: FC = () => {
|
|||
};
|
||||
|
||||
export const PersonalInfo: FC = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<div
|
||||
onClick={() => !open && setOpen(true)}
|
||||
className={classNames(style.info, open && style.open)}
|
||||
<FixedAnimateScalePanel
|
||||
className={style.personalInfo}
|
||||
openClassName={style.open}
|
||||
>
|
||||
<GithubIcon />
|
||||
<GithubLink />
|
||||
<BiliBiliIcon />
|
||||
<BiliBiliLink />
|
||||
<div className={style.close} onClick={() => setOpen(false)}>
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
</FixedAnimateScalePanel>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user