Commit a80f0ca9 authored by chechunchi's avatar chechunchi

add focus effect

parent 79611cf5
......@@ -72,10 +72,17 @@ export default (move: MsgMove) => {
matStore
.in(to.location)
.of(to.controler)
.setOccupant(to.sequence, code, to.position);
.setOccupant(to.sequence, code, to.position, true);
if (uuid) {
matStore.in(to.location).of(to.controler)[to.sequence].uuid = uuid;
}
setTimeout(
() =>
(matStore.in(to.location).of(to.controler)[to.sequence].focus =
false),
500
);
break;
}
case ygopro.CardZone.REMOVED:
......
import { sendTimeConfirm, ygopro } from "@/api";
import { matStore } from "@/stores";
const TIME_GAP = 800;
export default function handleTimeLimit(timeLimit: ygopro.StocTimeLimit) {
matStore.timeLimits.set(timeLimit.player, timeLimit.left_time);
sendTimeConfirm();
setTimeout(() => {
matStore.timeLimits.set(timeLimit.player, timeLimit.left_time);
sendTimeConfirm();
}, TIME_GAP);
}
......@@ -69,10 +69,12 @@ class CardArray extends Array<CardState> implements ArrayCardState {
async setOccupant(
sequence: number,
id: number,
position?: ygopro.CardPosition
position?: ygopro.CardPosition,
focus?: boolean
) {
const meta = await fetchCard(id);
const target = this[sequence];
target.focus = focus;
target.occupant = meta;
if (position) {
target.location.position = position;
......
......@@ -31,7 +31,8 @@ export interface DuelFieldState extends Array<CardState> {
setOccupant: (
sequence: number,
id: number,
position?: ygopro.CardPosition
position?: ygopro.CardPosition,
focus?: boolean
) => Promise<void>;
/** 添加 idle 的交互性 */
addIdleInteractivity: (
......@@ -117,6 +118,7 @@ export interface CardState {
zone: ygopro.CardZone; // 怪兽区/魔法陷阱区/手牌/卡组/墓地/除外区
position?: ygopro.CardPosition; // 卡片的姿势:攻击还是守备
}; // 位置信息,叫location的原因是为了和ygo对齐
focus?: boolean;
idleInteractivities: Interactivity<number>[]; // IDLE状态下的互动信息
placeInteractivity?: Interactivity<{
controler: number;
......
......@@ -100,7 +100,7 @@ button:focus-visible {
--x: calc(var(--x-margin-left) + var(--x-padding));
--y: calc(var(--r) * calc(var(--block-height) + var(--block-row-gap)));
--z: calc(var(--h) * 1px);
transform: translateZ(var(--z)) rotateX(calc(var(--hand-rotate) * var(--vertical)));
transform: translateZ(var(--z)) rotateX(calc(var(--hand-rotate) * var(--vertical))) scale(var(--scale-focus));
translate: var(--x) var(--y);
rotate: calc(var(--opponent-deg) * (1 - var(--vertical)));
transform-style: preserve-3d;
......
......@@ -12,6 +12,9 @@ const ASSETS_BASE =
? NeosConfig.assetsPath
: import.meta.env.BASE_URL + NeosConfig.assetsPath;
const FOCUS_SCALE = 2.5;
const FOCUS_HIGHT = 100;
export const Card: React.FC<{
code: number;
row: number;
......@@ -23,6 +26,7 @@ export const Card: React.FC<{
vertical?: boolean;
highlight?: boolean;
fly?: boolean;
focus?: boolean;
transTime?: number;
onClick?: MouseEventHandler<{}>;
style?: CSSProperties;
......@@ -37,6 +41,7 @@ export const Card: React.FC<{
vertical = false,
highlight = false,
fly = false,
focus = false,
transTime = 0.3,
onClick,
style = {},
......@@ -48,7 +53,7 @@ export const Card: React.FC<{
})}
style={
{
"--h": hight,
"--h": focus ? FOCUS_HIGHT : hight,
"--r": row,
"--c": col,
"--shadow": hight > 0 ? 1 : 0,
......@@ -56,6 +61,7 @@ export const Card: React.FC<{
"--vertical": vertical ? 1 : 0,
"--trans-time": `${transTime}s`,
"--highlight-on": highlight ? 1 : 0,
"--scale-focus": focus ? FOCUS_SCALE : 1,
"--card-img": facedown
? `url(${ASSETS_BASE + "/card_back.jpg"})`
: `url(${NeosConfig.cardImgUrl + "/" + code + ".jpg"})`,
......
......@@ -100,8 +100,9 @@ export const Mat = () => {
card.location.position === YgoPosition.FACEUP_DEFENSE
}
facedown={CardStateToFaceDown(card)}
vertical={card.location.zone == YgoZone.HAND}
vertical={card.location.zone == YgoZone.HAND || card.focus}
highlight={card.idleInteractivities.length > 0}
focus={card.focus && card.occupant?.id !== 0}
opponent={card.opponent}
onClick={
card.location.zone == YgoZone.SZONE ||
......@@ -121,6 +122,7 @@ export const Mat = () => {
};
function cardStateToRow(state: RenderCard): number {
if (state.focus) return 2;
if (state.opponent) {
switch (state.location.zone) {
case YgoZone.EXTRA:
......@@ -161,6 +163,7 @@ function cardStateToRow(state: RenderCard): number {
}
function cardStateToCol(state: RenderCard): number {
if (state.focus) return 2;
if (state.opponent) {
switch (state.location.zone) {
case YgoZone.EXTRA:
......@@ -223,6 +226,7 @@ function CardStateToHigh(state: RenderCard): number {
}
function CardStateToFaceDown(state: RenderCard): boolean {
if (state.focus && state.occupant?.id !== 0) return false;
const position = state.location.position;
return (
......
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