usePasteEvent.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { onMounted, onUnmounted } from 'vue'
  2. import { storeToRefs } from 'pinia'
  3. import { useMainStore } from '@/store'
  4. import { getImageDataURL } from '@/utils/image'
  5. import usePasteTextClipboardData from './usePasteTextClipboardData'
  6. import useCreateElement from './useCreateElement'
  7. export default () => {
  8. const { editorAreaFocus, thumbnailsFocus, disableHotkeys } = storeToRefs(useMainStore())
  9. const { pasteTextClipboardData } = usePasteTextClipboardData()
  10. const { createImageElement } = useCreateElement()
  11. // 粘贴图片到幻灯片元素
  12. const pasteImageFile = (imageFile: File) => {
  13. getImageDataURL(imageFile).then(dataURL => createImageElement(dataURL))
  14. }
  15. /**
  16. * 粘贴事件监听
  17. * @param e ClipboardEvent
  18. */
  19. const pasteListener = (e: ClipboardEvent) => {
  20. if (!editorAreaFocus.value && !thumbnailsFocus.value) return
  21. if (disableHotkeys.value) return
  22. if (!e.clipboardData) return
  23. const clipboardDataItems = e.clipboardData.items
  24. const clipboardDataFirstItem = clipboardDataItems[0]
  25. if (!clipboardDataFirstItem) return
  26. // 如果剪贴板内有图片,优先尝试读取图片
  27. let isImage = false
  28. for (const item of clipboardDataItems) {
  29. if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
  30. const imageFile = item.getAsFile()
  31. if (imageFile) pasteImageFile(imageFile)
  32. isImage = true
  33. }
  34. }
  35. if (isImage) return
  36. // 如果剪贴板内没有图片,但有文字内容,尝试解析文字内容
  37. if (clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') {
  38. clipboardDataFirstItem.getAsString(text => pasteTextClipboardData(text))
  39. }
  40. }
  41. onMounted(() => {
  42. document.addEventListener('paste', pasteListener)
  43. })
  44. onUnmounted(() => {
  45. document.removeEventListener('paste', pasteListener)
  46. })
  47. }