如何用QRCode.js库在前端生成和调节二维码

3,189 阅读13分钟

最近因为公司的产品说明书原因,每一个都需要使用二维码,于是在网上到处用生成二维码的工具。用久了就在想,感觉这个也不是很难,于是自己研究了一下,使用QRCode.js库自己写了一个二维码创建的页面。

最终运行截图:

image.png

为什么使用QRCode.js?

很简单的原因,因为我搜索二维码库的时候第一眼就瞅见了他。。。

QRCode.js 是一个轻量级且高效的 JavaScript 库,它能够帮助我们在网页上生成二维码。无论是将网址、文本还是其他数据生成二维码,QRCode.js 都能轻松胜任。而且,它提供了多种配置选项,让我们可以根据需求调整二维码的外观和行为。

Demo测试

首先我得尝试一下这个库是否真的如他的介绍而言,说的那么易用~

1. 引入QRCode.js库

首先,我们需要在HTML文件中引入QRCode.js库,这可以通过在<head>部分添加以下代码实现:

<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>

2. 创建输入框和按钮

接下来,我们在<body>中创建一个输入框和一个按钮,用户可以在输入框中输入想要生成二维码的文本,然后点击按钮生成二维码。

<input type="text" id="text" placeholder="输入要生成二维码的文本">
<button onclick="generateQRCode()">生成二维码</button>

3. 生成二维码

当用户点击按钮时,会触发generateQRCode函数。这个函数首先获取输入框中的文本内容,然后清空之前生成的二维码(如果有),最后生成新的二维码并显示在页面上。

function generateQRCode() {
    // 获取输入的文本
    var text = document.getElementById('text').value;
    // 清空之前的二维码
    document.getElementById('qrcode').innerHTML = '';
    // 生成新的二维码
    new QRCode(document.getElementById('qrcode'), text);
}

自定义选项

其实QRCode.js 提供了丰富的配置选项,我们可以根据需要对二维码进行各种自定义。例如,调整二维码的大小、颜色以及纠错等级。下面是一个示例代码,展示了如何使用这些配置选项:

new QRCode(document.getElementById('qrcode'), {
    text: text,
    width: 128,
    height: 128,
    colorDark: "#000000",
    colorLight: "#ffffff",
    correctLevel: QRCode.CorrectLevel.H
});

主要配置选项

  • text:要编码的文本或URL。
  • widthheight:二维码的宽度和高度。
  • colorDark:二维码前景色。
  • colorLight:二维码背景色。
  • correctLevel:二维码的纠错等级(L, M, Q, H)。

完整Demo

我们先来看一下完整的代码示例,这个例子展示了我如何用QRCode.js生成一个简单的二维码。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }

        input,
        button {
            font-size: 16px;
            padding: 10px;
            margin: 5px;
        }

        #qrcode {
            margin-top: 20px;
        }
    </style>
</head>

<body>
    <h1>二维码生成器</h1>
    <input type="text" id="text" placeholder="输入要生成二维码的文本">
    <button onclick="generateQRCode()">生成二维码</button>
    <br><br>
    <div id="qrcode"></div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <script>
        function generateQRCode() {
            // 获取输入的文本
            var text = document.getElementById('text').value;
            // 清空之前的二维码
            document.getElementById('qrcode').innerHTML = '';
            // 生成新的二维码
            new QRCode(document.getElementById('qrcode'), text);
        }
    </script>
</body>

</html>

运行截图

添加上传logo功能

测试Demo通过之后,我就准备基于这个库开始添加功能了,以便让这个工具更加实用。接下来,我将展示如何添加一个上传logo的功能,使用户能够选择一张图片作为logo,并将其裁剪为圆形,放置在二维码的中间位置。

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }

        input,
        button {
            font-size: 16px;
            padding: 10px;
            margin: 5px;
        }

        #canvas-container {
            position: relative;
            display: inline-block;
            margin-top: 20px;
        }

        canvas {
            border: 1px solid #000;
        }
    </style>
</head>

