uni-transition.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. "use strict";
  2. const uni_modules_uniTransition_components_uniTransition_createAnimation = require("./createAnimation.js");
  3. const common_vendor = require("../../../../common/vendor.js");
  4. const _sfc_main = {
  5. name: "uniTransition",
  6. emits: ["click", "change"],
  7. props: {
  8. show: {
  9. type: Boolean,
  10. default: false
  11. },
  12. modeClass: {
  13. type: [Array, String],
  14. default() {
  15. return "fade";
  16. }
  17. },
  18. duration: {
  19. type: Number,
  20. default: 300
  21. },
  22. styles: {
  23. type: Object,
  24. default() {
  25. return {};
  26. }
  27. },
  28. customClass: {
  29. type: String,
  30. default: ""
  31. },
  32. onceRender: {
  33. type: Boolean,
  34. default: false
  35. }
  36. },
  37. data() {
  38. return {
  39. isShow: false,
  40. transform: "",
  41. opacity: 0,
  42. animationData: {},
  43. durationTime: 300,
  44. config: {}
  45. };
  46. },
  47. watch: {
  48. show: {
  49. handler(newVal) {
  50. if (newVal) {
  51. this.open();
  52. } else {
  53. if (this.isShow) {
  54. this.close();
  55. }
  56. }
  57. },
  58. immediate: true
  59. }
  60. },
  61. computed: {
  62. // 生成样式数据
  63. stylesObject() {
  64. let styles = {
  65. ...this.styles,
  66. "transition-duration": this.duration / 1e3 + "s"
  67. };
  68. let transform = "";
  69. for (let i in styles) {
  70. let line = this.toLine(i);
  71. transform += line + ":" + styles[i] + ";";
  72. }
  73. return transform;
  74. },
  75. // 初始化动画条件
  76. transformStyles() {
  77. return "transform:" + this.transform + ";opacity:" + this.opacity + ";" + this.stylesObject;
  78. }
  79. },
  80. created() {
  81. this.config = {
  82. duration: this.duration,
  83. timingFunction: "ease",
  84. transformOrigin: "50% 50%",
  85. delay: 0
  86. };
  87. this.durationTime = this.duration;
  88. },
  89. methods: {
  90. /**
  91. * ref 触发 初始化动画
  92. */
  93. init(obj = {}) {
  94. if (obj.duration) {
  95. this.durationTime = obj.duration;
  96. }
  97. this.animation = uni_modules_uniTransition_components_uniTransition_createAnimation.createAnimation(Object.assign(this.config, obj), this);
  98. },
  99. /**
  100. * 点击组件触发回调
  101. */
  102. onClick() {
  103. this.$emit("click", {
  104. detail: this.isShow
  105. });
  106. },
  107. /**
  108. * ref 触发 动画分组
  109. * @param {Object} obj
  110. */
  111. step(obj, config = {}) {
  112. if (!this.animation)
  113. return this;
  114. Object.keys(obj).forEach((key) => {
  115. const value = obj[key];
  116. if (typeof this.animation[key] === "function") {
  117. Array.isArray(value) ? this.animation[key](...value) : this.animation[key](value);
  118. }
  119. });
  120. this.animation.step(config);
  121. return this;
  122. },
  123. /**
  124. * ref 触发 执行动画
  125. */
  126. run(fn) {
  127. if (!this.animation)
  128. return;
  129. this.animation.run(fn);
  130. },
  131. // 开始过度动画
  132. open() {
  133. clearTimeout(this.timer);
  134. this.isShow = true;
  135. this.transform = this.styleInit(false).transform || "";
  136. this.opacity = this.styleInit(false).opacity || 0;
  137. this.$nextTick(() => {
  138. this.timer = setTimeout(() => {
  139. this.animation = uni_modules_uniTransition_components_uniTransition_createAnimation.createAnimation(this.config, this);
  140. this.tranfromInit(false).step();
  141. this.animation.run(() => {
  142. this.transform = "";
  143. this.opacity = this.styleInit(false).opacity || 1;
  144. this.$emit("change", {
  145. detail: this.isShow
  146. });
  147. });
  148. }, 80);
  149. });
  150. },
  151. // 关闭过度动画
  152. close(type) {
  153. if (!this.animation)
  154. return;
  155. this.tranfromInit(true).step().run(() => {
  156. this.isShow = false;
  157. this.animationData = null;
  158. this.animation = null;
  159. let { opacity, transform } = this.styleInit(false);
  160. this.opacity = opacity || 1;
  161. this.transform = transform;
  162. this.$emit("change", {
  163. detail: this.isShow
  164. });
  165. });
  166. },
  167. // 处理动画开始前的默认样式
  168. styleInit(type) {
  169. let styles = { transform: "", opacity: 1 };
  170. const buildStyle = (type2, mode) => {
  171. const value = this.animationType(type2)[mode];
  172. if (mode.startsWith("fade")) {
  173. styles.opacity = value;
  174. } else {
  175. styles.transform += value + " ";
  176. }
  177. };
  178. if (typeof this.modeClass === "string") {
  179. buildStyle(type, this.modeClass);
  180. } else {
  181. this.modeClass.forEach((mode) => buildStyle(type, mode));
  182. }
  183. return styles;
  184. },
  185. // 处理内置组合动画
  186. tranfromInit(type) {
  187. let buildTranfrom = (type2, mode) => {
  188. let aniNum = null;
  189. if (mode === "fade") {
  190. aniNum = type2 ? 0 : 1;
  191. } else {
  192. aniNum = type2 ? "-100%" : "0";
  193. if (mode === "zoom-in") {
  194. aniNum = type2 ? 0.8 : 1;
  195. }
  196. if (mode === "zoom-out") {
  197. aniNum = type2 ? 1.2 : 1;
  198. }
  199. if (mode === "slide-right") {
  200. aniNum = type2 ? "100%" : "0";
  201. }
  202. if (mode === "slide-bottom") {
  203. aniNum = type2 ? "100%" : "0";
  204. }
  205. }
  206. this.animation[this.animationMode()[mode]](aniNum);
  207. };
  208. if (typeof this.modeClass === "string") {
  209. buildTranfrom(type, this.modeClass);
  210. } else {
  211. this.modeClass.forEach((mode) => {
  212. buildTranfrom(type, mode);
  213. });
  214. }
  215. return this.animation;
  216. },
  217. animationType(type) {
  218. return {
  219. fade: type ? 1 : 0,
  220. "slide-top": `translateY(${type ? "0" : "-100%"})`,
  221. "slide-right": `translateX(${type ? "0" : "100%"})`,
  222. "slide-bottom": `translateY(${type ? "0" : "100%"})`,
  223. "slide-left": `translateX(${type ? "0" : "-100%"})`,
  224. "zoom-in": `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
  225. "zoom-out": `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
  226. };
  227. },
  228. // 内置动画类型与实际动画对应字典
  229. animationMode() {
  230. return {
  231. fade: "opacity",
  232. "slide-top": "translateY",
  233. "slide-right": "translateX",
  234. "slide-bottom": "translateY",
  235. "slide-left": "translateX",
  236. "zoom-in": "scale",
  237. "zoom-out": "scale"
  238. };
  239. },
  240. // 驼峰转中横线
  241. toLine(name) {
  242. return name.replace(/([A-Z])/g, "-$1").toLowerCase();
  243. }
  244. }
  245. };
  246. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  247. return {
  248. a: $data.isShow,
  249. b: $data.animationData,
  250. c: common_vendor.n($props.customClass),
  251. d: common_vendor.s($options.transformStyles),
  252. e: common_vendor.o((...args) => $options.onClick && $options.onClick(...args))
  253. };
  254. }
  255. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  256. wx.createComponent(Component);
  257. //# sourceMappingURL=../../../../../.sourcemap/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.js.map