一、写在前面:
9月24号朋友圈,这一波爱国风,一切换国庆专属头像的活动,应该是卷席各位老铁的朋友圈,作为程序员,代码源于生活,笔者稍微手一痒,就想了一下原理是很简单的,于是乎,自己撸一个制作“国庆头像”的小程序来~,目前只是一个小demo,效果如下图(UI基本上搬腾讯新闻原版活动界面),很多功能也由于微信API调用需要的config配置,未提供实现代码,基于 Vue2.6x 构建的项目,源码码可以移步至
二、前情回顾:
9月24号一大早,估计很多人的朋友圈是这样的:
腾讯新闻官方推出“迎国庆换新颜”活动 ,可领取你的国庆专属头像,包括70纪念徽章、小国旗,不过仅仅一天官方就关闭了活动。
接下来我们,就自己撸一个,上车
三、简析实现原理
其实我们看页面的话,内容很简单,就是一个轮播图切换国庆背景的边框,然后点击保存,其实,这里是涉及Canvas知识点,大概可以分成以下几步:
1、获取或者上传微信头像
2、Canvas实现绘图和头像合成: Canvas实现定位绘图,以及两张图片的合成
3、保存合成的图片 将图片转换为base64,保存头像
四、构建项目
本项目是基于 Vue2.6x 构建的项目
第一步、布局切图
这是最基础的前端技能,就略了,这里主要就是一个轮播图的实现,在本项目中,我把这个拆一个轮播组件,目前写的是没有过渡动画特效的(有兴趣的同学可以优化一下,加点切换动画),如下图
目录components/slideshow.vue
<template>
<div class="slideshow-warpper">
<div class="img-warpper">
<div class="border-img">
<img :src="borderImgList[nowIndex].src" ref="isBorderImg" />
</div>
<div class="head-img">
<img :src="headImg" ref="isHeadImg" />
</div>
</div>
<div class="btn" @click="goto(prevIndex)"></div>
<div class="btn next" @click="goto(nextIndex)"></div>
</div>
</template>
<script>
export default {
name: "slideshow",
props: ["borderImgList", "headImg"],
data() {
return {
nowIndex: 0,
selectBorderImg: this.borderImgList[0].src
};
},
methods: {
goto(index) {
this.nowIndex = index;
this.selectBorderImg = this.borderImgList[index].src;
}
},
computed: {
prevIndex() {
if (this.nowIndex === 0) {
return this.borderImgList.length - 1;
} else {
return this.nowIndex - 1;
}
},
nextIndex() {
if (this.nowIndex === this.borderImgList.length - 1) {
return 0;
} else {
return this.nowIndex + 1;
}
}
}
};
</script>
这里代码很平淡,主要就是一个数组背景边框为背景,然后循环切换。这边的逻辑比较简单,
值得一提的是,vue关于src图片的坑,想必很多人都会遇到,就是正常img里加src="变量",这样是不会显示
举个例子,父组件传来的一个图片的URL,如果你子组件
URL = '/assets/border1.png'
<img :src="URL" />
这样是不显示的
但是你在子组件里直接,是可以正常加载图片的
<img :src="/assets/border1.png" />
这时候解决办法,通常就是加个 require(),例如
headImg: require("../assets/test.jpg"),
第二步、canvas合成图片
这里就是涉及到一些简单的canvas标签的运用
1、首先我们要创建一个canvas元素,创建canvas绘图的环境,设置画布长宽
2、把利用drawImage方法(详细的可以移步)两张照片绘制合成一张照片
3、设置图片返回的格式,HTMLCanvasElement.toDataURL() 方法
save() {
let slideshowChild = this.$refs.slideshowChild.$refs;
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
canvas.width = 150;
canvas.height = 150;
ctx.drawImage(slideshowChild.isHeadImg, 0, 0, 150, 150);
ctx.drawImage(slideshowChild.isBorderImg, 0, 0, 150, 150);
let urlSrc = canvas.toDataURL("img/png");
this.showCanvas = true;
console.log(urlSrc);
// wx.saveImageToPhotosAlbum({
// filePath: urlSrc
// });
},
接下来
我们拿一张图片做测试ok的。
五、获取或者上传头像
这块涉及到微信weixin-js-sdk,在项目中安装它
npm install weixin-js-sdk
接下来因为当用户从微信一进入页面需要授权获取用户信息,这里无论是 微信网页开发,还是小程序开发都涉及到授权,具体而言,网页授权流程分为四步:
1、引导用户进入授权页面同意授权,获取code
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
3、如果需要,开发者可以刷新网页授权access_token,避免过期
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
这里就能获取到微信头像
当然这就需要你自己在微信公众平台申请一个账号,笔者这里由于个人公众号和小程序的开发账号,都太久没玩,被冻结了,后面补全这些功能
上传图片,保存这些都有API可以现成的用咯
本项目里在/api/sdk.js,有部分封装
五、最后
文章写到这里,基本告一段落了,看起来这么火的活动,背后其实是可以用这么简单的代码实现的,代码源于生活,嘿嘿,是不是很有趣,目前微信sdk相关的部分代码未上传,可以给各位老铁,自行下载去玩,当然我也会尽快补全。国庆到了,祝各位老铁,国庆快乐呀~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。