<body>
    <h1>二维码生成器</h1>
    <input type="text" id="text" placeholder="输入要生成二维码的文本">
    <button onclick="generateQRCode()">生成二维码</button>
    <br><br>
    <input type="file" id="upload" accept="image/*" onchange="previewLogo()">
    <br><br>
    <div id="canvas-container">
        <canvas id="qrcode-canvas" width="200" height="200"></canvas>
    </div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <script>
        var logoImage;

        function generateQRCode() {
            var text = document.getElementById('text').value;
            var canvas = document.getElementById('qrcode-canvas');
            var context = canvas.getContext('2d');
            var qrCode = new QRCode(document.createElement('div'), {
                text: text,
                width: 200,
                height: 200
            });

            setTimeout(function () {
                var qrCanvas = qrCode._oDrawing._elCanvas;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(qrCanvas, 0, 0);

                if (logoImage) {
                    var logoSize = 40;
                    var logoX = (canvas.width - logoSize) / 2;
                    var logoY = (canvas.height - logoSize) / 2;
                    context.save();
                    context.beginPath();
                    context.arc(logoX + logoSize / 2, logoY + logoSize / 2, logoSize / 2, 0, Math.PI * 2, true);
                    context.closePath();
                    context.clip();
                    context.drawImage(logoImage, logoX, logoY, logoSize, logoSize);
                    context.restore();
                }
            }, 100);
        }

        function previewLogo() {
            var file = document.getElementById('upload').files[0];
            var reader = new FileReader();
            reader.onloadend = function () {
                logoImage = new Image();
                logoImage.src = reader.result;
            }
            if (file) {
                reader.readAsDataURL(file);
            }
        }
    </script>
</body>

</html>

代码解析

  1. HTML部分
    • 新增了一个文件输入元素 ,用户可以通过它上传图片作为logo。
  1. JavaScript部分
    • 新增了 logoImage 变量,用于保存用户上传的logo图片。
    • previewLogo 函数:当用户选择图片时,这个函数会读取图片文件并创建一个图像对象。
    • generateQRCode 函数:除了生成二维码外,还会在二维码生成后将logo图片绘制到二维码的中间。为了实现圆形裁剪效果,使用了context.arc 和 context.clip 方法。

自定义选项和配置

在这个示例中,我指定了二维码的大小(200x200)以及logo的大小(40x40)。这些参数可以根据需要进行调整,以适应不同的需求。

运行截图

调整二维码清晰度

这个二维码生成之后我发现二维码在放大之后会变得模糊,于是我通过调整 canvas 的尺寸(例如 3840x3840 像素)并相应地放大生成二维码的尺寸增加了一些二维码的清晰度。

但是这样生成的二维码在页面上会显示的很大,看起来很不美观。于是我使用 CSS 来缩小页面上显示canvas 尺寸,同时保持其高分辨率输出。通过调整 canvas 的 CSS 样式,而不是改变其实际尺寸实现这了一点。

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }

        input,
        button {
            font-size: 16px;
            padding: 10px;
            margin: 5px;
        }

        #canvas-container {
            position: relative;
            display: inline-block;
            margin-top: 20px;
        }

        canvas {
            border: 1px solid #000;
            width: 600px;
            /* 缩小显示尺寸 */
            height: 600px;
            /* 缩小显示尺寸 */
        }
    </style>
</head>

<body>
    <h1>二维码生成器</h1>
    <input type="text" id="text" placeholder="输入要生成二维码的文本">
    <button onclick="generateQRCode()">生成二维码</button>
    <br><br>
    <input type="file" id="upload" accept="image/*" onchange="previewLogo()">
    <br><br>
    <div id="canvas-container">
        <canvas id="qrcode-canvas" width="3840" height="3840"></canvas>
    </div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <script>
        var logoImage;

        function generateQRCode() {
            var text = document.getElementById('text').value;
            var canvas = document.getElementById('qrcode-canvas');
            var context = canvas.getContext('2d');
            var size = 3840; // 4K 分辨率
            var qrCode = new QRCode(document.createElement('div'), {
                text: text,
                width: size,
                height: size
            });

            setTimeout(function () {
                var qrCanvas = qrCode._oDrawing._elCanvas;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(qrCanvas, 0, 0, size, size, 0, 0, canvas.width, canvas.height);

                if (logoImage) {
                    var logoSize = 960; // logo 大小,确保在 4K 分辨率下清晰
                    var logoX = (canvas.width - logoSize) / 2;
                    var logoY = (canvas.height - logoSize) / 2;
                    context.save();
                    context.beginPath();
                    context.arc(logoX + logoSize / 2, logoY + logoSize / 2, logoSize / 2, 0, Math.PI * 2, true);
                    context.closePath();
                    context.clip();
                    context.drawImage(logoImage, logoX, logoY, logoSize, logoSize);
                    context.restore();
                }
            }, 100);
        }

        function previewLogo() {
            var file = document.getElementById('upload').files[0];
            var reader = new FileReader();
            reader.onloadend = function () {
                logoImage = new Image();
                logoImage.onload = function () {
                    if (logoImage.width > 960 || logoImage.height > 960) {
                        // 缩放logo至合适的大小
                        var scale = Math.min(960 / logoImage.width, 960 / logoImage.height);
                        var width = logoImage.width * scale;
                        var height = logoImage.height * scale;
                        var canvas = document.createElement('canvas');
                        canvas.width = width;
                        canvas.height = height;
                        var context = canvas.getContext('2d');
                        context.drawImage(logoImage, 0, 0, width, height);
                        logoImage.src = canvas.toDataURL();
                    }
                }
                logoImage.src = reader.result;
            }
            if (file) {
                reader.readAsDataURL(file);
            }
        }
    </script>
