Commit 5f6ce518 authored by timel's avatar timel

feat: finetune animation

parent 53a9bdf4
...@@ -39,8 +39,8 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } = ...@@ -39,8 +39,8 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } =
ygopro.CardZone; ygopro.CardZone;
export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => { export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
const state = cardStore.inner[idx]; const card = cardStore.inner[idx];
const snap = useSnapshot(state); const snap = useSnapshot(card);
const [styles, api] = useSpring( const [styles, api] = useSpring(
() => () =>
...@@ -60,34 +60,32 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -60,34 +60,32 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
} satisfies SpringApiProps) } satisfies SpringApiProps)
); );
// FIXME: move不应该只根据目的地判断,还要根据先前的位置判断。例子是Token。
const move = async (toZone: ygopro.CardZone, fromZone?: ygopro.CardZone) => { const move = async (toZone: ygopro.CardZone, fromZone?: ygopro.CardZone) => {
switch (toZone) { switch (toZone) {
case MZONE: case MZONE:
case SZONE: case SZONE:
await moveToGround({ card: state, api, fromZone }); await moveToGround({ card, api, fromZone });
break; break;
case HAND: case HAND:
await moveToHand({ card: state, api, fromZone }); await moveToHand({ card, api, fromZone });
break; break;
case DECK: case DECK:
case EXTRA: case EXTRA:
await moveToDeck({ card: state, api, fromZone }); await moveToDeck({ card, api, fromZone });
break; break;
case GRAVE: case GRAVE:
case REMOVED: case REMOVED:
await moveToOutside({ card: state, api, fromZone }); await moveToOutside({ card, api, fromZone });
break; break;
case TZONE: case TZONE:
// FIXME: 这里应该实现一个衍生物消散的动画,现在暂时让它在动画在展示上回到卡组 await moveToToken({ card, api, fromZone });
await moveToToken({ card: state, api, fromZone });
break; break;
} }
}; };
// 每张卡都需要移动到初始位置 // 每张卡都需要移动到初始位置
useEffect(() => { useEffect(() => {
move(state.location.zone); move(card.location.zone);
}, []); }, []);
const [highlight, setHighlight] = useState(false); const [highlight, setHighlight] = useState(false);
...@@ -107,18 +105,18 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -107,18 +105,18 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
eventbus.register( eventbus.register(
Task.Move, Task.Move,
async (uuid: string, fromZone?: ygopro.CardZone) => { async (uuid: string, fromZone?: ygopro.CardZone) => {
if (uuid === state.uuid) { if (uuid === card.uuid) {
await addToAnimation(() => move(state.location.zone, fromZone)); await addToAnimation(() => move(card.location.zone, fromZone));
} }
} }
); );
eventbus.register(Task.Focus, async (uuid: string) => { eventbus.register(Task.Focus, async (uuid: string) => {
if (uuid === state.uuid) { if (uuid === card.uuid) {
await addToAnimation(async () => { await addToAnimation(async () => {
setClassFocus(true); setClassFocus(true);
setTimeout(() => setClassFocus(false), 1000); setTimeout(() => setClassFocus(false), 1000);
await focus({ card: state, api }); await focus({ card, api });
}); });
} }
}); });
...@@ -130,9 +128,9 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -130,9 +128,9 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
directAttack: boolean, directAttack: boolean,
target?: ygopro.CardLocation target?: ygopro.CardLocation
) => { ) => {
if (uuid === state.uuid) { if (uuid === card.uuid) {
await addToAnimation(() => await addToAnimation(() =>
attack({ card: state, api, target, directAttack }) attack({ card, api, target, directAttack })
); );
} }
} }
...@@ -286,10 +284,10 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -286,10 +284,10 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
handleDropdownMenu(cards, true); handleDropdownMenu(cards, true);
}; };
if ([MZONE, SZONE, HAND].includes(state.location.zone)) { if ([MZONE, SZONE, HAND].includes(card.location.zone)) {
onCardClick(state); onCardClick(card);
} else if ([EXTRA, GRAVE, REMOVED].includes(state.location.zone)) { } else if ([EXTRA, GRAVE, REMOVED].includes(card.location.zone)) {
onFieldClick(state); onFieldClick(card);
} }
}; };
// <<< 效果 <<< // <<< 效果 <<<
......
...@@ -107,8 +107,9 @@ export const moveToGround: MoveFunc = async (props) => { ...@@ -107,8 +107,9 @@ export const moveToGround: MoveFunc = async (props) => {
ry, ry,
rz, rz,
config: { config: {
// mass: 0.5, tension: 250,
easing: easings.easeInOutSine, clamp: true,
easing: easings.easeOutSine,
}, },
}); });
} }
...@@ -118,10 +119,7 @@ export const moveToGround: MoveFunc = async (props) => { ...@@ -118,10 +119,7 @@ export const moveToGround: MoveFunc = async (props) => {
z: 0, z: 0,
zIndex: is_overlay ? 1 : 3, zIndex: is_overlay ? 1 : 3,
config: { config: {
easing: easings.easeInOutQuad, easing: easings.easeInQuad,
mass: 5,
tension: 300, // 170
friction: 12, // 26
clamp: true, clamp: true,
}, },
}); });
......
...@@ -29,6 +29,9 @@ export const moveToOutside: MoveFunc = async (props) => { ...@@ -29,6 +29,9 @@ export const moveToOutside: MoveFunc = async (props) => {
ry: [ygopro.CardPosition.FACEDOWN].includes(position) ? 180 : 0, ry: [ygopro.CardPosition.FACEDOWN].includes(position) ? 180 : 0,
subZ: 100, subZ: 100,
zIndex: sequence, zIndex: sequence,
config: {
tension: 140,
},
}); });
api.set({ subZ: 0 }); api.set({ subZ: 0 });
}; };
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