canvas入門實戰--邀請卡生成與下載

守候i發表於2017-12-14

1.前言

寫了很多的javascript和css3的文章,是時候寫一篇canvas的了。canvas是html5提供的一個新的功能!至於作用,就是一個畫布。然後畫筆就是javascript。canvas的用途非常的廣,特別是html5遊戲以及資料視覺化這兩個方面。現在canvas給我的感覺就和css3一樣,可以不用太厲害,但是必須要會基礎的用法。但是以後對canvas的需求,肯定會越來越大。所以canvas很值得學習,而且學好canvas,就是很好的一個加分項。對於這篇文章,我也是以canvas初學者的角度寫的,會有很多改善的地方。如果大家覺得我有什麼可以改善的,或者建議,歡迎指點迷津!程式碼已上傳github,需要的歡迎star(downloadImg)。

大家看這篇文章之前,要了解javascript的一些基礎,也要看著瞭解一些canvas的api(canvas-MSN教程canvas菜鳥教程

2.邀請卡例項

邀請卡自動生成這個會有的,畢竟有時候,很多邀請卡都是一樣的,就是被邀請的人不一樣而已,也就是說,整個邀請卡,就是一個名字不一樣,那麼下面。就寫一套程式碼,根據名字生成邀請卡!

2-1.執行效果

canvas入門實戰--邀請卡生成與下載

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);
}

複製程式碼

canvas入門實戰--邀請卡生成與下載

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圖差強人意,大家看懂就好)

canvas入門實戰--邀請卡生成與下載

canvas沒有層級的說法,只要改canvas,都要重繪。哪怕就是一個字移動一個畫素。

做好了這個,下面做選擇圖片的功能!

//選擇圖片
//獲取圖片控制元件
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);
    }
});

複製程式碼

canvas入門實戰--邀請卡生成與下載

下面開始改文字,使用者名稱這個有點不一樣,我以空格分割。如果輸入多個使用者名稱,以第一個使用者名稱重繪。下面程式碼,註釋就不寫了,還是和上面的邏輯一樣!

//使用者名稱
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);
});

複製程式碼

canvas入門實戰--邀請卡生成與下載

下面開始使用者名稱的座標,程式碼方面,也是改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);
    });
複製程式碼

canvas入門實戰--邀請卡生成與下載

是否水平居中顯示

canvas入門實戰--邀請卡生成與下載

其他的屬性,字型大小和顏色,基本是一樣的程式碼,執行的效果圖我不放了!

//字型顏色
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.按鈕操作

效果預覽

就是預覽當前canvas的一個效果,這個就很簡單了,就是新開一個視窗,然後把圖片寫進去而已

//預覽圖片
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);
複製程式碼

canvas入門實戰--邀請卡生成與下載

下載當前圖片

下載圖片這個,基本也是寫法的,都是些記憶的東西

//圖片型別
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);
}

複製程式碼

canvas入門實戰--邀請卡生成與下載

批量下載圖片

這個複雜一點,但也不難,下面一步一步來!

1.首先批量匯出,那麼使用者名稱我這裡是使用空格分割,那麼現在我在option裡面,弄一個欄位textAll,所有文字的集合。all代表是否是批量下載。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);
        }
    };
}
複製程式碼

canvas入門實戰--邀請卡生成與下載

canvas入門實戰--邀請卡生成與下載

3.小結

關於canvas入門的第一篇文章,就寫到這裡了。寫完之後,也發現自己對canvas的也是有很多的不懂!上文的這例子,知識canvas很簡單的一個入門例項。canvas如果深入學習,能做到很多讓人驚訝的效果,這個得以後要加強學習,如果發現些值得記錄的知識,我也會寫文章。canvas是一個非常值得學習的知識,也是很有趣的一個知識。期待與大家有更多的交流和學習!



-------------------------華麗的分割線--------------------
想了解更多,關注關注我的微信公眾號:守候書閣

canvas入門實戰--邀請卡生成與下載


相關文章