
本篇基本思路為:通過復制商品的圖片(一般是在QQ群或者微信群)卖漫,然后顯示在網(wǎng)頁的Canvas里面费尽,再將相對應的網(wǎng)址生成二維碼,也在Canvas顯示懊亡,最終自動合成為一個圖片依啰。那么就可以復制到群里面去,圖片就帶有二維碼了店枣。而不用打開圖像編輯軟件速警,直接在代碼里面生成叹誉。
上篇說到Flash江河日下,jQuery同樣也是江河日下闷旧,技術的發(fā)展真是日新月異长豁。在下面這個例程里面,我將使用Vue.js和Canvas制作二維碼和商品圖片的合成圖片忙灼。所以匠襟,這篇博客可以當做是淘客網(wǎng)站的制作思路,也可以視為Vue.js和Canvas的基礎教程该园。
Vue.js 是當下很火的一個JavaScript MVVM庫酸舍,它是以數(shù)據(jù)驅動和組件化的思想構建的。相比于Angular.js里初,Vue.js提供了更加簡潔啃勉、更易于理解的API,使得我們能夠快速地上手并使用Vue.js双妨。
如果你之前已經習慣了用jQuery操作DOM淮阐,學習Vue.js時請先拋開手動操作DOM的思維,因為Vue.js是數(shù)據(jù)驅動的刁品,你無需手動操作DOM泣特。它通過一些特殊的HTML語法,將DOM和數(shù)據(jù)綁定起來挑随。一旦你創(chuàng)建了綁定状您,DOM將和數(shù)據(jù)保持同步,每當變更了數(shù)據(jù)兜挨,DOM也會相應地更新竞阐。
Vue.js 自身不是一個全能框架——它只聚焦于視圖層。因此它非常容易學習暑劝,非常容易與其它庫或已有項目整合骆莹。另一方面,在與相關工具和支持庫一起使用時担猛,Vue.js 也能完美地驅動復雜的單頁應用幕垦。
我們首先來進行一個簡單二維碼生成界面。在以前傅联,我是使用jQuery.qrcode這個插件進行二維碼生成的先改,由于使用了Vue.js以后,我并不想那么依賴jQuery蒸走。于是我重新找了QRCanvas
這是一個用純JavaScript編寫的二維碼生成器仇奶。唯一的要求是瀏覽器與大多數(shù)現(xiàn)代瀏覽器支持的Canvas才能工作。
在官方的例程里面非常簡單:
<div id="qrcode"></div>
<script src="https://unpkg.com/qrcanvas"></script>
<!-- A slim version is not bundled with any effects. -->
<script src="https://unpkg.com/qrcanvas/dist/qrcanvas.slim.js"></script>
<script type="text/javascript">
var canvas = qrcanvas({
data: 'hello, world'
});
document.getElementById('qrcode').appendChild(canvas);
</script>
那么我需要的場景是有一個文本輸入框比驻,填入網(wǎng)址以后该溯,點擊按鈕生成二維碼岛抄。并且我想結合Vue.js進行使用。
代碼如下:
<body>
<div id="qrcode"></div>
<div id="app1">
<input type="text" class="form-control" placeholder="請輸入網(wǎng)址" id="code" v-model="code2">
<a href="#" @click="addRow()" class="btn btn-primary">二維碼</a>
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/qrcanvas/dist/qrcanvas.slim.js"></script>
<script>
var app8 = new Vue({
el: "#app1",
data: {
code2: ''
},
methods: {
addRow: function (name) {
var _this = this;
if (_this.code2) {
var canvas1 = qrcanvas({
data: _this.code2,
size: 128
});
document.getElementById("qrcode").innerHTML = '';
document.getElementById('qrcode').appendChild(canvas1);
}
},
}
})
</script>
</body>
測試通過狈茉,運行成功夫椭。
那么接下來我們再來新建一個文件,這次我希望在一個文本框里面復制圖片氯庆,然后將圖片放到Canvas里面蹭秋。
<body>
<div class="container" id="app">
<h1>復制圖片</h1>
<div class="input-group ma-b-10">
<span class="input-group-addon" id="basic-addon3">粘貼</span>
<input ref="input" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
獲得<code>base64數(shù)據(jù)</code>
</h4>
<textarea
v-if="base64"
class="form-control"
id="base64"
rows="3"
v-model="base64">
</textarea>
</div>
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
生成<code>img</code>
</h4>

