Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复二维码生成器无法清空内容的bug #111

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 101 additions & 95 deletions src/pages/generate_qrcode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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%',
Expand Down Expand Up @@ -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);
}
};
};

Expand All @@ -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(() => {
Expand All @@ -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) {
Expand Down Expand Up @@ -251,35 +231,39 @@ 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,
0,
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,
0,
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,
Expand All @@ -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]);

Expand All @@ -344,7 +326,7 @@ const _C = () => {
textarea: { height: '100% !important' },
}}
value={text}
rows={4}
rows={3}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setText(event.target.value)
}
Expand Down Expand Up @@ -393,14 +375,31 @@ const _C = () => {
{!!qrcodeData && (
<>
<Box sx={{ fontSize: '16px', fontWeight: 600, mb: 2 }}>Logo</Box>
<Button
variant='outlined'
sx={{ borderRadius: '4px', width: '120px' }}
size='small'
onClick={uploadLogo}
<Stack
direction={'row'}
alignItems={'center'}
spacing={2}
sx={{ fontSize: '14px' }}
>
上传 Logo
</Button>
<Button
variant='outlined'
sx={{ borderRadius: '4px', width: '120px' }}
size='small'
onClick={() => upload('logoInput')}
>
上传 Logo
</Button>
{!!logo && (
<Box
sx={{ color: 'error.main', cursor: 'pointer' }}
onClick={() => {
setLogo(undefined);
}}
>
清除
</Box>
)}
</Stack>
<Box sx={{ fontSize: '16px', fontWeight: 600, mb: 2 }}>颜色</Box>
<Stack
direction={'row'}
Expand Down Expand Up @@ -432,7 +431,7 @@ const _C = () => {
variant='outlined'
sx={{ borderRadius: '4px', width: '120px' }}
size='small'
onClick={uploadBgi}
onClick={() => upload('bgiInput')}
>
{!!bgimg ? '更换背景图' : '上传背景图'}
</Button>
Expand Down Expand Up @@ -478,7 +477,7 @@ const _C = () => {
variant='outlined'
sx={{ borderRadius: '4px', width: '120px' }}
size='small'
onClick={uploadFgi}
onClick={() => upload('fgiInput')}
>
{!!fgimg ? '更换前景图' : '上传前景图'}
</Button>
Expand Down Expand Up @@ -581,6 +580,13 @@ const _C = () => {
{options.width}x{options.width}px
</Box>
<Stack direction={'row'} spacing={2}>
<Button
variant='outlined'
sx={{ borderRadius: '4px', width: '100%' }}
onClick={clear}
>
清除美化
</Button>
<Button
variant='outlined'
sx={{ borderRadius: '4px', width: '100%' }}
Expand Down Expand Up @@ -616,23 +622,23 @@ const _C = () => {
type='file'
accept='image/*'
style={{ display: 'none' }}
onChange={addBgi}
onChange={(event) => addGi(event, 'bgimg')}
/>
<Box
component={'input'}
id='fgiInput'
type='file'
accept='image/*'
style={{ display: 'none' }}
onChange={addFgi}
onChange={(event) => addGi(event, 'fgimg')}
/>
<Box
component={'input'}
id='logoInput'
type='file'
accept='image/*'
style={{ display: 'none' }}
onChange={addLogo}
onChange={(event) => addGi(event, 'logoimg')}
/>
</Stack>
</MainContent>
Expand Down