9月24日,微信头像合成爆红,公司为了趁热点,也要做一个类似的功能,于是利用canvas也做了一个 ,其实很简单直接上代码
<div id="app">
<div class="wrap-bg">
<div class="header">
<div class="header-logo-box">
<img class="header-logo" src="./images/header_logo.png" alt="">
</div>
<div>
<img class="header-title" src="./images/header_title.png" alt="">
</div>
<div>
<img class="header-avatar" src="./images/header_avatar.png" alt="">
</div>
</div>
<div class="avatar-wrap">
<div class="btn-flex-left">
<div class="btn-left" @Click="pre"></div>
</div>
<div class="avatar-box">
<img v-for="(i,index) in canvasimg" :class="activeIndex===index?'avatar-show':'avatar-hide'" :src="i" alt="">
</div>
<div class="btn-flex-right">
<div class="btn-right" @Click="next"></div>
</div>
</div>
<div class="share-btn" >长按分享给好友</div>
</div>
<div style =" position: fixed;left: 0;bottom: 13.333vw;width: 100vw;height: 32.533vw;overflow: hidden;cu">
<img style="width: 100%" src="./images/fix_bg.png" alt="">
</div>
<a href="">
<div class="fix-bar">
<div class="fix-logo">
<img class="fix-logo-icon" src="./images/yuema_logo.png" alt="">
</div>
</div>
</a>
<canvas class="canvas" id="canvas0"></canvas>
<canvas class="canvas" id="canvas1"></canvas>
<canvas class="canvas" id="canvas2"></canvas>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
title: '头像活动',
dress: [
'./images/icon_00.png',
'./images/icon_01.png',
'./images/icon_02.png',
],
avatar: './test_avatar.jpg',
canvasimg: ['', '', ''],
activeIndex: 0,
mask:false
},
mounted() {
this.drawimg(0)
this.drawimg(1)
this.drawimg(2)
},
methods: {
next() {
if (this.activeIndex >= 2) {
this.activeIndex = 0
} else {
this.activeIndex = this.activeIndex + 1
}
},
pre() {
if (this.activeIndex <= 0) {
this.activeIndex = 2
} else {
this.activeIndex = this.activeIndex - 1
}
},
drawimg(index) {
var that = this;
var canvas = document.getElementById('canvas' + index);
var ctx = canvas.getContext('2d');
canvas.width = 180;//canvas画布的宽度
canvas.height = 180;//canvas画布大小
var img1 = new Image();
// img1.setAttribute('crossOrigin', 'anonymous');
img1.src = that.avatar
img1.onload = function () {
ctx.clearRect(0, 0, 180, 180)
//把图片画到canvas上
ctx.drawImage(
img1, 0, 0, 180, 180
);
var img2 = new Image();
// img2.setAttribute('crossOrigin', 'anonymous');
img2.src = that.dress[index]
img2.onload = function () {
ctx.drawImage(
img2, 0, 0, 180, 180
)
var url = document.getElementById('canvas' + index).toDataURL("image/png")
that.canvasimg.splice(index, 1, url)
setTimeout(function () {
ctx.clearRect(0, 0, 180, 180)
}, 300)
}
}
}
}
})
</script>
基本思路
利用canvas 将两张或多张图标叠加在一起,生成新图像;再通过toDataURL导出图片,就可以实现展示和下载.
1.获取原头像 和 合成边框 图像;
2.通过 ctx.drawImage,依次将 原头像和合成边框 绘制到 canvas 上;
3.通过 canvas.toDataURL ,返回一个包含图片展示的 data URL;
4.通过 data URL 实现展示和下载
注意事项
- 多张头像切换方案
- 实时切换时动态,canvas生成,不预加载图片,根据网络情况会出现空白期
- 一次全部生成 ,
- 图片加载
- 图片加载 属于异步,一次性全部生成会出现,单个 canvas处理时会出现加载阻塞,所以我采用多个canvas同时处理.
- 注意图片加载跨域,需要设置img.setAttribute(‘crossOrigin’, ‘anonymous’)