</body>

</html>

代码解析

  1. Canvas尺寸调整
    • 的尺寸调整为 3840x3840,以生成 4K 分辨率的二维码。
    • widthheight CSS 属性设置为 600px,以缩小页面上显示的尺寸,同时保持实际的 3840x3840 分辨率
  1. Logo尺寸调整
    • 根据 4K 分辨率调整 logo 的大小为 960x960,以确保在二维码中间保持清晰。
    • previewLogo 函数中,确保上传的 logo 不超过 960x960 像素,如果超过则按比例缩放。

运行截图

添加logo背景

如果看到这里的同学其实早已经发现了,我是直接裁剪的logo为圆形,并且作为一个二维码而言,他的logo背景应该为圆形白底。于是我修改了一下logo的机制,我希望logo的背景为白色,圆形,不裁剪图片,并且有一个控制logo大小的进度条。

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }

        input,
        button {
            font-size: 16px;
            padding: 10px;
            margin: 5px;
        }

        #canvas-container {
            position: relative;
            display: inline-block;
            margin-top: 20px;
        }

        canvas {
            border: 1px solid #000;
            width: 600px;
            /* 缩小显示尺寸 */
            height: 600px;
            /* 缩小显示尺寸 */
        }

        #logo-size-slider {
            width: 300px;
        }
    </style>
</head>

<body>
    <h1>二维码生成器</h1>
    <input type="text" id="text" placeholder="输入要生成二维码的文本">
    <button onclick="generateQRCode()">生成二维码</button>
    <br><br>
    <input type="file" id="upload" accept="image/*" onchange="previewLogo()">
    <br><br>
    <label for="logo-size-slider">Logo 大小</label>
    <input type="range" id="logo-size-slider" min="10" max="100" value="70" oninput="updateLogoSizeLabel()">
    <span id="logo-size-label">70%</span>
    <br><br>
    <div id="canvas-container">
        <canvas id="qrcode-canvas" width="3840" height="3840"></canvas>
    </div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <script>
        var logoImage;
        var logoSizePercentage = 70; // 初始值为70%

        function generateQRCode() {
            var text = document.getElementById('text').value;
            var canvas = document.getElementById('qrcode-canvas');
            var context = canvas.getContext('2d');
            var size = 3840; // 4K 分辨率
            var qrCode = new QRCode(document.createElement('div'), {
                text: text,
                width: size,
                height: size
            });

            setTimeout(function () {
                var qrCanvas = qrCode._oDrawing._elCanvas;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(qrCanvas, 0, 0, size, size, 0, 0, canvas.width, canvas.height);

                if (logoImage) {
                    var whiteCircleSize = canvas.width * 0.2; // 固定白色圆形背景大小
                    var logoSize = (logoSizePercentage / 100) * whiteCircleSize; // 根据百分比计算logo大小
                    var circleX = (canvas.width - whiteCircleSize) / 2;
                    var circleY = (canvas.height - whiteCircleSize) / 2;
                    var logoX = (canvas.width - logoSize) / 2;
                    var logoY = (canvas.height - logoSize) / 2;

                    context.save();
                    // 绘制白色圆形背景
                    context.beginPath();
                    context.arc(canvas.width / 2, canvas.height / 2, whiteCircleSize / 2, 0, Math.PI * 2, true);
                    context.closePath();
                    context.fillStyle = "#fff";
                    context.fill();

                    // 绘制logo
                    context.drawImage(logoImage, logoX, logoY, logoSize, logoSize);
                    context.restore();
                }
            }, 100);
        }

        function previewLogo() {
            var file = document.getElementById('upload').files[0];
            var reader = new FileReader();
            reader.onloadend = function () {
                logoImage = new Image();
                logoImage.onload = function () {
                    generateQRCode(); // 预览logo后重新生成二维码
                }
                logoImage.src = reader.result;
            }
            if (file) {
                reader.readAsDataURL(file);
            }
        }

        function updateLogoSizeLabel() {
            var slider = document.getElementById('logo-size-slider');
            logoSizePercentage = slider.value;
            document.getElementById('logo-size-label').innerText = slider.value + '%';
            generateQRCode(); // 实时更新二维码
        }

        // 初始化进度条标签
        document.addEventListener('DOMContentLoaded', function () {
            document.getElementById('logo-size-label').innerText = logoSizePercentage + '%';
        });
    </script>
