123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- const poster = {
- /**
- * 绘制分享海报
- * @param canvasId
- * @param winWidth 宽度
- * @param winHeight 高度
- * @param imgs 主图以及二维码图
- * 格式 {mainPic: mainPic,qrcode: qrcode}
- * @param text 描述文字
- * @param name 程序名称
- **/
- drawPoster(canvasId, winWidth, winHeight, imgs, text, name, callback) {
- //获取绘图上下文 context
- let context = uni.createCanvasContext(canvasId)
- // 海报背景
- const grd = context.createLinearGradient(0, winWidth, winHeight, 0)
- grd.addColorStop(0, '#FFF')
- grd.addColorStop(1, '#FFF')
- // Fill with gradient
- context.setFillStyle(grd);
- context.fillRect(0, 0, winWidth, winHeight);
- // 主图
- let width = winWidth,
- height = winHeight - 300;
- context.drawImage(imgs.mainPic, 0, 0, width, height)
- let a = uni.upx2px(40) //定义行高
- context.setFontSize(uni.upx2px(50))
- context.setFillStyle("#000")
- //名称很长调用方法将文字折行,传参 文字内容text,画布context
- let w = poster.getTextWidth(text, context) || uni.upx2px(550) * 2
- let x = winWidth / 15;
- let row = poster.wrapText(text, Math.floor(w), context)
- //console.log(w);
- for (let i = 0; i < row.length; i++) {
- context.fillText(row[i], (winWidth/ 4) + 80, (winHeight - uni.upx2px(360)) + a * i)
- }
- // 识别小程序二维码
- context.setFontSize(uni.upx2px(36))
- let w1 = poster.getTextWidth(name, context) || 140
- context.drawImage(imgs.qrcode, x, (winHeight - uni.upx2px(500)), winWidth/4, winWidth/4)
- context.setFillStyle("#152338")
- context.fillText('邀请您加入'+name, (winWidth/4) + 80, (winHeight - uni.upx2px(300)))
- context.setFillStyle("#333")
- context.setFontSize(uni.upx2px(24))
- context.fillText('长按识别·立即体验', (winWidth/4) + 80, (winHeight - uni.upx2px(250)))
- context.draw(false, () => {
- poster.createPoster(canvasId, winWidth, winHeight, (res) => {
- callback && callback(res)
- })
- })
- },
- /**
- *绘制商品海报
- * @param canvasId
- * @param winWidth 宽度
- * @param winHeight 高度
- * @param imgs 主图以及二维码图
- * 格式 {mainPic: mainPic,qrcode: qrcode}
- * @param text 商品名称
- * @param price 价格 格式 12.00,10.50
- * @param originalPrice 原价 格式 12.00,10.50
- * @param name 程序名称
- **/
- drawGoodsPoster(canvasId, winWidth, winHeight, imgs, text, price, originalPrice, name, callback) {
- let scaleRatio = 2
- //获取绘图上下文 context
- let context = uni.createCanvasContext(canvasId)
- // 海报背景
- const grd = context.createLinearGradient(0, winWidth, winHeight, 0)
- grd.addColorStop(0, '#FFFFFF')
- grd.addColorStop(1, '#FFFFFF')
- // Fill with gradient
- context.setFillStyle(grd);
- context.fillRect(0, 0, winWidth, winHeight);
- // 主图
- let width = uni.upx2px(500 * scaleRatio),
- height = uni.upx2px(500 * scaleRatio);
- context.drawImage(imgs.mainPic, (winWidth - width) / 2, uni.upx2px(30 * scaleRatio), width, height)
- let a = uni.upx2px(40 * scaleRatio) //定义行高
- context.setFontSize(uni.upx2px(30 * scaleRatio))
- context.setFillStyle("#343434")
- let w = uni.upx2px(468 * scaleRatio)
- //名称很长调用方法将文字折行,传参 文字内容text,画布context
- let row = poster.wrapText(text, Math.floor(w), context, 2)
- for (let i = 0; i < row.length; i++) {
- context.fillText(row[i], uni.upx2px(30 * scaleRatio), uni.upx2px(580 * scaleRatio) + a * i)
- }
- context.setFillStyle("#EB0909")
- context.setFontSize(uni.upx2px(26 * scaleRatio))
- context.fillText('¥', uni.upx2px(30 * scaleRatio), uni.upx2px(680 * scaleRatio))
- context.setFontSize(uni.upx2px(36 * scaleRatio))
- let priceArr = Number(price).toFixed(2).toString().split('.')
- context.fillText(priceArr[0], uni.upx2px(56 * scaleRatio), uni.upx2px(680 * scaleRatio))
- let w1 = poster.getTextWidth(priceArr[0], context) || 35
- context.setFontSize(uni.upx2px(26 * scaleRatio))
- context.setFillStyle("#EB0909")
- context.fillText(`.${priceArr[1]}`, uni.upx2px(60 * scaleRatio) + w1, uni.upx2px(680 * scaleRatio))
- context.setFillStyle("#999999")
- context.setFontSize(uni.upx2px(24 * scaleRatio))
-
- if(originalPrice>0){
- let w2 = uni.upx2px(76 * scaleRatio) + w1 + (poster.getTextWidth(`.${priceArr[1]}`, context) || 32)
- context.fillText(`¥${originalPrice}`, w2, uni.upx2px(680 * scaleRatio))
- context.moveTo(w2, uni.upx2px(672 * scaleRatio))
- context.lineTo((w2 + 50 * scaleRatio), uni.upx2px(672 * scaleRatio))
- context.setStrokeStyle('#999999')
- context.stroke(); //对当前路径进行描边
- }
-
- // 识别小程序二维码
- let x = winWidth - uni.upx2px(46 + 130) * scaleRatio;
- context.drawImage(imgs.qrcode, x, uni.upx2px(735 * scaleRatio), uni.upx2px(130 * scaleRatio), uni.upx2px(130 *
- scaleRatio))
- context.setFillStyle("#333")
- context.setFontSize(uni.upx2px(32 * scaleRatio))
- context.fillText(name, uni.upx2px(40 * scaleRatio), uni.upx2px(780 * scaleRatio))
- context.setFontSize(uni.upx2px(24 * scaleRatio))
- context.fillText('长按识别·立即体验', uni.upx2px(40 * scaleRatio), uni.upx2px(835 * scaleRatio))
- context.draw(false, () => {
- poster.createPoster(canvasId, winWidth, winHeight, (res) => {
- callback && callback(res)
- })
- })
- },
- //生成海报图片(分享所需图片)
- createPoster(canvasId, winWidth, winHeight, callback) {
- var that = this;
- // let scaleRatio= uni.getSystemInfoSync().scaleRatio
- uni.canvasToTempFilePath({
- x: 0,
- y: 0,
- // width: winWidth * scaleRatio,
- // height: Math.round(winHeight * scaleRatio),
- // destWidth: winWidth * scaleRatio,
- // destHeight: Math.round(winHeight) * scaleRatio,
- canvasId: canvasId,
- fileType: 'png',
- quality: 1,
- success: function(res) {
- callback && callback(res.tempFilePath)
- },
- fail() {
- callback && callback(false)
- }
- })
- },
- // 将海报图片保存到本地
- saveImage(file) {
- uni.saveImageToPhotosAlbum({
- filePath: file,
- success(res) {
- uni.showToast({
- title: '图片保存成功'
- })
- }
- })
- },
- //获取文本宽度(请先查看支持平台,App 端 2.8.12+ 支持)
- getTextWidth(text, context) {
- const metrics = context.measureText(text)
- return metrics.width || 0
- },
- //图片转成本地文件[同步执行]
- async getImage(url) {
- return await new Promise((resolve, reject) => {
- uni.downloadFile({
- url: url,
- success: res => {
- resolve(res.tempFilePath);
- },
- fail: res => {
- reject(false)
- }
- })
- })
- },
- //canvas多文字换行
- wrapText(text, width, context, rows = 2) {
- let txtArr = text.split('')
- let temp = ''
- let row = []
- for (let i = 0, len = txtArr.length; i < len; i++) {
- if (context.measureText(temp).width < width) {
- temp += txtArr[i]
- } else {
- i--
- row.push(temp)
- temp = ''
- }
- }
- row.push(temp)
- if (row.length > rows) {
- let rowCut = row.slice(0, rows);
- let rowPart = rowCut[rows - 1];
- let test = "";
- let empty = [];
- for (let j = 0, length = rowPart.length; j < length; j++) {
- if (context.measureText(test).width < width - 20) {
- test += rowPart[j];
- } else {
- break;
- }
- }
- empty.push(test);
- let group = empty[0] + "...";
- rowCut.splice(rows - 1, 1, group);
- row = rowCut;
- }
- return row
- },
- //删除已缓存文件,防止超出存储空间大小限制[同步执行]
- async removeSavedFile() {
- //使用前请先查看支持平台(其他方案:也可以先渲染出图片,当图片加载完成时执行相关方法)
- let count = 0;
- return await new Promise((resolve, reject) => {
- uni.getSavedFileList({
- success(res) {
- console.log(res)
- count = res.fileList.length;
- if (count > 0) {
- let num = 0;
- let list = res.fileList || []
- list.forEach(item => {
- console.log("执行删除文件。。。")
- uni.removeSavedFile({
- filePath: item.filePath,
- complete(res) {
- num++;
- if (num === count) {
- resolve(true)
- }
- }
- })
- })
- } else {
- resolve(true)
- }
- },
- fail() {
- reject(false)
- console.log("执行删除文件失败")
- }
- })
- })
- },
- //当服务器端返回图片base64时,转成本地文件[同步执行]
- async getImagebyBase64(base64) {
- //使用前先查看支持平台
- // #ifdef MP-WEIXIN
- return await new Promise((resolve, reject) => {
- const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
- let arrayBuffer = wx.base64ToArrayBuffer(bodyData)
- //getuuid:注意这里名称需要动态生成(名称相同部分机型会出现写入失败,显示的是上次生成的图片)
- const filePath = `${wx.env.USER_DATA_PATH}/${poster.getuuid()}.${format}`;
- wx.getFileSystemManager().writeFile({
- filePath,
- data: arrayBuffer,
- encoding: 'binary',
- success() {
- resolve(filePath);
- },
- fail() {
- reject(false)
- }
- })
- })
- // #endif
- },
- getuuid() {
- let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
- return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
- });
- return uuid;
- }
- }
- module.exports = {
- drawPoster: poster.drawPoster,
- drawGoodsPoster: poster.drawGoodsPoster,
- getImage: poster.getImage,
- removeSavedFile: poster.removeSavedFile,
- getImagebyBase64: poster.getImagebyBase64,
- saveImage: poster.saveImage
- };
|