transition.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // @ts-nocheck
  2. import { isObj, requestAnimationFrame } from '../common/utils';
  3. const getClassNames = (name) => ({
  4. enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`,
  5. 'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`,
  6. leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`,
  7. 'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`,
  8. });
  9. export function transition(showDefaultValue) {
  10. return Behavior({
  11. properties: {
  12. customStyle: String,
  13. // @ts-ignore
  14. show: {
  15. type: Boolean,
  16. value: showDefaultValue,
  17. observer: 'observeShow',
  18. },
  19. // @ts-ignore
  20. duration: {
  21. type: null,
  22. value: 300,
  23. observer: 'observeDuration',
  24. },
  25. name: {
  26. type: String,
  27. value: 'fade',
  28. },
  29. },
  30. data: {
  31. type: '',
  32. inited: false,
  33. display: false,
  34. },
  35. methods: {
  36. observeShow(value, old) {
  37. if (value === old) {
  38. return;
  39. }
  40. value ? this.enter() : this.leave();
  41. },
  42. enter() {
  43. const { duration, name } = this.data;
  44. const classNames = getClassNames(name);
  45. const currentDuration = isObj(duration) ? duration.enter : duration;
  46. this.status = 'enter';
  47. this.$emit('before-enter');
  48. requestAnimationFrame(() => {
  49. this.checkStatus('enter');
  50. this.$emit('enter');
  51. this.setData({
  52. inited: true,
  53. display: true,
  54. classes: classNames.enter,
  55. currentDuration,
  56. });
  57. requestAnimationFrame(() => {
  58. this.checkStatus('enter');
  59. this.transitionEnded = false;
  60. this.setData({ classes: classNames['enter-to'] });
  61. });
  62. });
  63. },
  64. leave() {
  65. if (!this.data.display) {
  66. return;
  67. }
  68. const { duration, name } = this.data;
  69. const classNames = getClassNames(name);
  70. const currentDuration = isObj(duration) ? duration.leave : duration;
  71. this.status = 'leave';
  72. this.$emit('before-leave');
  73. requestAnimationFrame(() => {
  74. this.checkStatus('leave');
  75. this.$emit('leave');
  76. this.setData({
  77. classes: classNames.leave,
  78. currentDuration,
  79. });
  80. requestAnimationFrame(() => {
  81. this.checkStatus('leave');
  82. this.transitionEnded = false;
  83. setTimeout(() => this.onTransitionEnd(), currentDuration);
  84. this.setData({ classes: classNames['leave-to'] });
  85. });
  86. });
  87. },
  88. checkStatus(status) {
  89. if (status !== this.status) {
  90. throw new Error(`incongruent status: ${status}`);
  91. }
  92. },
  93. onTransitionEnd() {
  94. if (this.transitionEnded) {
  95. return;
  96. }
  97. this.transitionEnded = true;
  98. this.$emit(`after-${this.status}`);
  99. const { show, display } = this.data;
  100. if (!show && display) {
  101. this.setData({ display: false });
  102. }
  103. },
  104. },
  105. });
  106. }