</body>

</html>

代码解析

  1. 添加进度条
    • 在 HTML 中添加了一个 元素,用于控制 logo 的大小。
    • 添加了一个 25% 元素,用于显示当前的 logo 大小百分比。
  1. 更新 logo 大小
    • generateQRCode 函数中,根据 logoSizePercentage 计算 logo 的大小,并在二维码中心绘制带有白色背景的圆形 logo。
  1. 更新 logo 大小标签
    • 添加了 updateLogoSizeLabel 函数,更新显示的 logo 大小百分比。
  1. 白色圆形背景大小固定
    • generateQRCode 函数中,固定白色圆形背景的大小为 canvas.width * 0.2,即二维码宽度的 20%。
  1. 进度条实时更新 logo 大小
    • logo-size-sliderinput 事件监听器中,更新 logoSizePercentage 并调用 generateQRCode 实时更新二维码。
  1. 实时显示变化
    • previewLogo 函数中,在 logo 加载后重新生成二维码,以便预览时实时显示 logo。
  1. 初始值为70%
    • logoSizePercentage 的初始值设置为 70。
    • 的初始值设置为 70。
  1. 初始化进度条标签
    • 使用 DOMContentLoaded 事件监听器,在页面加载时设置初始进度条标签值为 70%。
  1. 实时更新进度条
    • updateLogoSizeLabel 函数中,实时更新 logoSizePercentage 并调用 generateQRCode 函数。

运行截图

添加logo背景大小控制条

这个白色圆形背景我也想要增加一个进度条用以控制它的大小,于是增加了一些代码

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }

        input,
        button {
            font-size: 16px;
            padding: 10px;
            margin: 5px;
        }

        #canvas-container {
            position: relative;
            display: inline-block;
            margin-top: 20px;
        }

        canvas {
            border: 1px solid #000;
            width: 600px;
            /* 缩小显示尺寸 */
            height: 600px;
            /* 缩小显示尺寸 */
        }

        #logo-size-slider,
        #background-size-slider {
            width: 300px;
        }
    </style>
</head>

