懒散的一个前端,平时没事还会偷偷划水打游戏,最近看了一个文章 加油,阮一峰,感觉很是触动我,而且看到这篇文章的原因还是因为-公司的需求不会,来掘金寻求解决方法,实在惭愧,不多说了,也不立过大的flag,平时没事的时候少浏览点网页,来看点鸡汤文章,自己写一点最近的问题,方便以后查看,不要每次遇到问题,都去重新访问百度!!
每周写一点东西,遇到自己解决的难题,感觉有营养的东西都来记录一下
第一个问题:解决快应用的canvas裁剪和水印功能: 放弃了canvas的裁剪功能,使用了快应用官方的api,在处理保存的图片时,遇到了华为和其他手机不适配的问题,做前端没有搞过各个浏览器的适配问题,现在天天给这搞各个手机厂商的适配问题。难,下班,晚上回家继续干!
周末堕落两天,来上班感觉慌慌的,忙碌一上午,蓦然发现很多问题, 之前辛辛苦苦搞得宽高比,使图片居中展示在canvas里面,在面对华为的时候,什么都用不了,
canvas
一直以为toTempFilePath 这个api只有针对canvas才能用,开发了小米的时候,还可以指定顺顺利利的指定保存的区域,方法如下:
然后兼容到华为的时候,一脸懵逼,不支持指定 保存 的区域:
两脸懵逼:当时真的是把华为** 了一遍,这个可怎么实现呀:然后突然看到了上面文档说的,可以讲组件直接导出,那div也算吧没,试一试,哇哇哇,竟然真的可以,心情上升到~~。然后再试试的小米的,竟然也可。之前搞了一天的canvas的绘制字体,完全破费:但还是记录一下吧:
我的开始需求时绘制在一个7501000的canvas上面:
图片的宽和高
let imghei = this.imageGroup[this.groupindeximage].sourceimg[id].height
let imgwidth = this.imageGroup[this.groupindeximage].sourceimg[id].width
// 放置图像的x y轴坐标,必定有一个是0
let ctxdx = 0
let ctxdy = 0
let scanwidth = 0
let scanheight = 0
// 开始判断
if (imgwidth / ctxsettingwidth * this.devicePixelRatio > imghei / ctxsettingheight * this.devicePixelRatio) {
// 以宽为准
scanwidth = ctxsettingwidth * this.devicePixelRatio
scanheight = parseInt(scanwidth * imghei / imgwidth)
ctxdy = parseInt((ctxsettingheight * this.devicePixelRatio - scanheight) / 2)
} else {
// 以高为准
scanheight = ctxsettingheight * this.devicePixelRatio
scanwidth = parseInt(scanheight * imgwidth / imghei)
ctxdx = parseInt((ctxsettingwidth * this.devicePixelRatio - scanwidth) / 2)
}
canvas.width = 750 * this.devicePixelRatio
canvas.height = 1000 * this.devicePixelRatio
canvas.style.width = 750 * this.devicePixelRatio
canvas.style.height = 1000 * this.devicePixelRatio
console.log(this.devicePixelRatio + '屏幕分辨率')
ctx.scale(1 / this.devicePixelRatio, 1 / this.devicePixelRatio)
let img = new Image()
// img.src = 'https://static.zixunkankan.xyz/image628/xingzuopei/star.png' //加载网络图片
img.src = imguri //加载网络图片
img.onload = () => {
ctx.drawImage(img, ctxdx, ctxdy, scanwidth, scanheight)
}
这个是将图片居中绘制到canvas上: 然后是添加水印,要求是距离底部6%,字体大小60,居中展示:
let row = []
let temp = ''
for (let a = 0; a < this.watermarkText.length; a++) {
//计算字体的长度是否小于图片的宽度/
if (this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].ctx.measureText(temp).width < this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].canvas_width - 100) {
temp += this.watermarkText[a];
if (a === this.watermarkText.length - 1) {
row.push(temp);
}
}
else {
console.log(temp)
a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比
row.push(temp);
temp = "";
}
}
console.log(row)
let heizuobiao = this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].canvas_height * 0.93 - row.length * lineheight + this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].canvas_dy
for (let b = 0; b < row.length; b++) {
this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].ctx.fillText(row[b], this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].canvas_width / 2 + this.imageGroup[this.groupindeximage].sourceimg[this.currenimageindex].canvas_dx, heizuobiao + b * lineheight);
}
记录一下,感觉是需求初始满足了。
好了,去试试h5的 toTempFilePath 是不是也可以对任何组件保存图片...
哈哈,想多了,h5并没有 toTempFilePath 这个方法,在小程序里面有,跟小米的用法一样。
h5里面要保存画布的话:使用另一个api : toDataURL 测试很简单:
/****
验证 toTempFilePath 方法是否只支持 canvas
****/
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);
let uri = canvas.toDataURL()
console.log(uri)
document.getElementById('imgset').setAttribute('src',uri)
就是保存为了一个base64的地址,也挺好用,先到这吧。