一、canvas 首先创建一个canvas标签,下面的事件是为了你点击海报的时候是会报错 的,你需要定义一个事件,return就可以了!如图:
<canvas class="canvas" canvas-id="myCanvas" @touchmove.stop.prevent="moveHandle" ></canvas><!-- 海报 -->
二、首先我们要是一开始就画图的话需要在mounted的调用就可以了。
三、画图代码如图:
注意的点:
- 网络图片需要转化成本地图片在进行画质,微信头像有的是http的我们需要给他添加一下s,不然上线是画的时候是会报错的。
- 画圆图的时候需要使用到clip,再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内,(所以一把裁剪写在最后面,画的东西的层级是后面画的层级都比前面的高的。要是需要在裁剪之后需要添加图片的话,目前我还没有解决的方法,等以后发现了在更新。。。)
- 就是在一个页面重复画质的话是需要在外层套一个hidden属性来控制页面销毁了从新生成,清空canvas。如图:
<view class="toPoster dpf fdc aic jcc" :hidden="canvasFlag">
//初始化的时候给true,开始画的时候给他false,让他展示出来(就可以一直画了哦)
- 关于手机适配的问题(每个手机的屏幕不一样,我们需要求出他们之间的通用分辨率)如下:
this.message=uni.getSystemInfoSync();//获取手机信息
this.powerw=this.message.windowWidth/375
//一般屏幕的标准是375,我们用机型的宽度除以375就是他们的比例了,画图的时候尺寸直接乘以比例就可以适配了哦。
- 画图的代码如下:(api需要自己去百度都可以知晓怎么使用的哦!)
async createCanvasImage() {
this.canvasFlag=false
uni.showLoading({
title: '海报生成中...'
})
let _this = this;
let powerw=_this.powerw
let ctx = uni.createCanvasContext('myCanvas', this);
console.log(uni.getStorageSync("userInfo"), "useinfo")
let url ='https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eqG1yIlJaiaSz3ibbhw3u1OWpKc0Nq5IfFAxlXcQnK71QOarrawESLHHFEibhyGl24SuaBgC4VIratdQ/132'; //头像图片
let useName ="T.F";
let code='https://scrm.ocheng.me/storage/M00/06/A5/CmUACF_QYYGAI4YYAAFxYrMxZ1834.jpeg';//二维码
// let code = this.qrcode
let backUrl = _this.$fileUrl() + 'M00/0A/C6/CmUAB1_QMFWALgHNAAu1pIZD2i8535.png'; //背景图片
let maozi = _this.$fileUrl() + 'M00/06/A5/CmUACF_QQoGAFkx7AAAZFKfUWpE724.png'; //帽子
ctx.draw() //清空原来的画图内容
ctx.save();
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, 280, 470);
ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 可以继续绘制
//显示背景图片
await uni.getImageInfo({
src: backUrl,
}).then(item => {
if (item[1].errMsg == 'getImageInfo:ok') {
ctx.save();
ctx.drawImage(item[1].path, 0, 0,300*powerw,450*powerw); //绘制图
ctx.restore();
// ctx.draw(true)
} else {
this.canvasFlag=true
uni.showToast({
title: '海报生成失败',
duration: 2000,
icon: 'none'
});
}
console.log(item)
})
//二维码
await uni.getImageInfo({
src: code,
}).then(result => {
console.log(result,"res1")
if (result[1].errMsg == 'getImageInfo:ok') {
ctx.save();
ctx.drawImage(result[1].path, 109*powerw, 260*powerw,77*powerw,74*powerw); //绘制图
ctx.restore();
// ctx.draw(true)
} else {
this.canvasFlag=true
uni.showToast({
title: '海报生成失败',
duration: 2000,
icon: 'none'
});
}
})
// 绘画nickname
ctx.shadowColor = 'rgba(0, 0, 0, 0.2)';
ctx.setFillStyle('#FFFFFF')//文字颜色:默认黑色
ctx.setFontSize(12)//设置字体大小,默认10
ctx.textAlign = 'center' // 设置位置
ctx.font = 'normal 16px sans-serif'; // 字体样式
ctx.fillText('你是傻逼吧',150*powerw, 154*powerw);
//显示头像
await uni.getImageInfo({
src: url,
}).then(res => {
if (res[1].errMsg == 'getImageInfo:ok') {
ctx.beginPath(); //开始绘制
let grd = ctx.createLinearGradient(160*powerw, 130*powerw, 25*powerw, 0,)
grd.addColorStop(0, "#f7cb6b");
grd.addColorStop(0, "#fba980");
ctx.lineWidth = 4;
ctx.strokeStyle = grd;
ctx.beginPath();
//先画个圆
ctx.arc(150*powerw, 110*powerw, 25*powerw, 0, Math.PI * 2);
ctx.setFillStyle('#ffffff')
ctx.fill() //保证图片无bug填充
ctx.clip(); //画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
ctx.drawImage(res[1].path, 130*powerw, 86*powerw, 50*powerw, 50*powerw); //绘制图
ctx.stroke();
ctx.restore();
// ctx.draw(true)
} else {
this.canvasFlag=true
uni.showToast({
title: '海报生成失败',
duration: 2000,
icon: 'none'
});
}
})
ctx.draw()
uni.hideLoading();
},
- 保存图片在手机上面,如下:
save(){
console.log('点击了保存')
uni.showLoading({
title: '保存中...'
})
let _this = this;
// 1-把画布转化成临时文件
uni.canvasToTempFilePath({
x: 0,
y: 0,
width:300, // 画布的宽
height:500, // 画布的高
// destWidth: this.phoneW * 3,
// destHeight: 510 * 7,
canvasId: 'myCanvas',
success(res) {
// 2-保存图片至相册
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res2) {
uni.hideLoading();
uni.showToast({
title: '图片保存成功',
duration: 2000
})
_this.canvasFlag=false
// _this.canvasCancelEvn();
},
fail(err) {
uni.hideLoading();
uni.showToast({
title: '保存失败,稍后再试',
duration: 2000,
icon: 'none'
})
_this.getAuth=true
}
},this)
},
fail(err) {
console.log(err,"err")
uni.showToast({
title: '保存失败,稍后再试',
duration: 2000,
icon: 'none'
})
uni.hideLoading();
_this.canvasFlag=false
}
},this)
},