vue3图片裁剪

<template>
  <!-- 选择图片 -->
  <section class="section">
    <div class="desc">

      <a
          href="https://github.com/chengpeiquan/vue-picture-cropper-demo/blob/main/src/views/composition.vue"
          target="_blank"
      >
        <span>查看本 DEMO 源码</span>
      </a>
    </div>


    <input
        ref="uploadInput"
        type="file"
        accept="image/jpg, image/jpeg, image/png, image/gif"
        @change="selectFile"
    />
  </section>
  <!-- 选择图片 -->

  <!-- 结果预览区 -->
  <section class="section" v-if="result.dataURL && result.blobURL">
    <p>裁切后的 Base64 图片预览:</p>
    <div class="preview">
      <img :src="result.dataURL" alt="组合式 API" />
    </div>
    <p>裁切后的 Blob 图片预览:</p>
    <div class="preview">
      <img :src="result.blobURL" alt="组合式 API" />
    </div>
    <p>可以按 F12 查看打印的 base64 / blob / file 结果</p>
  </section>
  <!-- 结果预览区 -->

  <!-- 用于裁切的弹窗 -->
  <Modal v-model:visible="isShowDialog" title="图片裁切" :maskClosable="false">
    <template #footer>
      <el-button @click="isShowDialog = false">取消</el-button>
      <el-button @click="clear">清除</el-button>
      <el-button @click="reset">重置</el-button>
      <el-button type="primary" @click="getResult">裁切</el-button>
    </template>

    <!-- 图片裁切插件 -->
    <VuePictureCropper
        :boxStyle="{
        width: '100%',
        height: '100%',
        backgroundColor: '#f8f8f8',
        margin: 'auto',
      }"
        :img="pic"
        :options="{
        viewMode: 1,
        dragMode: 'crop',
        aspectRatio: 16 / 9,
      }"
    />
    <!-- 图片裁切插件 -->
  </Modal>
  <!-- 用于裁切的弹窗 -->
</template>

<script lang="ts">
import { defineComponent, reactive, ref } from 'vue'
import { Modal } from 'ant-design-vue'
import VuePictureCropper, { cropper } from 'vue-picture-cropper'
interface Result {
  dataURL: string
  blobURL: string
}
export default defineComponent({
  components: {
    Modal,
    VuePictureCropper,
  },
  setup() {
    const uploadInput = ref<HTMLInputElement | null>(null)
    const pic = ref<string>('')
    const result: Result = reactive({
      dataURL: '',
      blobURL: '',
    })
    const isShowDialog = ref<boolean>(false)
    /**
     * 选择图片
     */
    const selectFile = (e: Event): void => {
      // 重置上一次的结果
      result.dataURL = ''
      result.blobURL = ''
      // 如果有多个裁剪框,也需要重置掉裁剪目标的值,避免使用同一张图片无法触发watch
      pic.value = ''
      // 获取选取的文件
      const target = e.target as HTMLInputElement
      const { files } = target
      if (!files) return
      const file: File = files[0]
      // 转换为base64传给裁切组件
      const reader: FileReader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (): void => {
        // 更新裁切弹窗的图片源
        pic.value = String(reader.result)
        // 显示裁切弹窗
        isShowDialog.value = true
        // 清空已选择的文件
        if (!uploadInput.value) return
        uploadInput.value.value = ''
      }
    }
    /**
     * 获取裁切结果
     */
    const getResult = async (): Promise<void> => {
      // console.log(cropper)
      // 获取生成的base64图片地址
      const base64: string = cropper.getDataURL()
      // 获取生成的blob文件信息
      const blob = await cropper.getBlob()
      // 获取生成的file文件信息
      const file = await cropper.getFile({
        fileName: '测试文件名,可不传',
      })
      console.log({ base64, blob, file })
      // 把base64赋给结果展示区
      result.dataURL = base64
      try {
        result.blobURL = URL.createObjectURL(blob)
      } catch (e) {
        result.blobURL = ''
      }
      // 隐藏裁切弹窗
      isShowDialog.value = false
    }
    /**
     * 清除裁切框
     */
    const clear = (): void => {
      cropper.clear()
    }
    /**
     * 重置默认的裁切区域
     */
    const reset = (): void => {
      cropper.reset()
    }
    return {
      // 数据
      uploadInput,
      pic,
      result,
      isShowDialog,
      // 方法
      selectFile,
      getResult,
      clear,
      reset,
    }
  },
})
</script>

<style scoped></style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值