<!-- 朋友圈背景裁剪上传 -->
<template>
  <div
    class="cropper-content"
    data-weiling-mobile-ui-wl-cropper
    v-show="show"
    teleport="html"
    ref="contentRef"
  >
    <VueCropper
      v-show="loadStatue == 'success'"
      class="vue-cropper"
      ref="cropper"
      :img="option.img"
      :outputSize="option.outputSize"
      :outputType="option.outputType"
      :info="option.info"
      :full="option.full"
      :can-move="option.canMove"
      :can-move-box="option.canMoveBox"
      :original="option.original"
      :auto-crop="option.autoCrop"
      :fixed="option.fixed"
      :fixedNumber="option.fixedNumber"
      :center-box="option.centerBox"
      :infoTrue="option.infoTrue"
      :fixed-box="option.fixedBox"
      :mode="option.mode"
      :auto-crop-width="option.autoCropWidth"
      :auto-crop-height="option.autoCropHeight"
      @img-load="onImgLoad"
    />
    <div class="footer">
      <span class="cancel-btn" @click.stop="onClose">取消</span>
      <span class="sub-btn" @click.stop="submit">确定</span>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { VueCropper } from "vue-cropper";
import "vue-cropper/dist/index.css";
import { base64ToFile } from "@mobileUI/utils";
import { showLoadingToast } from "vant";
import { watch, ref } from "vue";
interface Props {
  value: boolean | object;
  file: any;
  cropperOption?: any;
}
const props = withDefaults(defineProps<Props>(), {
  value: false,
  file: () => {},
  cropperOption: () => {},
});
const emit = defineEmits<{
  (e: "onCroppered", val: any): void;
  (e: "update:value", val: boolean): void;
}>();
const contentRef = ref(null);
const cropper = ref(null);
const loadStatue = ref("");
const show = ref(false);
const option = ref<any>({
  img: "", // 裁剪图片的地址
  info: false, // 裁剪框的大小信息
  outputSize: 0.8, // 裁剪生成图片的质量
  outputType: "png", // 裁剪生成图片的格式
  canScale: true, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  // autoCropWidth: 80, // 默认生成截图框宽度
  // autoCropHeight: 80, // 默认生成截图框高度
  fixedBox: false, // 固定截图框大小 不允许改变
  fixed: true, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例
  full: false, // 是否输出原图比例的截图
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  mode: "",
  infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  ...props.cropperOption,
});
const loadingToast = () => {
  return showLoadingToast({
    duration: 0,
    forbidClick: true,
    message: "加载中...",
  });
};
const init = (file: any) => {
  let img = new Image();
  img.src = file.content;
  img.onload = () => {
    const { width, height } = img;
    option.value.img = file.content;
    if (width > height) {
      option.value.mode = "auto 255px";
    } else {
      option.value.mode = "contain";
    }
  };
};
const submit = () => {
  cropper.value.getCropData(async (res: any) => {
    const file = base64ToFile(res, props.file.file.name);
    emit("onCroppered", { file, content: res });
  });
};
const onImgLoad = (res: any) => {
  loadStatue.value = res;
  loadingToast().close();
};
const onClose = () => {
  option.value.img = "";
  loadStatue.value = "";
  option.value.mode = "";
  show.value = false;
  emit("onCroppered", { content: "" });
};
watch(
  () => props.value,
  (val) => {
    show.value = val;
  },
);
// onMounted(() => {
//   document.body.append(state.contentRef);
// });
// onBeforeUnmount(() => {
//   document.body.removeChild(state.contentRef);
// });
watch(
  () => show.value,
  (val) => {
    emit("update:value", val);
  },
);
watch(
  () => props.file,
  (val) => {
    if (val && props.value) init(val);
  },
);
</script>

<style scoped lang="scss">
.cropper-content[data-weiling-mobile-ui-wl-cropper] {
  position: fixed;
  z-index: 100;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0 j(20);
  background: rgba(0, 0, 0, 1);
  overflow: hidden;

  .footer {
    // width: 100%;
    position: absolute;
    left: j(20);
    right: j(20);
    bottom: j(20);
    display: flex;
    justify-content: space-between;
    align-items: center;

    .cancel-btn {
      color: #fff;
      font-weight: 600;
      font-size: j(14);
    }

    .sub-btn {
      text-align: center;
      width: j(58);
      height: j(32);
      line-height: j(32);
      background: #4f76b9;
      border-radius: j(4);
      font-size: j(14);
      color: #fff;
    }
  }
}

:deep() {
  .vue-cropper {
    height: 100%;
    width: 100%;

    .cropper-box {
      overflow: initial !important;
      background: rgba(0, 0, 0, 1);
    }

    .cropper-modal {
      left: j(-20);
      width: 100vw;
    }

    .cropper-view-box {
      outline: none;
    }
  }
}
</style>
