Схемная практика генерации фронтенд-плакатов через канвас

внешний интерфейс Canvas

В настоящее время возникла внезапная необходимость создать простую страницу постера в бизнесе и поделиться ею в WeChat и Moments.Из-за того, что текущее время онлайн слишком мало для реализации, небольшой спрос был отрезан, но в В свободное время я все же подумал о целесообразности.Несколько вариантов:

1. Родной рисунок холста для создания постеров

Как показано на рисунке ниже, это простое постерное изображение, состоящее из нескольких частей: базовое изображение + 3 области, отмеченные красными прямоугольниками. В настоящее время существует проблема: если это простое одиночное изображение плаката, его можно напрямую отобразить на html-странице; но если сложное изображение плаката состоит из нескольких частей, нам нужно нарисовать другие части на базовой карте, а затем объединить в законченный постерный образ. Мы создаем это полное изображение постера в несколько шагов: (источник github:GitHub.com/lecithin1990/лецитин…Я умоляю вас, ребята, снять его~~).

捕获.PNG

1.1 Сначала создайте базовую карту

<body>
    <div class="header">
        <img src="./imgs/share.png" alt="">
    </div>
    <canvas id="myCanvas"></canvas>
</body>
const canvas = document.getElementById("myCanvas"); // 使用id来寻找canvas元素
    const cxt = canvas.getContext("2d"); // 创建context对象

    // 取可视化区域的宽、高并设置myCanvas的宽高
    const clientWidth = document.documentElement.clientWidth;
    const clientHeight = document.documentElement.clientHeight;
    canvas.width = clientWidth; // 设置myCanvas的宽
    canvas.height = clientHeight; // 设置myCanvas的高

    // 绘制一个矩形,用来做全局背景颜色
    cxt.fillStyle = "#fff";
    cxt.fillRect(0, 0, canvas.width, canvas.height); // fillRect方法是创建一个矩形,x坐标、y坐标、宽度、高度

    // 把图片绘制到myCanvas
    const img = new Image()
    img.crossOrigin = "anonymous";
    img.src = "./imgs/imgdemo04.jpeg"; // 图片路径
    img.onload = () => {
        cxt.drawImage(img, 0, 0, clientWidth, clientHeight);
        
        ...... 省略内容为绘制文字和二维码部分内容 ......
    }

1.2 Нарисуйте часть текстового описания и часть QR-кода

// 绘制文字部分显示:
        cxt.fillStyle = "#ffffff";
        cxt.font = "14px bold 黑体";
        const str = "打开爱奇艺app,扫码领取积分,赢取豪华大礼,惊喜等着你~"
        cxt.textBaseline = "middle";
        cxt.textAlign = "left";
        let lineWidth = 0;
        let txtlimitWidth = 240; // 一行文字占用的宽度
        let initHeight = clientHeight - 50; // 绘制字体距离canvas顶部初始的高度
        let lastSubStrIndex = 0; // 每次开始截取的字符串的索引

        // 绘制文字的时候,如果当绘制的长度超出文字限制长度 txtlimitWidth, 就转行
        for (let i = 0; i < str.length; i++) {
            lineWidth += cxt.measureText(str[i]).width;
            if (lineWidth > txtlimitWidth) {
                cxt.fillText(str.substring(lastSubStrIndex, i), 20, initHeight); // 绘制截取部分
                initHeight += 20; // 20为字体的高度
                lineWidth = 0;
                lastSubStrIndex = i;
            }
            if (i == str.length - 1) { // 绘制剩余部分
                cxt.fillText(str.substring(lastSubStrIndex, i + 1), 20, initHeight);
            }
        }
        
        // 绘制二维码
        var qrcode = new Image()
        qrcode.crossOrigin = "anonymous";
        qrcode.src = "./imgs/qrcode.png" // 二维码图片路径
        qrcode.onload = () => {
            cxt.drawImage(qrcode, 300, clientHeight - 60, 50, 50);

            // 绘制特殊部位展示图
            var lightImg = new Image()
            lightImg.crossOrigin = "anonymous";
            lightImg.src = "./imgs/imgdemo05.png" // 特殊部位展示图路径
            lightImg.onload = () => {
                cxt.drawImage(lightImg, 210, 52, 72, 101);
                let _imgSrc = canvas.toDataURL("image/png", 1);
                console.log('_imgSrc =============', _imgSrc);
            }
        }

В приведенном выше коде есть несколько замечаний:

  1. При отрисовке изображения мы создаем экземпляр Image для генерации элемента img, вводим локальный путь изображения в атрибут src в элементе img и отрисовываем изображение с помощью метода ctx.drawImage после загрузки изображения (то есть в onload Перезвоните);
  2. Когда окончательное изображение будет нарисовано, мы можем преобразовать холст в формат base64: let _imgSrc = canvas.toDataURL("image/png", 1);

1.3 Решить проблему сообщения об ошибках при запуске локальной службы:

Если мы откроем html-страницу напрямую через браузер, будет сообщено о следующей ошибке:

捕获.PNGДанная ошибка является ошибкой при загрузке браузером локальных файлов между доменами, решить которую можно запуском локального сервиса через плагин live-server. После глобальной установки live-сервера запустите локальную службу, чтобы открыть html-страницу, что может избежать ошибки, когда холст открывает локальный путь к изображению:

  1. Установить live-сервер глобально

cnpm install --save live-server

  1. Откройте каталог, в котором локальный файл Canvas02.html расположен и выполняет команду:

live-server

На этом этапе изображение плаката может отображаться нормально. И генерируется кодировка base64 изображения плаката.

2. Создайте плакат с помощью плагина html2canvas.

В следующем коде файл html2canvas.min.js представлен глобально (ссылка для скачивания исходного кода:html2canvas.hertzen.com/) достигается за два следующих шага:

  • Первый шаг к реализации сохранения в виде изображения: преобразование html в холст. На основе html2canvas.js элемент может отображаться как холст, а затем объект Promise передаст захваченное изображение в параметр холста. В следующем коде статическая html-страница изображения плаката отрисовывается напрямую, а затем глобальным методом реализуется преобразование html в холст.

  • Холст к изображению. Холст, сгенерированный на предыдущем шаге, представляет собой объект элемента холста, содержащий целевой элемент. Чтобы достичь цели сохранения изображений, вам нужно всего лишь преобразовать холст в изображение. Метод toDataURL, основанный на собственном холсте, выводит холст как кодировку изображения base64.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script src="./js/html2canvas.min.js"></script>

<body>
    <div class="container">
        <div class="header">
            <img src="./imgs/share.png" alt="">
        </div>
        <span class="desc">打开爱奇艺app,扫码领取积分,赢取豪华大礼,惊喜等着你~</span>
        <img class="code-img" src="./imgs/qrcode.png" alt="">
        <img class="hug-img" src="./imgs/imgdemo05.png" alt="">
    </div>
</body>

<script>
    html2canvas(document.querySelector(".container")).then(canvas => {
        let _imgSrc = canvas.toDataURL("image/png", 1);
        console.log('_imgSrc =============', _imgSrc);
    });
</script>
Категории