Введение в Canvas — создание и загрузка пригласительных билетов

JavaScript HTML

1. Введение

После написания множества статей по javascript и css3 пришло время написать холст. Canvas — это новая функция, предоставляемая html5! Что касается роли, то это полотно. Тогда кисть - это javascript. Использование холста очень широко, особенно в играх HTML5 и визуализации данных. Теперь холст дает мне то же ощущение, что и css3, вам не нужно быть слишком мощным, но вы должны знать основы его использования. Но спрос на холст обязательно возрастет в будущем. Таким образом, холст стоит изучить, а хорошее изучение холста — это хороший плюс. Для этой статьи я также написал ее с точки зрения новичка в холсте, и будет много улучшений. Если вы считаете, что у меня есть что улучшить, или предложения, добро пожаловать, чтобы дать указатели! Код выложен на гитхаб, добро пожаловать звездочка(downloadImg).

Прежде чем читать эту статью, вам нужно понять некоторые основы javascript, а также прочитать и понять некоторые API холста (холст-MSN Tutorial,учебник по холсту для новичков)

2. Пример пригласительного билета

Пригласительный билет генерируется автоматически.В конце концов, иногда многие пригласительные билеты одинаковы, но приглашенные люди разные.То есть весь пригласительный билет имеет другое имя, поэтому следующее. Просто напишите набор кода для создания пригласительных билетов на основе имен!

2-1 Эффект операции

HTML-код

<html>
<head>
    <meta charset="utf-8">
    <title>下载图片</title>
    <style>
        .set-option {
            float: left;
            width: 400px;
        }

        .set-option .text {
            width: 200px;
            height: 40px;
            padding-left: 10px;
            border-radius: 4px;
            border: 1px solid #ccc;
        }

        .set-option td {
            padding: 10px 0;
        }

        .set-option td:first-child {
            text-align: right;
            padding-right: 10px;
        }

        .set-option p {
            margin: 0;
            line-height: 16px;
        }

        .check-box {
            width: 16px;
            height: 16px;
            margin: 0;
            vertical-align: top;
        }

        button {
            width: 200px;
            height: 50px;
            border: none;
            color: #fff;
            font-size: 16px;
            cursor: pointer;
            display: block;
            margin: 10px auto;
        }

        button:hover {
            opacity: .9;
        }

        .btn-all {
            background: #f90;
        }

        .btn-save {
            background: #09f;
        }

        .btn-download {
            background: #4CAF50;
        }
    </style>
</head>
<body>
<div>
    <div class="set-option">
        <table>
            <tr>
                <td>画布尺寸</td>
                <td><input type="text" class="text" id="size"/></td>
            </tr>
            <tr>
                <td>背景图片</td>
                <td><input type="file" id="file"/></td>
            </tr>
            <tr>
                <td>用户名</td>
                <td>
                    <input type="text" class="text" id="user-name"/>
                </td>
            </tr>
            <tr>
                <td>用户名x坐标</td>
                <td>
                    <input type="number" class="text" id="text-option-x"/></br>
                    <p><input type="checkbox" class="check-box" value="1" id="is-center-x">居中显示</p>
                </td>
            </tr>
            <tr>
                <td>用户名y坐标</td>
                <td>
                    <input type="number" class="text" id="text-option-y"/></br>
                    <p><input type="checkbox" class="check-box" value="1" id="is-center-y">居中显示</p>
                </td>
            </tr>
            <tr>
                <td>用户名字体大小</td>
                <td><input type="number" class="text" id="text-size"/></td>
            </tr>
            <tr>
                <td>文字颜色</td>
                <td><input type="text" class="text" id="text-color"/></td>
            </tr>
            <tr>
                <td>图片类型</td>
                <td>
                    <select type="text" class="text" id="img-type">
                        <option value="jpg">jpg</option>
                        <option value="png">png</option>
                    </select>
                </td>
            </tr>
        </table>
        <button id="save-image" class="btn-save">效果预览</button>
        <button id="download-img" class="btn-download">下载当前图片</button>
        <button id="download-all" class="btn-all">批量导出</button>
    </div>
    <div class="show-canvas">
        <canvas width=200 height=200 id="thecanvas"></canvas>
    </div>
</div>
</body>
</html>

Эффект как на картинке, тогда хорошенько подумайте, насчет пригласительного билета, что нужно изменить! Нетрудно увидеть сравнение картинки выше! Есть следующие свойства, которые необходимо изменить: размер картинки, картинка, имя пользователя, координаты имени пользователя (отцентрованы ли оси x, y, x, центрирована ли ось y), размер шрифта имени пользователя, цвет шрифта имени пользователя и тип загружаемого изображения.

