<script setup lang="ts">
import { onMounted, reactive, ref,computed, watch } from 'vue'
import { UploadProps,UploadRawFile,genFileId } from 'element-plus'
import DetailHeader from '@/components/Layout/DetailHeader/DetailHeader.vue'
import ToolDetail from '@/components/Layout/ToolDetail/ToolDetail.vue'

const info = reactive({
  title: "图片切割",
})

const fileList = ref()
const lineNum = ref(3)
const image = ref({} as any)
const cutImg = ref([] as string[])
const dataFileRef = ref()

//上传
const updateDataFile = async (params) => {
  let reader = new FileReader();
  reader.readAsDataURL(params.file);
  reader.addEventListener(
      'load',
      async () => {
          const imageTmp = new Image();
          imageTmp.onload = () => {
            image.value = imageTmp;
            cut();
          };
          imageTmp.src = reader.result as string;
      },
      false
  );
}

//当超出限制时，执行的钩子函数
//这里覆盖前一个文件
const handleExceed: UploadProps['onExceed'] = (files) => {
  dataFileRef.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  dataFileRef.value!.handleStart(file)
  dataFileRef.value!.submit()
}

//切割
const cut = () => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const img = image.value;

  const wpiece = Math.floor(img.naturalWidth / lineNum.value);
  const hpiece = Math.floor(img.naturalHeight / lineNum.value);
  const results = [] as string[];

  canvas.width = wpiece;
  canvas.height = hpiece;

  for (let r = 0; r < lineNum.value; r++) {
      for (let c = 0; c < lineNum.value; c++) {
          ctx?.drawImage(
              img,
              c * wpiece,
              r * hpiece,
              wpiece,
              hpiece,
              0,
              0,
              wpiece,
              hpiece
          );
          results.push(canvas.toDataURL());
      }
  }
  cutImg.value = results;
}

//计算切割样式
const cutImgStyle = computed(() => {
  const width = `width: ${image.value.width || 800}px;`;
  const grid = `grid: repeat(${lineNum.value}, 1fr) / repeat(${
    lineNum.value
  }, 1fr);`;
  return width + grid;
})

watch(cutImgStyle, () => {
  if (fileList.value) cut();
})

onMounted(() => {

})
</script>

<template>
  <div class="flex flex-col mt-3 flex-1">
    <DetailHeader :title="info.title"></DetailHeader>

    <div class="p-4 rounded-2xl bg-white">
      <el-upload
        v-model:file-list="fileList"
        class="dataFileRef flex"
        ref="dataFileRef"
        accept="image/*"
        :http-request="updateDataFile"
        :on-exceed="handleExceed"
        :limit="1"
      >
        <el-button type="primary">请上传需要切割的图片</el-button>
      </el-upload>
      <div class="flex mt-3">
        <div class="flex">
          <el-text>行数和列数</el-text>
          <el-input-number v-model="lineNum" :min="1" :max="10" class="ml-3"/>
        </div>
      </div>


      <div class="mt-3 min-h-md bg-gray-100 p-3 mb-3 flex flex-col" v-if="image.src">
        <!-- 预览 -->
        <div class="mb-3">
          <el-text>预览: </el-text>
          <div :style="cutImgStyle" class="grid gap-1 max-w-full">
              <img v-for="(src,index) in cutImg" :key="index" :src="src" alt="结果" />
          </div>
        </div>

        <!-- 原图 -->
        <div>
          <el-text>原图: </el-text>
          <div>
            <img :src="image.src" alt="原图" v-if="image.src"/>
          </div>
        </div>
      </div>
      <div v-else>
        <el-empty :image-size="200" description="无预览"/>
      </div>
    </div>

    <!-- desc -->
    <ToolDetail title="描述">
      <el-text>
        将图片分割成四宫格、九宫格、十六宫格，支持自定义行与列；<br>
        比如：九宫格切图广泛应用于微信朋友圈，微博等社交媒体。
      </el-text> 
    </ToolDetail>
  </div>
</template>

<style scoped>
</style>