寫了不少的javascript和css3的文章,是時候寫一篇canvas的了。canvas是html5提供的一個新的功能!至於做用,就是一個畫布。而後畫筆就是javascript。canvas的用途很是的廣,特別是html5遊戲以及數據可視化這兩個方面。如今canvas給個人感受就和css3同樣,能夠不用太厲害,可是必需要會基礎的用法。可是之後對canvas的需求,確定會愈來愈大。因此canvas很值得學習,並且學好canvas,就是很好的一個加分項。對於這篇文章,我也是以canvas初學者的角度寫的,會有不少改善的地方。若是你們以爲我有什麼能夠改善的,或者建議,歡迎指點迷津!代碼已上傳github,須要的歡迎star(downloadImg)。javascript
你們看這篇文章以前,要了解javascript的一些基礎,也要看着瞭解一些canvas的api( canvas-MSN教程, canvas菜鳥教程)
邀請卡自動生成這個會有的,畢竟有時候,不少邀請卡都是同樣的,就是被邀請的人不同而已,也就是說,整個邀請卡,就是一個名字不同,那麼下面。就寫一套代碼,根據名字生成邀請卡!css
html代碼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軸是否居中),用戶名字體的大小,用戶名字體的顏色,以及下載圖片的類型。html5
這樣就獲得了以下的參數(你們看到有些參數是有值的,能夠想成默認值就好了)java
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,
};複製代碼
根據上面的參數,先初步畫一個效果,代碼基本都是一個寫法,沒什麼技巧css3
//畫圖
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);
}
複製代碼
看到圖已經畫好了,工做其實已經完成一半了!git
下面就是動態改變參數!這一步其實很簡單。
首先,改變畫布的尺寸github
//畫布尺寸
//獲取按鈕
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,都要重繪。哪怕就是一個字移動一個像素。
作好了這個,下面作選擇圖片的功能!api
//選擇圖片
//獲取圖片控件
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);
});
複製代碼
下面開始用戶名的座標,代碼方面,也是改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);
});
複製代碼
效果預覽
就是預覽當前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);
複製代碼
下載當前圖片
下載圖片這個,基本也是寫法的,都是些記憶的東西
//圖片類型
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.首先批量導出,那麼用戶名我這裏是使用空格分割,那麼如今我在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的也是有不少的不懂!上文的這例子,知識canvas很簡單的一個入門實例。canvas若是深刻學習,能作到不少讓人驚訝的效果,這個得之後要增強學習,若是發現些值得記錄的知識,我也會寫文章。canvas是一個很是值得學習的知識,也是頗有趣的一個知識。期待與你們有更多的交流和學習!
-------------------------華麗的分割線--------------------
想了解更多,關注關注個人微信公衆號:守候書閣