一、首先實現一個把canvas轉換為圖片,簡單點就是把dom轉換為圖片
1、優先想到的就是html2canvas ,具體使用參考官網
但是它有一個bug,你複製的容器不能使用css3的box-shadow要不然會導致你轉換的圖片變成白色和灰色相間的背景色,並且無解,
如果有跨域問題,那就繼續使用html2canvas
2、dom-to-image 外掛也可以將dom轉換為圖片,並且你容器使用任意css3屬性都無影響
安裝 npm install dom-to-image --save-dev 使用 import domtoimage from 'dom-to-image' domtoimage .toPng('轉換的容器,支援vdom', config) .then(baseUrl => { waferCopyBigImage.value = baseUrl //這時候就拿到圖片了 })
二、將圖片複製到剪下板
有兩種方式
1、document.execCommand('copy') //這個無相容問題
2、navigator.clipboard.writeText() //這個方法不支援在http下面
很多外掛都是把這兩個整合進去了
<template> <div v-if="copySuccess" class="copy-success" :style="menuStyle" @click="copyWaferHandler"> 複製 </div> <div ref="waferCopyBigImageContainer" :style="{ width: waferMapContentSize?.width + 'px', height: waferMapContentSize?.height + 'px', position: 'absolute', left: '1000%', overflow: 'hidden', background: '#fff', }" v-if="waferCopyBigImage" > <img width="100%" height="100%" v-if="waferCopyBigImage" :src="waferCopyBigImage" /> </div> </template> <script setup lang="ts" name="WaferCopyContent"> import { ref, nextTick } from 'vue' import { Message } from '@arco-design/web-vue' import domtoimage from 'dom-to-image' import type { IWaferMapSize } from '../wafer-map-canvas' const props = defineProps<{ copySuccess: boolean waferMapContentSize?: IWaferMapSize menuStyle: any copyContentBox: HTMLDivElement | null }>() const emits = defineEmits<{ (e: 'copySet', value: boolean): void }>() const waferCopyBigImage = ref<string | null>(null) const waferCopyBigImageContainer = ref<HTMLElement | null>(null) const copyWaferHandler = e => { emits('copySet', false) e.stopPropagation() e.preventDefault() console.log('複製') document.execCommand('delete') Message.loading('複製中...') copyImage() } const copyImage = async () => { const config = { width: props.waferMapContentSize?.width, height: props.waferMapContentSize?.height, backgroundColor: '#fff', } if (props && props.copyContentBox) { domtoimage .toPng(props.copyContentBox, config) .then(baseUrl => { waferCopyBigImage.value = baseUrl Message.clear() nextTick(() => { const selection = window.getSelection() if (!selection) { return } selection.removeAllRanges() selection?.empty() const range = document.createRange() range.selectNode(waferCopyBigImageContainer.value!) selection?.addRange(range) try { document.execCommand('copy') Message.info('圖片已複製到剪貼簿') } catch (err: any) { Message.error('複製失敗:', err) } if (selection) { selection.removeAllRanges() } }) }) .catch(err => { Message.clear() console.log('轉換失敗', err) }) } } </script> <style scoped lang="scss"> .copy-success { position: absolute; padding: 0 10px; width: 50px; height: 32px; text-align: center; line-height: 32px; cursor: pointer; background-color: var(--color-bg-popup); border: 1px solid var(--color-fill-3); border-radius: var(--border-radius-medium); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1019607843); } </style>
複製的時候有個bug
如果遇到要複製兩次的時候,一定要記得把你裝載的容器加一個v-if,因為會出現資料層實現了,dom層沒有載入的問題,導致轉換的圖片複製不上