From 903d6fcbbffcd0608790b73115335ad747493186 Mon Sep 17 00:00:00 2001 From: KuaiYu95 Date: Wed, 10 Jan 2024 19:03:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=8C=E7=BB=B4?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E6=97=A0=E6=B3=95=E6=B8=85?= =?UTF-8?q?=E7=A9=BA=E5=86=85=E5=AE=B9=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/generate_qrcode.tsx | 196 ++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/src/pages/generate_qrcode.tsx b/src/pages/generate_qrcode.tsx index 1fd9cb1..e190095 100644 --- a/src/pages/generate_qrcode.tsx +++ b/src/pages/generate_qrcode.tsx @@ -18,12 +18,8 @@ import { useEffect, useState } from 'react'; const OriginTypes = [ { label: '文本', value: 'text' }, { label: '网址', value: 'url' }, - // { label: "文件", value: "file" }, - // { label: "图片", value: "image" }, - // { label: "音视频", value: "media" }, - // { label: "名片", value: "card" }, - // { label: "微信", value: "wechat" }, ]; + const LevelErrorResistance = { L: '7%', M: '15%', @@ -88,59 +84,33 @@ const _C = () => { document.body.removeChild(a); }; - const uploadBgi = () => { - const bgiInput = document.getElementById('bgiInput'); - bgiInput?.click(); - }; - - const uploadFgi = () => { - const fgiInput = document.getElementById('fgiInput'); - fgiInput?.click(); - }; - - const uploadLogo = () => { - const logoInput = document.getElementById('logoInput'); - logoInput?.click(); - }; - - const addBgi = (event: any) => { - const file = event.target.files[0]; - const img = new Image(); - const canvas = document.createElement('canvas'); - img.src = URL.createObjectURL(file); - img.onload = () => { - canvas.width = options.width!; - canvas.height = options.width!; - const ctx = canvas.getContext('2d'); - ctx?.drawImage(img, 0, 0, options.width!, options.width!); - const bgiData = ctx?.getImageData(0, 0, options.width!, options.width!); - setBgcolor('#ffffff'); - setBgimg(bgiData); - }; + const upload = (type: string) => { + const input = document.getElementById(type); + input?.click(); }; - const addFgi = (event: any) => { + const addGi = (event: any, type: 'bgimg' | 'fgimg' | 'logoimg') => { const file = event.target.files[0]; const img = new Image(); const canvas = document.createElement('canvas'); img.src = URL.createObjectURL(file); img.onload = () => { + if (type === 'logoimg') { + setLogo(img); + return; + } canvas.width = options.width!; canvas.height = options.width!; const ctx = canvas.getContext('2d'); ctx?.drawImage(img, 0, 0, options.width!, options.width!); - const fgiData = ctx?.getImageData(0, 0, options.width!, options.width!); - setFgcolor('#000000'); - setFgimg(fgiData); - }; - }; - - const addLogo = (event: any) => { - const file = event.target.files[0]; - const img = new Image(); - img.src = URL.createObjectURL(file); - img.onload = () => { - setLogo(img); + const data = ctx?.getImageData(0, 0, options.width!, options.width!); + if (type === 'bgimg') { + setBgcolor('#ffffff'); + setBgimg(data); + } else { + setFgcolor('#000000'); + setFgimg(data); + } }; }; @@ -157,11 +127,19 @@ const _C = () => { const deleteCanvas = () => { clear(); - setText(''); - setUrl(''); - const qrcodeCanvas = document.getElementById('qrcode') as HTMLCanvasElement; - const qrcodeCtx = qrcodeCanvas!.getContext('2d'); - qrcodeCtx?.clearRect(0, 0, options.width!, options.width!); + setTimeout(() => { + clear(); + setText(''); + setUrl(''); + const qrcodeCanvas = document.getElementById( + 'qrcode' + ) as HTMLCanvasElement; + const qrcodeCtx = qrcodeCanvas!.getContext('2d', { + willReadFrequently: true, + })!; + qrcodeCtx.clearRect(0, 0, options.width!, options.width!); + }, 0); + // requestAnimationFrame(deleteCanvas) }; useEffect(() => { @@ -177,7 +155,9 @@ const _C = () => { const qrcodeCanvas = document.getElementById( 'qrcode' ) as HTMLCanvasElement; - const qrcodeCtx = qrcodeCanvas!.getContext('2d'); + const qrcodeCtx = qrcodeCanvas!.getContext('2d', { + willReadFrequently: true, + })!; if (bgcolor) { for (let i = 0; i < qrcodePixels.length; i += 4) { @@ -251,11 +231,12 @@ const _C = () => { } } - qrcodeCtx?.putImageData(qrcodeimg, 0, 0); + qrcodeCtx.putImageData(qrcodeimg, 0, 0); if (logo) { - qrcodeCtx?.beginPath(); - qrcodeCtx?.arc( + // 绘制外圆 + qrcodeCtx.beginPath(); + qrcodeCtx.arc( options.width! / 2, options.width! / 2, (options.width! / 8 + 4) | 0, @@ -263,12 +244,14 @@ const _C = () => { 2 * Math.PI, false ); - qrcodeCtx!.fillStyle = '#ffffff'; - qrcodeCtx?.fill(); - qrcodeCtx?.clip(); - qrcodeCtx?.closePath(); - qrcodeCtx?.beginPath(); - qrcodeCtx?.arc( + qrcodeCtx.fillStyle = '#ffffff'; + qrcodeCtx.fill(); + qrcodeCtx.clip(); + qrcodeCtx.closePath(); + + // 绘制内圆 + qrcodeCtx.beginPath(); + qrcodeCtx.arc( options.width! / 2, options.width! / 2, (options.width! / 8) | 0, @@ -276,10 +259,11 @@ const _C = () => { 2 * Math.PI, false ); - qrcodeCtx?.fill(); - qrcodeCtx?.clip(); - qrcodeCtx?.closePath(); - qrcodeCtx?.drawImage( + qrcodeCtx.fill(); + qrcodeCtx.clip(); + qrcodeCtx.closePath(); + + qrcodeCtx.drawImage( logo, (options.width! * 3) / 8, (options.width! * 3) / 8, @@ -302,22 +286,20 @@ const _C = () => { }, [oType]); useEffect(() => { - setTimeout(() => { - const content = oType === 'text' ? text : url; - const qrcodeCanvas = document.getElementById( - 'qrcode' - ) as HTMLCanvasElement; - if (!qrcodeCanvas || !content) return; - QRCode.toCanvas(qrcodeCanvas, content, options); - const qrcodeCtx = qrcodeCanvas!.getContext('2d'); - const qrcodeData = qrcodeCtx?.getImageData( - 0, - 0, - options.width!, - options.width! - ); - setQrcodeData(qrcodeData!); - }, 200); + const content = oType === 'text' ? text : url; + const qrcodeCanvas = document.getElementById('qrcode') as HTMLCanvasElement; + if (!qrcodeCanvas || !content) return; + QRCode.toCanvas(qrcodeCanvas, content, options); + const qrcodeCtx = qrcodeCanvas!.getContext('2d', { + willReadFrequently: true, + })!; + const qrcodeData = qrcodeCtx.getImageData( + 0, + 0, + options.width!, + options.width! + ); + setQrcodeData(qrcodeData!); // eslint-disable-next-line react-hooks/exhaustive-deps }, [options, bgimg, fgimg, bgcolor, fgcolor, logo, count]); @@ -344,7 +326,7 @@ const _C = () => { textarea: { height: '100% !important' }, }} value={text} - rows={4} + rows={3} onChange={(event: React.ChangeEvent) => setText(event.target.value) } @@ -393,14 +375,31 @@ const _C = () => { {!!qrcodeData && ( <> Logo - + + {!!logo && ( + { + setLogo(undefined); + }} + > + 清除 + + )} + 颜色 { variant='outlined' sx={{ borderRadius: '4px', width: '120px' }} size='small' - onClick={uploadBgi} + onClick={() => upload('bgiInput')} > {!!bgimg ? '更换背景图' : '上传背景图'} @@ -478,7 +477,7 @@ const _C = () => { variant='outlined' sx={{ borderRadius: '4px', width: '120px' }} size='small' - onClick={uploadFgi} + onClick={() => upload('fgiInput')} > {!!fgimg ? '更换前景图' : '上传前景图'} @@ -581,6 +580,13 @@ const _C = () => { {options.width}x{options.width}px +