You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.8 KiB
Vue
120 lines
2.8 KiB
Vue
<template>
|
|
<div @dragover.prevent @drop.prevent>
|
|
<div class="drop" @drop="dragFile">
|
|
<span v-if="loading" class="loading">
|
|
Loading...
|
|
</span>
|
|
<span v-else>
|
|
Drag file here
|
|
</span>
|
|
<img ref="thumb" />
|
|
</div>
|
|
</div>
|
|
|
|
</template>
|
|
<script setup>
|
|
|
|
import {ref, computed} from 'vue'
|
|
const emit = defineEmits(['upload'])
|
|
|
|
|
|
const file = ref([])
|
|
const fileType = ref("")
|
|
const thumb = ref(null)
|
|
const loading = ref(false)
|
|
|
|
|
|
const dragFile = (e) => {
|
|
file.value = e.dataTransfer.files[0]
|
|
createPreview(file.value)
|
|
}
|
|
|
|
const container = computed(()=>{
|
|
if (fileType.value == 'image') return 'img'
|
|
if (fileType.value == 'video') return 'video'
|
|
return 'div'
|
|
})
|
|
|
|
const createPreview = (file) => {
|
|
let fileExt;
|
|
const fileName = file.name
|
|
const filePath = (window.URL || window.webkitURL).createObjectURL(file)
|
|
|
|
// get file extension
|
|
fileExt = fileName.toLowerCase().substr(fileName.lastIndexOf('.')+1, fileName.length - fileName.lastIndexOf('.'))
|
|
|
|
// get file type
|
|
fileType.value = file.type.toLowerCase().substr(0, file.type.indexOf("/"))
|
|
|
|
|
|
const reader = new FileReader()
|
|
reader.readAsDataURL(file)
|
|
loading.value = true
|
|
|
|
|
|
reader.onloadend = (e) => {
|
|
if (e.target.readyState == FileReader.DONE) {
|
|
if (fileType.value == 'video') videoSnapshot(filePath)
|
|
if (fileType.value == 'image') imageSnapshot(filePath)
|
|
}
|
|
}
|
|
}
|
|
|
|
const imageSnapshot = (url) => {
|
|
thumb.value.src = url
|
|
emit('upload', url)
|
|
loading.value = false;
|
|
}
|
|
|
|
|
|
const videoSnapshot = (url) => {
|
|
let video = document.createElement('video')
|
|
video.src = url
|
|
|
|
const snapshot = () => {
|
|
let canvas = document.createElement('canvas')
|
|
canvas.width = 1280
|
|
canvas.height = 720
|
|
let ctx = canvas.getContext('2d')
|
|
|
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
|
thumb.value.src = canvas.toDataURL('image/png')
|
|
emit('upload', thumb.value.src)
|
|
loading.value = false
|
|
video.removeEventListener('canplay', snapshot)
|
|
}
|
|
video.addEventListener('canplay', snapshot)
|
|
}
|
|
|
|
</script>
|
|
|
|
<style>
|
|
|
|
.drop {
|
|
position: relative;
|
|
display: inline-block;
|
|
width: 160px;
|
|
height: 90px;
|
|
border: 1px solid currentColor;
|
|
padding: 16px;
|
|
}
|
|
|
|
.drop img,
|
|
.drop video {
|
|
position: absolute;
|
|
z-index: 100;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
.loading {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
</style>
|