Flip.batch
Flip.batch(id:String):FlipBatch
协调创建多个Flip动画,按正确的步骤顺序执行以避免相互干扰。
参数
id:字符串
此特定批次的唯一标识符。如果已经存在匹配的标识符,则会返回对应的 FlipBatch。否则,将创建并返回一个新的 FlipBatch。如果你调用了 kill() 方法来销毁某个批次,该批次将被注销,并释放对应的 ID。
返回:FlipBatch
一个 FlipBatch 实例
细节
协调多个 Flip 动画的创建,确保按照正确的步骤顺序执行,以避免交叉污染。例如:所有的getState()
必须首先进行的调用第一步(FIRST)因为其中一个组件的状态变化可能会影响另一个组件中的元素位置或大小。然后所有的状态变化应先发生,最后根据完整的新状态集创建动画。
或许你有多个相互独立的 React 组件都参与了一个 Flip 动画,但需要尽可能地将逻辑封装起来。Flip.batch() 就起到了这样一个中心枢纽的作用。你可以获取到这个 batch 实例(通常是通过一个id
,但这不是必须的),然后创建任意数量的“actions”(每个组件可能对应一个 action),接着run()
以协调的方式执行整个 batch,确保getState()
的调用首先发生,之后是setState()
状态设置,animate()
.
用法
// first create (or get the existing) batch by id
let batch = Flip.batch("id");
现在我们需要用“actions”来填充它。每个 action 可以包含以下任意一项(全部都是可选的):
// add an action to the batch
let action = batch.add({
// record any state objects that you may need in the animate() function. "self" is the action.
getState(self) {
// Use Flip.getState() any number of times in here, return data the way you prefer working with it later via self.state.
return Flip.getState(".box, .container");
},
// make state changes here...
setState(self) {
el.classList.toggle("active");
return gsap.utils.toArray(".box, .container"); // optionally return Array of targets; added to self.targets. Required if you want onEnter/onLeave to fire.
},
animate(self) {
// create as many Flip animations in here as you'd like...
Flip.from(self.state, { duration: 1 });
// self.state = whatever was returned from this action's getState() call
// self.targets = whatever was returned from this action's setState() call
// self.batch = parent batch instance
// self.timeline = flip animation timeline (same as self.batch.timeline - always reused)
},
onEnter(elements) {
// only called when elements are entering (ones that weren't present in the initial state/layout).
// in order for this to work, you must return an Array of targets from .setState()
},
onLeave(elements) {
// only called when elements are leaving (ones that are no longer present compared to the initial state/layout).
// in order for this to work, you must return an Array of targets from .setState()
},
onStart(self) {
// animation started
},
onComplete(self) {
// animation finished
},
once: true, // removes the action from its batch when animate() is called
});
在你add()
添加了你想添加的任意数量的 actions 到 batch 实例之后,你可以简单地batch.run()
调用 run() 方法,
- getState()
- setState()
- animate()
如果我需要等待新状态加载或渲染怎么办?
没问题!你可以从两种策略中选择其一:
-
使用 loadState(done) 方法代替 setState()
loadState() 的神奇之处在于它提供了一个 "done" 函数供你随时调用,因此它实际上会在中途暂停批处理,防止它继续执行 animate() 调用,直到所有 loadState()done
函数都被触发。batch.add({
...
// all done() when you're ready to continue.
loadState(done) {
// Pass targets to done(targets) if you want onEnter/onLeave to work.
done(gsap.utils.toArray(".box, .container"));
}
});-或者-
-
拆分 batch.run()
你可以只触发整个 batch 中的部分内容……垂直位置getState()
首先运行部分 batch...// calls JUST getState() on all of the batch's actions
batch.getState();然后在 batch 外部应用状态更改,批处理之外然后当你准备就绪时……
// true means "skip the .getState() part!"
batch.run(true);完成!
清理工作
你可以kill()
销毁一个 batch……
batch.kill();
……或者单独的某一个 action:
let action = batch.add({...});
// then later...
action.kill();
记住,如果你只想让 action 运行一次,你可以设置once: true
on 该 action 上的属性,当它的 animate() 函数被调用时它会自动被销毁。
Batch 的方法/属性
// flushes all actions and clears the batch.state
batch.clear();
// true means only clear batch.state but keep all the actions
batch.clear(true);
// triggers ONLY the getState() of all actions
batch.getState();
// Searches the state objects that were captured inside ANY of this batch actions' most recent getState() call and returns the first one it finds that matches the provided data-flip-id value. For example, if you Flip.getState("#someID") inside this action's getState() and there's a <div id="#someID" data-flip-id="box1"></div>, you could find that using action.getStateById("box1"); As a last resort, it will search batch.state too.
batch.getStateById("flip-id");
// passing true records a merged copy of ALL the .getState() results into batch.state
batch.getState(true);
// kills entire batch
batch.kill();
// same as action.kill()
batch.remove(action);
// executes the following parts of every action in this order: getState(), loadState(), setState(), animate(), onEnter(), onLeave(), onStart(), onComplete()
batch.run();
// true means "skip the getState() part"
batch.run(true);
// --- PROPERTIES ---
// Array of all the FlipAction instances
batch.actions;
// a place to store any arbitrary data - your choice
batch.data;
// the batch id
batch.id;
// whenever you Flip.getState(targets, {batch: "id"}) it copies the results into the batch.state object. If you batch.getState(true), it'll overwrite the contents with all the ones that occur inside the .getState() of any actions in the batch.
batch.state;
// the timeline instance. All Flip animations created inside animate() will be pushed into this.
batch.timeline;
Action 的方法/属性
// same as batch.getStateById() except that it limits the scope to ones that were captured inside this action's getState() rather than the entire batch.
action.getStateById("flip-id");
// kills just the action (removes it from the batch)
action.kill();
// --- PROPERTIES ---
// the parent batch instance
action.batch;
// whatever was returned by this action's getState()
action.state;
// the batch's timeline (reused) - same as action.batch.timeline
action.timeline;
// whatever was returned by this action's setState() or the done() function in loadState()
action.targets;
演示
下面是一个高级演示,展示了 Flip.batch() 的实际应用:
https://codesandbox.io/s/topeka-quiz-gsap-flip-plugin-rs7lw