<body>
    <h1>二维码生成器</h1>
    <input type="text" id="text" placeholder="输入要生成二维码的文本">
    <button onclick="generateQRCode()">生成二维码</button>
    <br><br>
    <input type="file" id="upload" accept="image/*" onchange="previewLogo()">
    <br><br>
    <label for="logo-size-slider">Logo 大小</label>
    <input type="range" id="logo-size-slider" min="10" max="100" value="70" oninput="updateLogoSizeLabel()">
    <span id="logo-size-label">70%</span>
    <br><br>
    <label for="background-size-slider">背景大小</label>
    <input type="range" id="background-size-slider" min="10" max="100" value="20" oninput="updateBackgroundSizeLabel()">
    <span id="background-size-label">20%</span>
    <br><br>
    <div id="canvas-container">
        <canvas id="qrcode-canvas" width="3840" height="3840"></canvas>
    </div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <script>
        var logoImage;
        var logoSizePercentage = 70; // 初始值为70%
        var backgroundSizePercentage = 20; // 初始值为20%

        function generateQRCode() {
            var text = document.getElementById('text').value;
            var canvas = document.getElementById('qrcode-canvas');
            var context = canvas.getContext('2d');
            var size = 3840; // 4K 分辨率
            var qrCode = new QRCode(document.createElement('div'), {
                text: text,
                width: size,
                height: size
            });

            setTimeout(function () {
                var qrCanvas = qrCode._oDrawing._elCanvas;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(qrCanvas, 0, 0, size, size, 0, 0, canvas.width, canvas.height);

                if (logoImage) {
                    var whiteCircleSize = (backgroundSizePercentage / 100) * canvas.width; // 根据百分比计算白色圆形背景大小
                    var logoSize = (logoSizePercentage / 100) * whiteCircleSize; // 根据百分比计算logo大小
                    var circleX = (canvas.width - whiteCircleSize) / 2;
                    var circleY = (canvas.height - whiteCircleSize) / 2;
                    var logoX = (canvas.width - logoSize) / 2;
                    var logoY = (canvas.height - logoSize) / 2;

                    context.save();
                    // 绘制白色圆形背景
                    context.beginPath();
                    context.arc(canvas.width / 2, canvas.height / 2, whiteCircleSize / 2, 0, Math.PI * 2, true);
                    context.closePath();
                    context.fillStyle = "#fff";
                    context.fill();

                    // 绘制logo
                    context.drawImage(logoImage, logoX, logoY, logoSize, logoSize);
                    context.restore();
                }
            }, 100);
        }

        function previewLogo() {
            var file = document.getElementById('upload').files[0];
            var reader = new FileReader();
            reader.onloadend = function () {
                logoImage = new Image();
                logoImage.onload = function () {
                    generateQRCode(); // 预览logo后重新生成二维码
                }
                logoImage.src = reader.result;
            }
            if (file) {
                reader.readAsDataURL(file);
            }
        }

        function updateLogoSizeLabel() {
            var slider = document.getElementById('logo-size-slider');
            logoSizePercentage = slider.value;
            document.getElementById('logo-size-label').innerText = slider.value + '%';
            generateQRCode(); // 实时更新二维码
        }

        function updateBackgroundSizeLabel() {
            var slider = document.getElementById('background-size-slider');
            backgroundSizePercentage = slider.value;
            document.getElementById('background-size-label').innerText = slider.value + '%';
            generateQRCode(); // 实时更新二维码
        }

        // 初始化进度条标签
        document.addEventListener('DOMContentLoaded', function () {
            document.getElementById('logo-size-label').innerText = logoSizePercentage + '%';
            document.getElementById('background-size-label').innerText = backgroundSizePercentage + '%';
        });
    </script>
</body>

</html>

代码解析

  1. 初始值设置
    • logoSizePercentage 初始值设置为 70。
    • backgroundSizePercentage 初始值设置为 20。
    • 在 HTML 中设置 logo-size-sliderbackground-size-slider 的初始值分别为 70 和 20。
  1. 添加控制背景大小的进度条
    • 添加了一个 元素,用于控制背景大小。
    • 添加了一个 20% 元素,用于显示当前背景大小百分比。
  1. 更新背景大小的函数
    • updateBackgroundSizeLabel 函数中,实时更新 backgroundSizePercentage 并调用 generateQRCode 实时更新二维码。

这样,您可以通过两个进度条分别控制 logo 图片和白色圆形背景的大小,并且实时显示变化。

运行截图

使用Bootstrap库美化界面