Это предполагает следующие параметры (мы видим, что некоторые параметры являются значениями, вы можете использовать их по умолчанию в строке)

var option = {
    img: '111.jpg',
    width: 500,
    height: 350,
    fontSize: "20px Microsoft YaHei",
    color: "black",
    text: '守候',
    imgType: 'jpg',
    x: 30,
    y: 30,
    xCenter: false,
    yCenter: false,
};

2-2. Шаги

1. Начальный эффект

В соответствии с вышеуказанными параметрами сначала нарисуйте предварительный эффект, код в основном представляет собой метод написания, навыков нет

//画图
function draw(obj) {
    var canvas = document.getElementById("thecanvas");
    //画布大小
    canvas.width = obj.width;
    canvas.height = obj.height;
    //设置图片
    var img = new Image();
    img.src = obj.img;
    var ctx = canvas.getContext("2d");
    //设置字体的坐标
    var _x = obj.x, _y = obj.y;
    //是否居中显示
    if (obj.xCenter) {
        _x = obj.width / 2;
    }
    if (obj.yCenter) {
        _y = obj.height / 2;
    }
    //图片加载后
    img.onload = function () {
        //先画图片
        ctx.drawImage(img, 0, 0);
        //设置文字的大小
        ctx.font = obj.fontSize;
        //设置文字的颜色
        ctx.fillStyle = obj.color;
        //设置文字坐标
        if (obj.xCenter) {
            ctx.textAlign = "center";
        }
        //画文字
        ctx.fillText(obj.text, _x, _y);
    };
}

window.onload = function () {
    draw(option);
}

2. Динамически изменять параметры

Видя, что картинка нарисована, работа фактически наполовину сделана!

Далее следует динамически изменять параметры! Этот шаг на самом деле очень прост.
Во-первых, измените размер холста

//画布尺寸
//获取按钮
var size = document.getElementById("size");
size.addEventListener("blur", function () {
    //根据空格,区分高宽
    var _width = parseInt(size.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/)[0]),
        _height = parseInt(size.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/)[1]);
    //把参数的width和height改掉
    option.width = _width || 100;
    option.height = _height || 100;
    //重新画图
    draw(option);
});

Приведенный выше код установлен. Пока поле ввода не потеряет фокус, размер холста будет изменен. Давайте запустим его ниже и посмотрим на эффект (gif-изображение неудовлетворительное, это всем понятно)

В холсте нет иерархии, пока холст меняется, его нужно перерисовывать. Даже если слово сдвинуто на один пиксель.

После этого займемся функцией выбора картинок!

//选择图片
//获取图片控件
var file = document.getElementById("file"), imagesFile, imageData;
file.addEventListener('change', function (e) {
    //获取图片
    imagesFile = e.target.files[0];
    //把图片转base64
    var reader = new FileReader();
    reader.readAsDataURL(imagesFile);
    //图片加载后
    reader.onload = function (e) {
        //设置option的img属性,再冲洗年绘制
        imageData = this.result;
        option.img = imageData;
        draw(option);
    }
});

Начинайте менять текст ниже, имя пользователя немного другое, я разделяю его пробелами. Если введено несколько имен пользователей, перерисуйте с первым именем пользователя. В следующем коде комментарии писаться не будут, в нем все та же логика, что и выше!

//用户名
var userName = document.getElementById("user-name");
userName.addEventListener("blur", function () {
    var _text = userName.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/);
    option.text = _text[0];
    draw(option);
});

Начнем с координат имени пользователя, с точки зрения кода это также сопутствующие свойства опции.

    optionXCenter.addEventListener("change", function () {
        if (optionXCenter.checked) {
            option.xCenter = true;
        }
        else {
            option.xCenter = false;
            option.x = parseInt(optionX.value);
        }
        draw(option);
    });
    //纵坐标
    var optionY = document.getElementById("text-option-y");
    optionY.value = option.y;
    var optionYCenter = document.getElementById("is-center-y");
    optionY.addEventListener("input", function () {
        if (optionYCenter.checked) {
            option.yCenter = true;
        }
        else {
            option.yCenter = false;
            option.y = parseInt(optionY.value);
        }
        draw(option);
    });
    //是否垂直居中显示
    optionYCenter.addEventListener("change", function () {
        if (optionYCenter.checked) {
            option.yCenter = true;
        }
        else {
            option.yCenter = false;
            option.y = parseInt(optionY.value);
        }
        draw(option);
    });

Отображать ли по центру по горизонтали

