<script setup>
import { JsvNinePatch, getKeyFramesGroup } from "jsview";
import { reactive, onBeforeUnmount } from "vue";

const props = defineProps({
  //为了确保多个keyframe动画不重名, 需要传递id
  id: {
    type: String,
    required: true,
  },
  imgUrl: {
    type: String,
  },
  initWidth: {
    type: Number,
    default: 0,
  },
  initHeight: {
    type: Number,
    default: 0,
  },
  initLeft: {
    type: Number,
    default: 0,
  },
  initTop: {
    type: Number,
    default: 0,
  },
});

const styleShell = getKeyFramesGroup();

const animationCache = {};
const addAnimation = (fromRect, toRect, name) => {
  if (animationCache.hasOwnProperty(name)) {
    styleShell.removeRule(name);
    delete animationCache[name];
  }
  if (!(name in animationCache)) {
    const animStr = `@keyframes ${name} {
      0% {
        left: ${fromRect.left};
        top: ${fromRect.top};
        width: ${fromRect.width};
        height: ${fromRect.height};
      }
      50% {
        left: ${Math.min(fromRect.left, toRect.left)};
        top: ${Math.min(fromRect.top, toRect.top)};
        width: ${
          Math.max(fromRect.left + fromRect.width, toRect.left + toRect.width) -
          Math.min(fromRect.left, toRect.left)
        };
        height: ${
          Math.max(fromRect.top + fromRect.height, toRect.top + toRect.height) -
          Math.min(fromRect.top, toRect.top)
        };
      }
      100% {
        left: ${toRect.left};
        top: ${toRect.top};
        width: ${toRect.width};
        height: ${toRect.height};
      }
    }`;
    animationCache[name] = animStr;
    styleShell.insertRule(animStr);
  }
};
const removeAnimation = (name) => {
  styleShell.removeRule(name);
};

const focusSize = reactive({
  width: props.initWidth,
  height: props.initHeight,
  left: props.initLeft,
  top: props.initTop,
  animation: null,
  onTransitionEnd: null,
});

let animateChange = 0; // A B版动画切换，解决animation属性不变化引起不刷新问题
let preRect = null;
let curRect = null;
let first = true;

const changeRect = (rect, doAnim = true) => {
  preRect = curRect;
  curRect = rect;
  if (first) {
    first = false;
  } else if (doAnim) {
    const animName = props.id + animateChange;
    animateChange = animateChange == 0 ? 1 : 0; // A B 版切换
    addAnimation(preRect, curRect, animName);
    focusSize.animation = `${animName} 0.3s linear`;
  }
  focusSize.left = curRect.left;
  focusSize.top = curRect.top;
  focusSize.width = curRect.width;
  focusSize.height = curRect.height;
};

onBeforeUnmount(() => {
  for (let name in animationCache) {
    removeAnimation(name);
  }
});

function onAnimationEnd() {
  console.log("testtest onAnimationEnd")
}

defineExpose({
  changeRect,
});
</script>

<template>
  <jsv-nine-patch
    :style="{
      width: focusSize.width,
      height: focusSize.height,
      top: focusSize.top,
      left: focusSize.left,
    }"
    :animation="focusSize.animation"
    :imageUrl="imgUrl"
    :imageWidth="35"
    :centerWidth="0"
    :borderOutset="0"
    :animTime="0.2"
    :waitForInit="true"
    :onAnimationEnd="onAnimationEnd"
  ></jsv-nine-patch>
</template>
