动画方案设想
如果单纯依赖于store的变化来进行ui动画,因为card本身是存在不同的list之中的,flip动画是一个可能的方案,但是这么做会遇到一个很棘手的问题——动画前后卡对应的state不是同一个。在move之中,我们是先删掉一个旧的state,再增加一个新的state。即使我们可以使用id等技术,但动画还是非常难以实现。
一个比较好的解决方案:
核心在于:决斗盘不和store直接挂钩,场上的卡片实际上和store之中存储的card是不一样的。
我们将显示的卡片(ui之中)和隐藏的卡片(store之中)分别叫做ui卡和store卡。ui卡和store卡之间互相绑定。
当move.ts之中:
- 卡从墓地、卡组、额外、除外等隐藏区出现时,将ui卡添加到dom。此时播放登场动画:
- store之中occupant/insert一张store卡。
- 渲染一张ui卡,ui卡设置基础数据(img等),ui卡和to的store卡互相绑定。
- 根据from和to,计算ui卡的先后位置a和b。使用spring等库,令卡从a移动到b。
- 卡在场上移动
- 根据from和to,决定动画类型
- 根据from找到store卡,从store卡找到ui卡,记录初始位置a
- 根据to,记录结束位置b
- 根据to,维护ui卡、新的store卡、旧的store卡之间的绑定关系
- 动画:根据动画类型,进行a -> b的动画
- 卡片交互性
- 由ui卡找到store卡/由store卡找到ui卡即可,因为是互相绑定的,所以实现起来也并不复杂
一些可以预想的优化点:
- 预渲染几张隐藏的ui卡在dom之中,减少卡出现的渲染时间
- 播放动画时候应该有一个动画锁/动画队列,避免动画冲突
- 使用一些useGesture/useDrag等库,从而实现拖动效果
- ...