Другие свойства, размер и цвет шрифта, по сути, тот же код, и я не отпущу запущенные рендеры!

//字体颜色
var textColor = document.getElementById("text-color");
textColor.addEventListener("blur", function () {
    textColor.value === "" ? option.color = "#fff" : option.color = '#' + textColor.value;
    draw(option);
});
//字体大小
var textSize = document.getElementById("text-size");
textSize.addEventListener("input", function () {
    textSize.value === "" ? option.fontSize = '20px Microsoft YaHei' : option.fontSize = textSize.value + 'px Microsoft YaHei';
    draw(option);
});

3. Кнопочное управление

Предварительный просмотр эффекта

Это предварительный просмотр эффекта текущего холста.Это очень просто.Открыть новое окно и написать в нем картинку.

//预览图片
function saveImageInfo() {
    var mycanvas = document.getElementById("thecanvas");
    //生成图片
    var image = mycanvas.toDataURL("image/png");
    var w = window.open('about:blank', 'image from canvas');
    //把图片新进新的窗口
    w.document.write("<img src='" + image + "' alt='from canvas'/>");
}
var saveButton = document.getElementById("save-image");
saveButton.addEventListener('click', saveImageInfo);

Скачать текущее изображение

Скачай картинку, это в основном написано, это вся память

//图片类型
var imgType = document.getElementById("img-type");
imgType.addEventListener("change",function () {
    option.imgType=this.value;
});
//下载图片
function downloadImg(fileName) {
    //获取canvas
    var myCanvas = document.getElementById("thecanvas");
    //设置图片类型
    var image = myCanvas.toDataURL("image/" + option.imgType).replace("image/" + option.imgType, "image/octet-stream");
    var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    save_link.href = image;
    //设置下载图片的名称
    save_link.download = fileName + '.' + option.imgType;
    //下载图片
    var event = document.createEvent('MouseEvents');
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    save_link.dispatchEvent(event);
}

Загружайте изображения партиями

Это немного сложнее, но не сложно, давайте пошагово!

1. Сначала пакетный экспорт, потом имя пользователя через пробел, потом теперь получаю поле textAll в опции, набор всех текстов. все представляет, является ли это пакетной загрузкой. Атрибут fn представляет функцию обратного вызова.

//批量导出
var downloadAll = document.getElementById("download-all");
downloadAll.addEventListener('click', function () {
    var _text = userName.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/);
    option.textAll = _text;
    option.all = true;
    option.fn = downloadImg;
    draw(option);
});

2. Затем измените нарисованную функцию draw, чтобы определить, нарисована ли она вся!

function draw(obj) {
    var canvas = document.getElementById("thecanvas");
    //画布大小
    canvas.width = obj.width;
    canvas.height = obj.height;
    //设置图片
    var img = new Image();
    img.src = obj.img;
    var ctx = canvas.getContext("2d");
    //设置字体的坐标
    var _x = obj.x, _y = obj.y;
    //是否居中显示
    if (obj.xCenter) {
        _x = obj.width / 2;
    }
    if (obj.yCenter) {
        _y = obj.height / 2;
    }
    //图片加载后
    img.onload = function () {
        //是否是全部打印
        if(obj.all){
            //遍历textAll
            for(var i=0;i<obj.textAll.length;i++){
                //绘制图片
                ctx.drawImage(img,0,0);
                //设置字体大小
                ctx.font=obj.fontSize;
                //设置字体颜色
                ctx.fillStyle=obj.color;
                //是否居中显示
                if(obj.xCenter){
                    ctx.textAlign="center";
                }
                //绘制文字
                ctx.fillText(obj.textAll[i], _x,_y);
                //是否回调
                if(obj.fn){
                    obj.fn(obj.textAll[i]);
                }
            }
            //最后取消全部批量下载
            defult.all=false;
        }
        else{
            ctx.drawImage(img,0,0);
            ctx.font=obj.fontSize;
            ctx.fillStyle=obj.color;
            if(obj.xCenter){
                ctx.textAlign="center";
            }
            ctx.fillText(obj.text, _x,_y);
        }
    };
}

3. Резюме

Первая статья о начале работы с холстом написана здесь. После его написания я также обнаружил, что мало что понимаю в холсте! Приведенный выше пример является очень простым вводным примером холста знаний. Если холст изучить глубоко, то можно добиться множества удивительных эффектов. Это можно усилить в будущем. Если я найду какие-то знания, достойные записи, я тоже напишу статью. Холст — это очень ценное знание и очень интересное знание. Ждем новых обменов и обучения вместе с вами!



------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина