<!--
 * 【模块 export 内容】
 * Banger：鞭炮组件
 *      props说明:
 *          left          {Number}   组件顶端中心Left位置
 *          top           {Number}   组件顶端中心Top位置
 *          num           {Number}   鞭炮个数(个数决定长度)
 *          leadWireTime  {Number}   引线燃烧时间
 *          width         {Number}   整个组件的宽度
-->
<template>
  <!-- 预加载 -->
  <JsvPreload
    :preloadList="preload_info"
    :onPreloadDone="loadDone"
  ></JsvPreload>
  <div
    v-show="myShow"
    :style="{
      left: props.left - widgetWidth / 2,
      top: props.top,
      width: widgetWidth,
      height: leadWireHeight,
      transform: `scale3d(${props.width / widgetWidth},${
        props.width / widgetWidth
      },1)`,
      transformOrigin: 'center top',
    }"
  >
    <div
      :style="{
        top: -leadWireHeight,
        left: 0,
        width: 80,
        height: leadWireHeight,
        overflow: 'hidden',
        animation: aniName1,
      }"
    >
      <div
        :style="{
          top: leadWireHeight,
          left: 0,
          width: 80,
          height: leadWireHeight,
          backgroundImage: leadWire,
          animation: aniName2,
        }"
      ></div>
    </div>
    <!-- 燃烧特效 -->
    <div
      v-if="isSpark"
      :style="{
        top: -10,
        left: 31,
        animation: aniName1,
      }"
      @animationend="closeSpark"
    >
      <JsvSpriteLoader
        :imageUrl="sparkPng"
        :configUrl="sparkJson"
        :onConfigReady="preloadCallback"
        :noNeedResource="false"
      >
        <div
          :style="{
            transform: `scale3d(${20 / view_size.w},${20 / view_size.h},1)`,
          }"
        >
          <JsvSpriteAnim
            :spriteInfo="sprite_info.info"
            :loop="'infinite'"
            :duration="0.1"
            :imageUrl="sparkPng"
            ref="controllerAnim"
            autoStart="true"
          >
          </JsvSpriteAnim>
        </div>
      </JsvSpriteLoader>
    </div>

    <MaroonLoader>
      <Maroon
        v-for="(item, index) in spriteArray"
        :top="leadWireHeight - 40 - index * 16"
        :left="10"
        :deg="index % 2 == 0 ? 30 : -30"
        :ref="(el) => (RefArray[index] = el)"
        :myRef="spriteArray[index]"
      ></Maroon>
    </MaroonLoader>
  </div>
</template>

<script setup>
import Maroon from "./Maroon.vue";
import MaroonLoader from "./MaroonLoader.vue";
import { shallowRef, onBeforeUnmount, watch, provide } from "vue";
import {
  JsvSpriteAnim,
  getKeyFramesGroup,
  JsvSpriteLoader,
  JsvPreload,
  buildPreloadInfo,
} from "jsview";
import { _formatInfo } from "../Common/SpriteDeal";

const leadWire =
  "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/CoupletsTest/widget/Banger/Banger/leadWire.png";
const sparkPng =
  "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/CoupletsTest/widget/Banger/Banger/spark.png";
const sparkJson =
  "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/CoupletsTest/widget/Banger/Banger/spark.json";

//预加载
const preload_info = [buildPreloadInfo(leadWire), buildPreloadInfo(sparkPng)];
//定义ref
let controllerAnim = shallowRef(null);
//设定变量控制动画的播放
let readyNum = shallowRef(0);
const loadDone = (a) => {
  readyNum.value++;
  myShow.value = true;
};
let myShow = shallowRef(false);
const props = defineProps({
  top: { type: Number, default: 0 },
  left: { type: Number, default: 0 },
  num: { type: Number, default: 12 },
  width: { type: Number, require: true },
  leadWireTime: { type: Number, require: true },
});
// 组件宽度
const widgetWidth = 80;
let sprite_info = shallowRef(null);
let view_size = shallowRef(null);
//计算引线长度
let leadWireHeight = (props.num - 1) * 16 + 20;
//插入动画
const idRandom = Math.floor(Math.random() * 1000000);
let styleShell = getKeyFramesGroup();
let name1 = "animLw1-" + idRandom;
let name2 = "animLw2-" + idRandom;
let animLw1 = `@keyframes ${name1} {
        from {
          transform: translate3d(0,${leadWireHeight}, 0);
        }
        to {
          transform: translate3d(0, 0, 0);
        }
      }`;
styleShell.insertRule(animLw1);
let animLw2 = `@keyframes ${name2} {
        from {
          transform: translate3d(0,${-leadWireHeight}, 0);
        }
        to {
          transform: translate3d(0, 0, 0);
        }
      }`;
styleShell.insertRule(animLw2);

//预加载
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++;
};
//子组件加载完毕的flag
let sonFlag = shallowRef(false);
provide("sonFlag", sonFlag);
//动画名字
let aniName1 = shallowRef(null);
let aniName2 = shallowRef(null);
//控制燃烧特效
let isSpark = shallowRef(true);
const closeSpark = () => {
  isSpark.value = false;
};
//ref数组
const spriteArray = new Array(props.num);
let RefArray = shallowRef([]);
for (let i = 0; i < spriteArray.length; i++) {
  spriteArray[i] = shallowRef(null);
}

const callFireMethod = (index) => {
  // 检查索引是否超出范围，如果超出则停止递归
  if (index >= spriteArray.length) {
    return;
  }

  // 获取当前索引对应的Maroon组件的ref
  const currentMaroonRef = RefArray.value[index];
  // 调用当前Maroon组件的fire方法
  if (currentMaroonRef) {
    currentMaroonRef.fire();
  }
  // 延迟1秒后递归调用下一个Maroon组件的fire方法
  timer.id2 = setTimeout(() => {
    callFireMethod(index + 1);
  }, (props.leadWireTime * 1000) / (props.num - 1));
};

//延时器
let timer = { id: -1, id2: -1 };
watch(readyNum, (n, o) => {
  if (o != 3 && n == 3) {
    timer.id = setTimeout(() => {
      controllerAnim.value.start();
      callFireMethod(0);
      aniName1.value = `${name1} ${props.leadWireTime}s linear`;
      aniName2.value = `${name2} ${props.leadWireTime}s linear`;
    }, 0);
  }
});

watch(sonFlag, (n) => {
  if (n == true) {
    readyNum.value++;
  }
});

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

<style scoped>
.text {
  font-size: 24;
  color: #ffffff;
  font-weight: bold;
  text-align: center;
  line-height: 32;
}
</style>
