useSvgAnimation.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { ref } from 'vue';
  2. /**
  3. * svg二维模型动画使用的钩子,需要配合指定的组件使用,即svg模型组件(README里有更详细的说明)
  4. *
  5. * 备注:一个元素的动画仅有两种状态,正常播放、倒放;例如:`triggerAnimation(id1, false)`代表触发id1对应的动画,false代表触发正常播放的动画
  6. */
  7. export function useSvgAnimation() {
  8. /** 管理节点是否处于初始状态 */
  9. const animationManager = ref<{ [id: string]: boolean }>({});
  10. /**
  11. * 触发动画函数,该函数用来根据id查找SVG图片中的对应group,然后触发绑定在此group上的动画
  12. *
  13. * 动画有且仅有两个状态,一种是初始状态,一种是结束状态,当动画触发后,会根据reverse传参自动切换状态
  14. *
  15. * @param id 标识符号(可以在页面中使用元素选择器选择具体元素后查询其id),可以传数组
  16. * @param reverse 是否需要反向执行动画,如果id传了数组该参数可以传数组以一一匹配,默认为false
  17. */
  18. function triggerAnimation(id: string | string[], reverse: boolean | boolean[] = false) {
  19. const idArray = typeof id === 'string' ? [id] : id;
  20. const reverseArray = typeof reverse === 'boolean' ? idArray.map(() => reverse) : reverse;
  21. idArray.forEach((id, index) => {
  22. if (animationManager.value[id] === undefined) {
  23. animationManager.value[id] = true;
  24. }
  25. const unchanged = animationManager.value[id];
  26. // const element = document.querySelector(`#${id}`) as SVGElement;
  27. // if (!element) return;
  28. // const group = element.parentElement?.parentElement;
  29. // console.log('debug rrrr', element, group);
  30. // if (!group) return;
  31. const reverse = reverseArray[index] || false;
  32. // 不指定反向播放且group处于初始状态时播放正常动画
  33. if (!reverse && unchanged) {
  34. // group.classList.remove(`${id}_animate_reverse`);
  35. // group.classList.add(`${id}_animate`);
  36. animationManager.value[id] = false;
  37. return;
  38. }
  39. if (reverse && !unchanged) {
  40. // group.classList.remove(`${id}_animate`);
  41. // group.classList.add(`${id}_animate_reverse`);
  42. animationManager.value[id] = true;
  43. return;
  44. }
  45. });
  46. }
  47. return {
  48. animationManager,
  49. triggerAnimation,
  50. };
  51. }