1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 微信小程序Canvas绘制主页保存到手机相册

微信小程序Canvas绘制主页保存到手机相册

时间:2018-12-01 23:09:59

相关推荐

微信小程序Canvas绘制主页保存到手机相册

本篇文章适用于保存用户主页、海报等至手机相册,内容包含圆角头像、文字超出显示省略号、多行超出显示省略号!(整体代码放入最下方可直接复制查看)

话不多说上图

页面如下

保存相册之后如下

整体分三部分来讲,分为wxml、wxss、js,主讲js!!!

wxml

页面除了canvas还有其他元素主要就是想让页面看起来不那么难看

<view class="canvasBox"><canvas canvas-id='myCanvas' style='width:{{canvasWidth}}px;height: {{canvasHeight}}px;'></canvas></view><view bindtap="saveHomepage" hover-class="btnHover" class="btn">保存主页</view>

wxss

在页面上加上样式

page {background-color: antiquewhite;}.canvasBox {display: flex;justify-content: center;padding: 20px 0;}.btn {width: 100px;height: 42px;background: #FFD401;border-radius: 22px;margin: 0 auto;line-height: 42px;text-align: center;}.btnHover {opacity: .7;}

以上两部分没什么说的。

主要还是js

data里面放了canvas的宽高,因为下面也有用到,如果改的话只需要改动data就行了

data: {canvasWidth: 250,canvasHeight: 250}

声明一个函数 getCanvasImg(canvasId) 用来生成canvas主页;

参数canvasId:canvas的id;

主页绘制顺序是先把名字、简介绘制上去最后再去绘制圆形头像;

首先获取canvas的宽高并且给canvas一个白色的背景

let {canvasWidth,canvasHeight} = this.data;let ctx = wx.createCanvasContext(canvasId);//给canvas一个白色背景ctx.fillStyle = '#FFFFFF';ctx.fillRect(0, 0, canvasWidth, canvasHeight);ctx.fill();

将名字绘制指定位置,声明字体颜色、行高等通用变量;

名字水平居中显示,通过canvas的宽的1/2减去名字宽度的1/2;

canvas的measureText()方法返回指定字符串的一个对象包含宽度可以用measureText(str).width获取

let fontColor = "#333333"; //字体颜色let lineHeight = 25; //文字行高let nameMove = '《龙猫》';ctx.font = 'normal 16px Arial';ctx.setFillStyle(fontColor);// 名字居中显示ctx.fillText(nameMove, canvasWidth / 2 - ctx.measureText(nameMove).width / 2, 140);

此时的canvas如图

接下来是主页简介部分:

canvas没有给定方法可以让文字自动换行、超出显示省略号。

我们可以通过measureText()方法获取字符串的长度进行操作

看下面这个方法

封装一个函数textSplit(ctx, text, lineWidth, lines);

ctx:页面的canvas

text:需要分割的文本

lineWidth:canvas上显示文本的宽度

lines:指定行数显示省略号

方法描述:

1.通过measureText()方法获取字符串的长度;

2.根据你要在canvas上要显示的文本宽度进行判断;

3.把字符串分割通过一个字符一个字符相加获取长度,与你要显示的长度进行比较,如果大于切割,暂存数组,继续判断;多行还要进行,行数判断,当达到最后一行时,判断暂存数组的最后一个,长度是否还大于要显示的长度,如果大于进行切割拼接省略号,然后return返回。

//根据文字分割textSplit(ctx, text, lineWidth, lines) {if (ctx.measureText(text).width < lineWidth) {return [text]} else {let textArr = []; //暂存数组let c_text = ''; //字符拼接之后的字符串for (let i = 0; i < text.length; i++) {if (ctx.measureText(c_text).width < lineWidth) {//字符拼接获取宽度进行判断c_text += text[i]} else {//行数判断if (textArr.length < lines) {textArr.push(c_text)c_text = text[i];} else if (textArr.length == lines) {let c_str = textArr[lines - 1];c_str = c_str.slice(0, c_str.length - 3) + '...'textArr[lines - 1] = c_str;return textArr} else {return textArr}}};textArr.push(c_text);return textArr}}

对主页简介文字绘制

//封装一个函数,ctx:获取的canvas,maskText传的字符串,250:所需要的宽度,2:超出指定行数显示省略号let maskText = '宫崎骏的《龙猫》你看懂了吗?带你寻找隐藏的教育意义!如果你在下雨天的车站,遇到被淋湿的妖怪,请把雨伞借给它,你会得到森林的通行证哦!'; //文字let showText = this.textSplit(ctx, maskText, 230, 2);console.log(showText);showText.forEach((item,index)=>{ctx.font = 'normal 14px Arial';ctx.setFillStyle(fontColor);ctx.fillText(item,15 , 170 + index*lineHeight);})

到这里,简介文字已经绘制完毕,看一下效果

接下来就是头像

canvas同样没有直接给绘制圆形头像的方法,我们可以通过arc()画圆,通过clip()剪切圆形区域,只有圆形区域可见,这样就形成了圆形头像。

// 头像居中显示ctx.save();ctx.beginPath();ctx.arc(canvasWidth / 2, 65, 40, 0, 2 * Math.PI);ctx.clip();ctx.drawImage('/image/02.png', 50, 0, 200, 200);ctx.restore()

到这之后canvas主页就已经绘制完毕了

接下来就是如何将绘制的主页保存至手机上

还是一样弄个函数

saveHomepage()保存主页

方法描述:

1.通过wx.getSetting()判断当前小程序是否有保存相册的权限;

2.如果有,调用 wx.saveImageToPhotosAlbum()直接保存;

3.如果没有,调用wx.authorize()向用户发起相册授权请求;

4.如果授权允许,调用 wx.saveImageToPhotosAlbum()直接保存;

5.如果拒绝授权给个弹窗提示

// 保存saveHomepage(){let that = this;//判断当前小程序是否有保存相册的权限wx.getSetting({success(res) {if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success(res) {that.startSaveImage();},fail() {//这里是用户拒绝授权后的回调wx.showModal({content: '请允许相册权限,拒绝将无法正常使用小程序',showCancel: false,success() {wx.openSetting({success(settingdata) {if (settingdata.authSetting["scope.writePhotosAlbum"]) {} else {console.log("获取权限失败")}}})}})}})} else {that.startSaveImage();}}})},

为了方便调用保存相册,单独把保存方法wx.saveImageToPhotosAlbum()封装起来了

// 确认开启相册权限,canvas绘画完成,canvas生成图片完成startSaveImage() {let that = this;wx.saveImageToPhotosAlbum({filePath: that.data.homePage,success(res) {wx.showToast({title: '保存成功',icon: 'success',duration: 1500})},fail(err) {console.log('err', err);}});},

到此全部流程已经结束了,上面圆形头像采用是本地图片,如果是线上还要使用wx.downloadFile()转成本地路径才能使用。

整体代码

wxml

<view class="canvasBox"><canvas canvas-id='myCanvas' style='width:{{canvasWidth}}px;height:{{canvasHeight}}px;'></canvas></view><view bindtap="saveHomepage" hover-class="btnHover" class="btn">保存主页</view>

wxss

page {background-color: antiquewhite;}.canvasBox {display: flex;justify-content: center;padding: 20px 0;}.btn {width: 100px;height: 42px;background: #FFD401;border-radius: 22px;margin: 0 auto;line-height: 42px;text-align: center;}.btnHover {opacity: .7;}

js

Page({data: {canvasWidth: 250,canvasHeight: 250},// 获取主页getCanvasImg(canvasId) {return new Promise((resolve, reject) => {let {canvasWidth,canvasHeight} = this.data;let ctx = wx.createCanvasContext(canvasId);//给canvas一个白色背景ctx.fillStyle = '#FFFFFF';ctx.fillRect(0, 0, canvasWidth, canvasHeight);ctx.fill();let maskText = '宫崎骏的《龙猫》你看懂了吗?带你寻找隐藏的教育意义!如果你在下雨天的车站,遇到被淋湿的妖怪,请把雨伞借给它,你会得到森林的通行证哦!'; //文字let fontColor = "#333333"; //字体颜色let lineHeight = 25; //文字行高let nameMove = '《龙猫》';ctx.font = 'normal 16px Arial';ctx.setFillStyle(fontColor);// 名字居中显示ctx.fillText(nameMove, canvasWidth / 2 - ctx.measureText(nameMove).width / 2, 140);//封装一个函数,ctx:获取的canvas,maskText传的字符串,250:所需要的宽度,2:超出指定行数显示省略号let showText = this.textSplit(ctx, maskText, 230, 2);showText.forEach((item,index)=>{ctx.font = 'normal 14px Arial';ctx.setFillStyle(fontColor);ctx.fillText(item,15 , 170 + index*lineHeight);})// 头像居中显示ctx.save();ctx.beginPath();ctx.arc(canvasWidth / 2, 65, 40, 0, 2 * Math.PI);ctx.clip();ctx.drawImage('/image/02.png', 50, 0, 200, 200);ctx.restore()ctx.draw(false, () => {wx.canvasToTempFilePath({width: canvasWidth,height: canvasHeight,canvasId,success: function (res) {resolve(res.tempFilePath);},fail: function (res) {reject(res)}}, this);});})},// 保存saveHomepage(){let that = this;//判断当前小程序是否有保存相册的权限wx.getSetting({success(res) {if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success(res) {that.startSaveImage();},fail() {//这里是用户拒绝授权后的回调wx.showModal({content: '请允许相册权限,拒绝将无法正常使用小程序',showCancel: false,success() {wx.openSetting({success(settingdata) {if (settingdata.authSetting["scope.writePhotosAlbum"]) {} else {console.log("获取权限失败")}}})}})}})} else {that.startSaveImage();}}})},// 确认开启相册权限,canvas绘画完成,canvas生成图片完成startSaveImage() {let that = this;wx.saveImageToPhotosAlbum({filePath: that.data.homePage,success(res) {wx.showToast({title: '保存成功',icon: 'success',duration: 1500})},fail(err) {console.log('err', err);}});},//根据文字分割textSplit(ctx, text, lineWidth, lines) {if (ctx.measureText(text).width < lineWidth) {return [text]} else {let textArr = []; //暂存数组let c_text = ''; //字符拼接之后的字符串for (let i = 0; i < text.length; i++) {if (ctx.measureText(c_text).width < lineWidth) {//字符拼接获取宽度进行判断c_text += text[i]} else {//行数判断if (textArr.length < lines) {textArr.push(c_text)c_text = text[i];} else if (textArr.length == lines) {let c_str = textArr[lines - 1];c_str = c_str.slice(0, c_str.length - 3) + '...'textArr[lines - 1] = c_str;return textArr} else {return textArr}}};textArr.push(c_text);return textArr}},onLoad() {this.getCanvasImg('myCanvas').then(res=>{this.setData({homePage:res});});},})

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。