</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
base64: ''
},
mounted: function () {
var _this = this
this.$refs.input.addEventListener("paste", function (e){
if ( !(e.clipboardData && e.clipboardData.items) ) {
return ;
}
for (var i = 0; i < e.clipboardData.items.length; i++) {
if (e.clipboardData.items[i].type === 'image/png'){
var pasteFile = e.clipboardData.items[i].getAsFile();
var reader = new FileReader();
reader.readAsDataURL(pasteFile);
reader.onload=function(e){
_this.base64 = this.result;
}
}
}
});
}
})
</script>
</body>
代碼其原理就是通過獲取圖像數(shù)據(jù),如果該數(shù)據(jù)是圖片類型的堤撵,那么就調用 reader.readAsDataURL
將其圖片顯示出來仁讨。
這個功能就是可以在QQ群、微信群里面实昨,對圖片復制陪竿,我們粘貼以后就顯示在網(wǎng)頁里面。然后在結合網(wǎng)址生成二維碼屠橄,通過代碼將其合成在一起。
那么現(xiàn)在核心問題來了闰挡,怎么通過代碼來合成兩個圖片呢锐墙?
在寫代碼的中間還是發(fā)生了很多問題,例如用base64代碼我不知道怎么去獲取它的尺寸长酗,只好用#imgdiv讓它顯示出圖片后再得出尺寸溪北,等到合成二維碼圖片完成以后,我再將其隱藏掉《崞ⅲ現(xiàn)在先看一下html代碼:
<div class="container" id="app">
<h1>復制圖片</h1>
<div class="input-group ma-b-10">
<span class="input-group-addon" id="basic-addon3">粘貼</span>
<input ref="input" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
獲得base64數(shù)據(jù)
</h4>
<textarea v-if="base64" class="form-control" id="base64" rows="3" v-model="base64">
</textarea>
</div>
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
生成 img
</h4>
<canvas id="myCanvas">
你的瀏覽器不支持canvas之拨,建議使用最新版的Chrome瀏覽器。
</canvas>
<div id="tempDiv"></div>

</div>
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
圖片生成
</h4>
<input type="text" class="form-control" placeholder="請輸入網(wǎng)址" id="code" v-model="code2"><br/>
<a href="#" @click="addRow()" class="btn btn-primary">二維碼</a>
</div>
</div>
</div>
JavaScript的代碼:
var vm = new Vue({
el: '#app',
data: {
base64: '',
code2: ''
},
mounted: function () {
var _this = this
this.$refs.input.addEventListener("paste", function (e) {
if (!(e.clipboardData && e.clipboardData.items)) {
return;
}
for (var i = 0; i < e.clipboardData.items.length; i++) {
if (e.clipboardData.items[i].type === 'image/png') {
var pasteFile = e.clipboardData.items[i].getAsFile();
var reader = new FileReader();
reader.readAsDataURL(pasteFile);
reader.onload = function (e) {
_this.base64 = this.result;
}
}
}
});
},
methods: {
addRow: function () {
var _this = this;
if (_this.code2) {
var canvas0 = qrcanvas({
data: _this.code2,
size: 128
});
var image = new Image();
image.src = canvas0.toDataURL("image/png");
var img_all=new Image();
img_all.src=_this.base64;
var nWidth = document.getElementById('imgdiv').naturalWidth;
var nHeight = document.getElementById('imgdiv').naturalHeight;
image.setAttribute("crossOrigin", 'anonymous');
img_all.setAttribute("crossOrigin", 'anonymous');
console.log(nWidth);
console.log(nHeight);
var canvas = document.getElementById("myCanvas");
canvas.width = nWidth;
canvas.height = nHeight;
var ctx = canvas.getContext("2d");
ctx.rect(0,0, nWidth, nHeight);
ctx.fillStyle = "#fff";
ctx.fill();
img_all.addEventListener("load",function(){
ctx.drawImage(img_all, 0, 0, nWidth,nHeight);
},false);
image.addEventListener("load",function(){
ctx.drawImage(image, nWidth-128, nHeight-128,128,128);
imageURL = canvas.toDataURL("image/png");
var img3 = new Image();
document.getElementById('tempDiv').appendChild(img3);
img3.src = imageURL;
canvas.style.display = "none";
document.getElementById('imgdiv').style.display = "none";
},false);
}
},
}
})
其實還是寫得很匆忙的咧叭,里面是有一些錯漏的地方蚀乔,敬請指教。最終效果如下圖: