PC端react实现一键复制图片功能
背景:要求前端实现生成二维码并实现一键复制图片,
粘贴的效果图如下:
本文用到的工具库:
qrcode.react、b64-to-blob、html2canvas
首先将后端链接通过qrcode.react通过canvas生成二维码
<div>
<QRCode
value={'https://www.toutiao.com/a7003614188446761479/?log_from=105dea9e42726_1630663662691'}
size={200}
fgColor="#000000"
/>
</div>
复制代码
然后再将整个dom转成canvas,此时会发现之前二维码已经是canvas了,不能再用canvas转了,所以我们修改下逻辑
const [url, setUrl] = useState('');
const qrCoderef = useRef();
// 初始化,将canvas生成的二维码通过base64给到img标签
const init = () => {
const image = new Image();
// 解决canvas跨域问题
image.setAttribute('crossOrigin', 'anonymous');
image.src = ‘图片地址’;
// 利用图片加载,触发事件
image.onload = function () {
try {
const canvas = document.getElementsByTagName('canvas');
const ctx = canvas[0].getContext('2d');
ctx.drawImage(image, 200, 200);
const imgUrl = canvas[0].toDataURL('image/png');
setUrl(imgUrl);
} catch {
message.error('生成失败,请重试');
props.onCancel();
}
};
};
useEffect(() => {
init();
}, []);
复制代码
<div ref={qrCoderef}>
{!url&&<QRCode
value={'https://www.toutiao.com/a7003614188446761479/?log_from=105dea9e42726_1630663662691'}
size={200}
fgColor="#000000"
/>}
{url && <div className={styles.imgDiv}>
<img className={styles.copyImg} src={url} alt="" />
</div>}
</div>
复制代码
这样再通过html2canvas,就可以获取完整的dom节点,再通过b64-to-blob,将base64格式转换成blob,将blob赋值到浏览器剪切板就大功告成了。
具体操作:
const copy = () => {
html2canvas(qrCoderef.current, {
useCORS: true
}).then((canvas) => {
const imgUrl = canvas.toDataURL('image/png');
const str = imgUrl.replace(/data:image\/png;base64,/, '');
const file = b64toBlob(str, 'image/png');
const clipboardItemInput = new window.ClipboardItem({ 'image/png': file });
window.navigator.clipboard.write([clipboardItemInput]);
});
};
复制代码
完整代码:
import React, { useState, useEffect, useRef } from 'react';
import { Modal, message, Popover } from 'antd';
import QRCode from 'qrcode.react';
import html2canvas from 'html2canvas';
import b64toBlob from 'b64-to-blob';
import bg from 'public/1.png';
const QrCodeModal = (props) => {
const [url, setUrl] = useState('');
const qrCoderef = useRef();
const copy = () => {
html2canvas(qrCoderef.current, {
useCORS: true
}).then((canvas) => {
const imgUrl = canvas.toDataURL('image/png');
const str = imgUrl.replace(/data:image\/png;base64,/, '');
const file = b64toBlob(str, 'image/png');
const clipboardItemInput = new window.ClipboardItem({ 'image/png': file });
window.navigator.clipboard.write([clipboardItemInput]);
});
};
const init = () => {
const image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = bg;
image.onload = function () {
try {
const canvas = document.getElementsByTagName('canvas');
const ctx = canvas[0].getContext('2d');
ctx.drawImage(image, 200, 200);
const imgUrl = canvas[0].toDataURL('image/png');
setUrl(imgUrl);
} catch {
// 可能在canvas还没画完就调用造成失败
message.error('生成失败,请重试');
props.onCancel();
}
};
};
useEffect(() => {
init();
}, []);
return (
<Modal {...props} >
<Popover content={<div><a onClick={() => copy()}>一键复制</a></div>} title="">
<div ref={qrCoderef}>
<h3 >你来啦?</h3>
<p>
<span>xxxx</span>
<span>xxxxxxxxxxxxxx</span>
</p>
<div>
{!url && <div >
<QRCode
value={'https://www.toutiao.com/a7003614188446761479/?log_from=105dea9e42726_1630663662691'}
size={200}
fgColor="#000000"
/>
</div>}
{url && <div >
<img src={url} alt="" />
</div>}
</div>
</div>
</Popover>
</Modal >
);
};
export default QrCodeModal;
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END