小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
蹭一波热度
值此华夏举国欢庆之日,微信的过期头像每年都是一个小小的热点话题,作为一只文章人,当然是要蹭一下热点了。
这不,带上目前再用的uniapp来蹭一波热度了,在首页看到有小伙伴用css或者其他的实现了一波,我就想,他们用js或者css实现的,没法反馈给用户啊,但是JavaScript的canvas是可以提供给jpg的图片的。不是更合适吗?
先找到一波素材;这是最终要实现的效果
那么我们可以找到国旗,分别制作好对应的红旗的png部分,这里拿单图举例,其他同理。
有图如上,扣掉中间灰色的部分,保留整体的框架宽高。然后在canvas中组合图片。
使用uniapp的input组件选中图片后,拿到图片的临时地址。
previewImage() {
var _this = this;
uni.showLoading({
title: '图片生成中...'
});
// 将图片写入画布
const ctx = uni.createCanvasContext('myCanvas');
// 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W - 4;
var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H - 4;
var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W + 2;
var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H + 2;
ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
ctx.globalCompositeOperation = 'destination-in';
ctx.fillStyle = '#fff';
ctx.arc(canvasL + canvasW / 2, canvasT + canvasW / 2, canvasW / 2, 0, 2*Math.PI);
ctx.fill();
ctx.globalCompositeOperation = 'lighter';
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, _this.imageW, _this.imageH);
//确定之后才能画到canvas上
ctx.draw(false, () => {
uni.canvasToTempFilePath({
x: canvasL,
y: canvasT,
width: canvasW,
height: canvasH,
destWidth: SCREEN_WIDTH * 0.8,
destHeight: SCREEN_WIDTH * 0.8,
canvasId: 'myCanvas',
quality: 1,
success: function(res) {
uni.hideLoading();
// 成功获得地址的地方
uni.previewImage({
current: '', // 当前显示图片的http链接
urls: [res.tempFilePath] // 需要预览的图片http链接列表
});
},
fail: err => {
console.log(err);
}
});
});
},
之后再将提供一个选择项供用户选择,讲选中的png素材图放在头像之上即可。
uni.canvasToTempFilePath({
x: 100,
y: 200,
width: 50,
height: 50,
destWidth: 100,
destHeight: 100,
canvasId: 'myCanvas',
success: function(res) {
// 在H5平台下,tempFilePath 为 base64
console.log(res.tempFilePath)
}
})