<!--
 * 【模块 export 内容】
 * JsvCouplets：春联组件
 *      props说明:
 *          width         {Number}   春联宽度
 *          duration      {Number}   春联滚动时间
 *          left          {Number}   春联Left位置
 *          top           {Number}   春联Top位置 
 * 
-->
<template>
  <JsvPreload
    :preloadList="preload_info"
    :onPreloadDone="loadDone"
  ></JsvPreload>
  <div v-for="layout in layouts">
    <div
      v-show="myShow"
      :style="{
        width: 180,
        height: size.height,
        top: layout.top,
        left: layout.left,
        transform: `scale3d(${size.width / 180},${size.width / 180},1)`,
        transformOrigin: 'left top',
      }"
    >
      <div
        :style="{
          top: 0,
          left: 0,
          width: 180,
          height: size.height,
          overflow: 'hidden',
          animation: aniName1,
        }"
      >
        <div
          :style="{
            top: 0,
            left: 0,
            width: 180,
            height: size.height,
            backgroundImage: layout.isLeft
              ? sourceMap.leftContent
              : sourceMap.rightContent,
            animation: aniName2,
          }"
        ></div>
      </div>
      <!-- 滚轴动画 -->
      <JsvSpriteLoader
        :imageUrl="sourceMap.scrollSprite"
        :configUrl="scrollJson"
        :onConfigReady="preloadCallback"
        :noNeedResource="false"
      >
        <div
          :style="{
            left: -30,
            top: size.height,
            transform: `scale3d(${(180 + 60) / view_size.w},1,1)`,
          }"
        >
          <div
            :style="{
              width: view_size.w,
              height: view_size.h,
              animation: aniName1,
            }"
          >
            <JsvSpriteAnim
              :spriteInfo="sprite_info.info"
              :loop="4"
              :duration="props.duration / 4"
              :imageUrl="sourceMap.scrollSprite"
              ref="myRef"
            >
            </JsvSpriteAnim>
          </div>
        </div>
      </JsvSpriteLoader>
      <!-- 滚轴图片 -->
      <div
        :style="{
          top: -30,
          left: -30,
          width: 180 + 60,
          height: 30,
          backgroundImage: sourceMap.scrollStatic,
        }"
      ></div>
    </div>
  </div>
</template>

<script setup>
import {
  JsvSpriteAnim,
  getKeyFramesGroup,
  JsvSpriteLoader,
  JsvPreload,
  buildPreloadInfo,
} from "jsview";
import { shallowRef, onBeforeUnmount, watch } from "vue";
const props = defineProps({
  sourceMap: {
    type: Object,
    require: true,
    validator: function (value) {
      return (
        "leftContent" in value &&
        "rightContent" in value &&
        "scrollSprite" in value &&
        "scrollStatic" in value
      );
    },
  },
  size: {
    type: Object,
    required: true,
    validator: function (value) {
      return "width" in value && "height" in value;
    },
  },
  leftPosition: {
    type: Object,
    require: true,
    validator: function (value) {
      return "left" in value && "top" in value;
    },
  },
  rightPosition: {
    type: Object,
    require: true,
    validator: function (value) {
      return "left" in value && "top" in value;
    },
  },
  duration: { type: Number, require: true },
});
const layouts = [{ ...props.leftPosition, isLeft: true }, props.rightPosition];
let myShow = shallowRef(false);
const scrollJson = props.sourceMap.scrollSprite.split("?")[0] + ".json";

//预加载
const preload_info = [
  buildPreloadInfo(props.sourceMap.leftContent),
  buildPreloadInfo(props.sourceMap.rightContent),
  buildPreloadInfo(props.sourceMap.scrollSprite),
  buildPreloadInfo(props.sourceMap.scrollStatic),
];

let readyNum = shallowRef(0);
const loadDone = (a) => {
  readyNum.value++;
};
let sprite_info = shallowRef(null);
const view_size = shallowRef(null);

const _formatInfo = (action_json) => {
  const info = {
    frames: [],
    meta: {
      size: action_json.meta.size,
    },
  };
  let frames_ref = info.frames;
  let max_width = 0;
  let max_height = 0;

  for (let i = 0; i < action_json.frames.length; i++) {
    const target = action_json.frames[i].spriteSourceSize;
    frames_ref.push({
      target,
      source: action_json.frames[i].frame,
    });
    const sprite_with = target.x + target.w;
    const sprite_height = target.y + target.h;
    if (sprite_with > max_width) {
      max_width = sprite_with;
    }
    if (sprite_height > max_height) {
      max_height = sprite_height;
    }
  }
  return { info, maxW: max_width, maxH: max_height };
};
const preloadCallback = (config_json, resolve_set) => {
  sprite_info.value = _formatInfo(config_json);
  view_size.value = {
    w: sprite_info.value.maxW,
    h: sprite_info.value.maxH,
  };
  resolve_set(); // 通知loader数组设置完成
  readyNum.value++;
};
//动画名字
let aniName1 = shallowRef(null);
let aniName2 = shallowRef(null);

//插入动画
const idRandom = Math.floor(Math.random() * 1000000);
let name1 = "anim1-" + idRandom;
let name2 = "anim2-" + idRandom;
let styleShell = getKeyFramesGroup();
let anim1 = `@keyframes ${name1} {
        from {
          transform: translate3d(0,${-props.size.height}, 0);
        }
        to {
          transform: translate3d(0, 0, 0);
        }
      }`;
styleShell.insertRule(anim1);
let anim2 = `@keyframes ${name2} {
        from {
          transform: translate3d(0,${props.size.height}, 0);
        }
        to {
          transform: translate3d(0, 0, 0);
        }
      }`;
styleShell.insertRule(anim2);

let timer = { id: -1 };
//ref
let myRef = shallowRef(null);
watch(readyNum, (n, o) => {
  if (o != 2 && n == 2) {
    timer.id = setTimeout(() => {
      myShow.value = true;
      myRef.value?.forEach((i) => i.start());
      aniName1.value = `${name1} ${props.duration}s linear`;
      aniName2.value = `${name2} ${props.duration}s linear`;
    }, 0);
  }
});

onBeforeUnmount(() => {
  styleShell.removeRule(name1);
  styleShell.removeRule(name2);
  clearTimeout(timer.id);
  timer.id = -1;
});
</script>

<style scoped></style>