我的基本功能都实现了,身为一个前端而言,我实在是看不下去这么丑的界面,于是我使用Bootstrap库美化了一下界面

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <!-- 引入Bootstrap CSS -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin-top: 50px;
        }

        #canvas-container {
            position: relative;
            display: flex;
            justify-content: center;
            align-items: center;
            margin-top: 20px;
        }

        canvas {
            border: 1px solid #000;
            width: 600px;
            /* 缩小显示尺寸 */
            height: 600px;
            /* 缩小显示尺寸 */
        }

        #logo-size-slider,
        #background-size-slider {
            width: 100%;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1 class="text-center">二维码生成器</h1>
        <div class="form-group">
            <input type="text" id="text" class="form-control" placeholder="输入要生成二维码的文本">
        </div>
        <div class="form-group text-center">
            <button class="btn btn-primary" onclick="generateQRCode()">生成二维码</button>
        </div>
        <div class="form-group">
            <input type="file" id="upload" class="form-control-file" accept="image/*" onchange="previewLogo()">
        </div>
        <div class="form-group">
            <label for="logo-size-slider">Logo 大小</label>
            <input type="range" id="logo-size-slider" min="10" max="100" value="70" class="custom-range"
                oninput="updateLogoSizeLabel()">
            <span id="logo-size-label">70%</span>
        </div>
        <div class="form-group">
            <label for="background-size-slider">背景大小</label>
            <input type="range" id="background-size-slider" min="10" max="100" value="20" class="custom-range"
                oninput="updateBackgroundSizeLabel()">
            <span id="background-size-label">20%</span>
        </div>
        <div id="canvas-container" class="d-flex justify-content-center">
            <canvas id="qrcode-canvas" width="3840" height="3840"></canvas>
        </div>
    </div>

    <!-- 引入QRCode.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    <!-- 引入Bootstrap JS和依赖 -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <script>
        var logoImage;
        var logoSizePercentage = 75; // 初始值为70%
        var backgroundSizePercentage = 25; // 初始值为20%

        function generateQRCode() {
            var text = document.getElementById('text').value;
            var canvas = document.getElementById('qrcode-canvas');
            var context = canvas.getContext('2d');
            var size = 3840; // 4K 分辨率
            var qrCode = new QRCode(document.createElement('div'), {
                text: text,
                width: size,
                height: size
            });

            setTimeout(function () {
                var qrCanvas = qrCode._oDrawing._elCanvas;
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(qrCanvas, 0, 0, size, size, 0, 0, canvas.width, canvas.height);

                if (logoImage) {
                    var whiteCircleSize = (backgroundSizePercentage / 100) * canvas.width; // 根据百分比计算白色圆形背景大小
                    var logoSize = (logoSizePercentage / 100) * whiteCircleSize; // 根据百分比计算logo大小
                    var circleX = (canvas.width - whiteCircleSize) / 2;
                    var circleY = (canvas.height - whiteCircleSize) / 2;
                    var logoX = (canvas.width - logoSize) / 2;
                    var logoY = (canvas.height - logoSize) / 2;

                    context.save();
                    // 绘制白色圆形背景
                    context.beginPath();
                    context.arc(canvas.width / 2, canvas.height / 2, whiteCircleSize / 2, 0, Math.PI * 2, true);
                    context.closePath();
                    context.fillStyle = "#fff";
                    context.fill();

                    // 绘制logo
                    context.drawImage(logoImage, logoX, logoY, logoSize, logoSize);
                    context.restore();
                }
            }, 100);
        }

        function previewLogo() {
            var file = document.getElementById('upload').files[0];
            var reader = new FileReader();
            reader.onloadend = function () {
                logoImage = new Image();
                logoImage.onload = function () {
                    generateQRCode(); // 预览logo后重新生成二维码
                }
                logoImage.src = reader.result;
            }
            if (file) {
                reader.readAsDataURL(file);
            }
        }

        function updateLogoSizeLabel() {
            var slider = document.getElementById('logo-size-slider');
            logoSizePercentage = slider.value;
            document.getElementById('logo-size-label').innerText = slider.value + '%';
            generateQRCode(); // 实时更新二维码
        }

        function updateBackgroundSizeLabel() {
            var slider = document.getElementById('background-size-slider');
            backgroundSizePercentage = slider.value;
            document.getElementById('background-size-label').innerText = slider.value + '%';
            generateQRCode(); // 实时更新二维码
        }

        // 初始化进度条标签
        document.addEventListener('DOMContentLoaded', function () {
            document.getElementById('logo-size-label').innerText = logoSizePercentage + '%';
            document.getElementById('background-size-label').innerText = backgroundSizePercentage + '%';
        });
    </script>
</body>

</html>

代码解析

  1. 引入 Bootstrap
    • 标签中添加 引入 Bootstrap CSS 文件。
  1. 使用 Bootstrap 样式和组件
    • 使用 Bootstrap 样式类美化文本输入框、按钮、文件上传输入框和进度条。
    • 包装了所有内容在
      中,以创建一个响应式布局。
    • 为按钮添加 btn btn-primary 样式类,使其看起来更美观。
    • 为进度条添加 custom-range 样式类,以匹配 Bootstrap 样式。
  1. 修改Logo初始大小为75%,背景初始大小为25%。

运行截图