Преглед изворни кода

[Feat 0000] 为SVG动画控制Hook添加了进度控制功能

houzekong пре 2 недеља
родитељ
комит
e4780829c7
1 измењених фајлова са 12 додато и 7 уклоњено
  1. 12 7
      src/hooks/vent/useSvgAnimation.ts

+ 12 - 7
src/hooks/vent/useSvgAnimation.ts

@@ -1,4 +1,5 @@
 import { ref } from 'vue';
+import _ from 'lodash';
 
 /**
  * svg二维模型动画使用的钩子,需要配合指定的组件使用,即svg模型组件(README里有更详细的说明)
@@ -18,8 +19,10 @@ export function useSvgAnimation(elementInfo: Map<string, { key: string; transfor
    *
    * @param id 标识符号(可以在页面中使用元素选择器选择具体元素后查询其id),可以传数组
    * @param reverse 是否需要反向执行动画,如果id传了数组该参数可以传数组以一一匹配,默认为false
+   * @param duration 动画持续时长,越长动画执行的越慢
+   * @param progress 指定动画执行的进度,默认为1,即动画执行到100%,该数字范围为0-1
    */
-  function triggerAnimation(id: string | string[], reverse: boolean | boolean[] = false, duration = 3000) {
+  function triggerAnimation(id: string | string[], reverse: boolean | boolean[] = false, duration = 3000, progress = 1) {
     const idArray = typeof id === 'string' ? [id] : id;
     const reverseArray = typeof reverse === 'boolean' ? idArray.map(() => reverse) : reverse;
 
@@ -33,34 +36,36 @@ export function useSvgAnimation(elementInfo: Map<string, { key: string; transfor
       // 不指定反向播放且group处于初始状态时播放正常动画
       if (!reverse && unchanged) {
         animationManager.value[id] = false;
-        animateByKey(id, true, duration);
+        animateByKey(id, true, duration, progress);
         return;
       }
       if (reverse && !unchanged) {
         animationManager.value[id] = true;
-        animateByKey(id, false, duration);
+        animateByKey(id, false, duration, progress);
         return;
       }
     });
   }
 
   // 直接控制动画的方法
-  const animateElement = (elementId: string, toEnd: boolean, duration: number = 3000) => {
+  const animateElement = (elementId: string, toEnd: boolean, duration = 3000, progress = 1) => {
     const el = animationElements.get(elementId);
     const info = elementInfo.get(elementId);
 
     if (el && info && info.transforms.length > 1) {
+      const endTransform = _.nth(info.transforms, Math.floor(info.transforms.length * progress));
+      const startTransform = _.nth(info.transforms, -Math.ceil(info.transforms.length * progress));
       el.style.transition = `transform ${duration}ms`;
-      el.setAttribute('transform', toEnd ? info.transforms[info.transforms.length - 1] : info.transforms[0]);
+      el.setAttribute('transform', toEnd ? endTransform : startTransform);
     }
   };
 
   // 批量控制同一key的所有元素
-  const animateByKey = (key: string, toEnd: boolean, duration: number = 3000) => {
+  const animateByKey = (key: string, toEnd: boolean, duration = 3000, progress = 1) => {
     animationElements.forEach((__, elementId) => {
       const info = elementInfo.get(elementId);
       if (info && info.key === key) {
-        animateElement(elementId, toEnd, duration);
+        animateElement(elementId, toEnd, duration, progress);
       }
     });
   };