| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { addUniqueItem, removeItem } from 'motion-utils';
- class NodeStack {
- constructor() {
- this.members = [];
- }
- add(node) {
- addUniqueItem(this.members, node);
- node.scheduleRender();
- }
- remove(node) {
- removeItem(this.members, node);
- if (node === this.prevLead) {
- this.prevLead = undefined;
- }
- if (node === this.lead) {
- const prevLead = this.members[this.members.length - 1];
- if (prevLead) {
- this.promote(prevLead);
- }
- }
- }
- relegate(node) {
- const indexOfNode = this.members.findIndex((member) => node === member);
- if (indexOfNode === 0)
- return false;
- /**
- * Find the next projection node that is present
- */
- let prevLead;
- for (let i = indexOfNode; i >= 0; i--) {
- const member = this.members[i];
- if (member.isPresent !== false) {
- prevLead = member;
- break;
- }
- }
- if (prevLead) {
- this.promote(prevLead);
- return true;
- }
- else {
- return false;
- }
- }
- promote(node, preserveFollowOpacity) {
- const prevLead = this.lead;
- if (node === prevLead)
- return;
- this.prevLead = prevLead;
- this.lead = node;
- node.show();
- if (prevLead) {
- prevLead.instance && prevLead.scheduleRender();
- node.scheduleRender();
- node.resumeFrom = prevLead;
- if (preserveFollowOpacity) {
- node.resumeFrom.preserveOpacity = true;
- }
- if (prevLead.snapshot) {
- node.snapshot = prevLead.snapshot;
- node.snapshot.latestValues =
- prevLead.animationValues || prevLead.latestValues;
- }
- if (node.root && node.root.isUpdating) {
- node.isLayoutDirty = true;
- }
- const { crossfade } = node.options;
- if (crossfade === false) {
- prevLead.hide();
- }
- /**
- * TODO:
- * - Test border radius when previous node was deleted
- * - boxShadow mixing
- * - Shared between element A in scrolled container and element B (scroll stays the same or changes)
- * - Shared between element A in transformed container and element B (transform stays the same or changes)
- * - Shared between element A in scrolled page and element B (scroll stays the same or changes)
- * ---
- * - Crossfade opacity of root nodes
- * - layoutId changes after animation
- * - layoutId changes mid animation
- */
- }
- }
- exitAnimationComplete() {
- this.members.forEach((node) => {
- const { options, resumingFrom } = node;
- options.onExitComplete && options.onExitComplete();
- if (resumingFrom) {
- resumingFrom.options.onExitComplete &&
- resumingFrom.options.onExitComplete();
- }
- });
- }
- scheduleRender() {
- this.members.forEach((node) => {
- node.instance && node.scheduleRender(false);
- });
- }
- /**
- * Clear any leads that have been removed this render to prevent them from being
- * used in future animations and to prevent memory leaks
- */
- removeLeadSnapshot() {
- if (this.lead && this.lead.snapshot) {
- this.lead.snapshot = undefined;
- }
- }
- }
- export { NodeStack };
|