Commit 18baf14b authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/ui/chain' into 'main'

Feat/ui/chain

See merge request !200
parents 6fc21e22 df976f6b
Pipeline #21756 passed with stages
in 14 minutes and 20 seconds
......@@ -113,5 +113,13 @@
"73": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
},
"75": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
},
"76": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
}
}
import { ygopro } from "@/api";
import { matStore } from "@/stores";
// FIXME: 处理连锁会存在三种结果:
// 1. Solved - 已处理;
// 2. NEGATED - 被无效;
// 3. DISABLED - 被禁用。
//
// 对于这三种情况`service`层的逻辑是一致的,但是UI展示应该有区别,
// 因为现在还没实现连锁处理的动画,因此暂时先都一致处理,
// 体现在 `penetrage.json`文件中三个一样的配置。
export default (chainSolved: ygopro.StocGameMessage.MsgChainSolved) => {
const location = matStore.chains
.splice(chainSolved.solved_index - 1, 1)
......
......@@ -63,6 +63,11 @@ export default async (move: MsgMove) => {
}
}
if (chainIndex) {
// 如果`chainIndex`不为空,则连锁位置变了,需要更新连锁栈的状态
matStore.chains[chainIndex - 1] = to;
}
switch (to.location) {
// @ts-ignore
case ygopro.CardZone.MZONE: {
......
.circles {
position: relative;
margin: 50% auto;
width: var(--R);
height: var(--R);
font-size: 50px;
}
.circle {
position: absolute;
width: 8px;
height: 8px;
left: var(--x);
bottom: var(--y);
border-radius: 50%;
background-color: #ffff00;
animation: flade 1s ease var(--ease) alternate infinite;
}
.font {
position: absolute;
margin: 25% 30%;
font-size: 50px;
font-style: oblique;
}
@keyframes flade {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
......@@ -5,6 +5,8 @@ import React, { type CSSProperties, MouseEventHandler } from "react";
import { useConfig } from "@/config";
import { Chain } from "./Chain";
const NeosConfig = useConfig();
const ASSETS_BASE =
......@@ -27,6 +29,7 @@ export const Card: React.FC<{
highlight?: boolean;
focus?: boolean;
fly?: boolean;
chainIdx?: number;
transTime?: number;
onClick?: MouseEventHandler<{}>;
style?: CSSProperties;
......@@ -42,6 +45,7 @@ export const Card: React.FC<{
highlight = false,
focus = false,
fly = false,
chainIdx,
transTime = 0.3,
onClick,
style = {},
......@@ -71,5 +75,7 @@ export const Card: React.FC<{
} as any
}
onClick={onClick}
></div>
>
{chainIdx ? <Chain chainIdx={chainIdx} /> : <></>}
</div>
);
import "@/styles/chain.css";
import React from "react";
const CIRCLES_COUNT = 8;
const EASE = 0.2;
const R = 60;
export const Chain: React.FC<{ chainIdx: number }> = (props: {
chainIdx: number;
}) => (
<div
className="circles"
style={
{
"--R": R + "px",
} as any
}
>
{calcXYs(30, CIRCLES_COUNT).map((item, idx) => (
<div
className="circle"
key={idx}
style={
{
"--x": item.X + "px",
"--y": item.Y + "px",
"--ease": (idx * EASE).toString() + "s",
} as any
}
></div>
))}
<div className="font">{props.chainIdx}</div>
</div>
);
// Ref: https://zhuanlan.zhihu.com/p/104226591
/**
* R:大圆半径,2*R = 外部正方形的边长
* counts: 圆的数量
* 返回值:
* [
* [x1,y1],
* [x2,y2],
* ...
* ]
*/
function calcXYs(R: number, counts: number) {
// 当前度数
let deg = 0;
// 单位度数
let pDeg = 360 / counts;
return Array(counts)
.fill(0)
.map((_, i) => {
// 度数以单位度数递增
deg = pDeg * i;
// Math.sin接收的参数以 π 为单位,需要根据360度 = 2π进行转化
const proportion = Math.PI / 180;
// 以外部DIV左下角为原点,计算小圆圆心的横纵坐标
const Y = R + R * Math.sin(proportion * deg);
const X = R + R * Math.cos(proportion * deg);
return { X, Y, deg };
});
}
......@@ -113,6 +113,7 @@ export const Mat = () => {
card.directAttack
}
opponent={card.opponent}
chainIdx={card.chainIndex}
onClick={
card.location.zone == YgoZone.SZONE ||
card.location.zone == YgoZone.MZONE ||
......
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