一、图片生成变形
程序员的口头禅“我电脑上没问题啊”。
在开发微信小程序时,常常会讲一句话:“我的手机上没问题”。世界上最可恶的事情是开发用的安卓,而验收用的是ios。我们使用微信开发工具时,常常不会遇到什么问题,等在安卓真机调试时就会有些小bug,再看看ios手机,他喵的更多bug了。最后你会发现在微信小程序电脑端上看,就更更更离谱了。
微信小程序在电脑端加载非常慢,有很多问题是微信自身问题无法解决,这里不讨论了。
而我们在生成海报等需求时,用canvas生成图片在安卓上不会有问题,ios会出现变形问题。
解决方法:
首先在创建canvas元素时就应该设定好标签的width以及height值,准确来说应该是在你绘制已填充矩形,就是设置fillRect时就设置好height的值,并且设置fillRect的高度应该与canvas元素的height一样,这样就不会因为不匹配而拉长或者压缩。
//这里设置好width、height,或者在方法内部设置也可以
<canvas type="2d" id="posterItem" class="widget" style="width:350px;height:440px;"></canvas>
//js中这样写
wx.createSelectorQuery()
.select('#posterItem')
.fields({ node: true, size: true })
.exec(async (res) => {
try {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const { pixelRatio: dpr, windowWidth } = wx.getSystemInfoSync();
const width = 350;
const height = 440;
//这里设置width与height也可以
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
ctx.fillStyle = '#FFFFFF';
//fillRect里的width、height一定与canvas标签元素一致才行
ctx.fillRect(0, 0, width, height);
// 生成图片
wx.canvasToTempFilePath({
canvas,
success: (res) => {
wx.saveFile({
tempFilePath: res.tempFilePath,
success: (res) => {
},
});
},
});
} catch (error) {
console.log(error);
}
});
//css中设置canvas标签位置为一个一定看不到位置,不能直接设置隐藏,否则无法显示
.widget {
position: fixed;
top: 99999px;
left: 0;
}
二、canvas内无法画base64的图
在微信小程序开发工具中canvas可以传入base64画图,但是手机端不会报错,但整个图片无法生成。
这是因为canvas的drawImage()传入的第一个参数是 imageResource 图片资源路径,这个参数通常由从相册选择图片 wx.chooseImage 或 wx.getImageInfo 获取图片信息来获得,如果是base64格式的数据,无法被 getImageInfo 直接调用。
解决方法:
1、首先使用 wx.base64ToArrayBuffer 将 base64 数据转换为 ArrayBuffer 数据;( getwxacodeunlimit 返回的分享小程序码就是ArrayBuffer数据)
2、使用 FileSystemManager.writeFile 将 ArrayBuffer 写为本地用户路径的二进制图片文件
3、转好的图片再传到drawImage方法中
export async function base64Save(base64File) {
const fsm = wx.getFileSystemManager();
let extName = base64File.match(/data\:\S+\/(\S+);/);
if (extName) {
extName = extName[1];
}
let fileName = Date.now() + '.' + extName;
return new Promise((resolve, reject) => {
let filePath = wx.env.USER_DATA_PATH + '/' + fileName;
fsm.writeFile({
filePath,
data: base64File.replace(/^data:\S+\/\S+;base64,/, ''),
encoding: 'base64',
success: (res) => {
console.log('filePath', filePath);
resolve(filePath);
},
});
});
}
三、canvas内无法画网络图片
canvas在画网络图片时会出现整个canvas空白的情况
解决方法:
需要通过getImageInfo先把图片缓存到本地能够使用
wx.getImageInfo({
src:'https://xxxxx',
success:(img)=>{
wx.createSelectorQuery()
.select('#posterItem')
.fields({ node: true, size: true })
.exec(async (res) => {
try {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const { pixelRatio: dpr, windowWidth } = wx.getSystemInfoSync();
const width = 350;
const height = 440;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, width, height);
const bg = drawImg(canvas,ctx.false);
//这个img就能直接用了
bg(img,0,0,350,150);
});
}
})
四、canvas画圆角图
canvas提供drawImage方法生成图片,但是都只能是方方正正的,要生成有圆角弧度的图片需要自己写方法截取原图片再画图
解决方法:
利用 Canvas 先画出一个圆角矩形,然后将图片定位到圆角矩形位置进行剪切,将超出圆形的部分去掉,就会形成一个圆角矩形
/*
* 参数说明
* ctx Canvas实例
* img 图片地址
* x x轴坐标
* y y轴坐标
* w 宽度
* h 高度
* r 弧度大小
*/
export const circleImg = (ctx, img, x, y, w, h, r) => {
ctx.save();
// 画一个图形
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
ctx.strokeStyle = '#FFFFFF'; // 设置绘制圆形边框的颜色
ctx.stroke();
ctx.clip();
ctx.drawImage(img, x, y, w, h);
ctx.restore();
};
五、背景图片不能引用本地图片
在wxss文件中,不能引用本地图片作为背景图片,否则,即便开发者工具上预览正常,真机上是读不出图片的
解决办法:
其实正常情况下我们都会用image标签绑定src,但是实在要设置背景图那就将本地图片转为base64格式,或者是使用网络图片。
//转base64
wx.chooseImage({
count:1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success:res=>{
var base64 = 'data:image/jpeg;base64,'+wx.getFileSystemManager().readFileSync(res.tempFilePaths[0], "base64");
// console.log(base64);
}
})
六、字体粗细问题
ios和其他安卓手机显示字体粗细不一样,ios一般设置500就已经有加粗效果,而安卓手机要设置700才有效果,但是如果设置700在ios中就会显示得特别粗,影响美观
解决方法:
1、设置font-weight为bold,这样所有手机都会有加粗效果,不过加粗效果也会有粗细不一的问题 2、通过getSystemInfo方法拿到手机的型号以及系统,根据不同系统和型号去设置不同的font-weight,比较麻烦
七、scroll-view滑动卡顿问题
有些安卓手机中,在scroll-view上设置height:100%会导致页面上滑时不流畅的卡顿问题
解决办法:
设置高度自动撑开
八、样式穿透问题
微信小程序原生组件camera、canvas、input(仅在focus时表现为原生组件)、live-player、live、pusher、map、textarea、video的层级是最高的,页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。
解决办法: 最靠谱的解决方法是弹出时,就把input框设置为view框,不能单纯的隐藏掉input框,因为当页面滑倒弹出框没有遮住的位置时,就什么都看不到了,这样也算是bug。
九、输入框内容会滑动飘动
ios有时候在输入框输入了内容后,再去滑动,输入框内容会滑动飘动,而且还有时候会有时候不会,不一定能复现。
解决办法:
可以使用输入框设置 always-embed。always-embed 解决 ios系统在input 聚焦时同层显示的问题
十、onPullDownRefresh下拉刷新兼容问题
在ios中,使用onPullDownRefresh下拉刷新时,如果将wx.stopPullDownRefresh()放在接口请求的回调中执行并且在请求过程中使用了小程序自带的showToast或showLoading等交互反馈时,下拉之后反弹过大页面不会回弹至顶部
解决办法:
下拉请求完数据之后,关闭下拉刷新,就不会弹不回去了
onPullDownRefresh:function(){
this.getInfo(); //发送请求
wx.stopPullDownRefresh() //关闭下拉刷新
}