一、首先实现一个把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层没有加载的问题,导致转换的图片复制不上
日常所遇,随手而记。