Mobile sharing poster generation

Recently, the requirement of the project is to generate commodity sharing posters, and save them in the mobile phone to be compatible with H5 and small programs. After communication with the backend students, the posters will generate minimum performance in the front end and have better interactive experience, so we should first consider the good effect

The source address

The front-end framework uses UNI-App, which is easy to package into H5 and small program. The solution is to take the data returned from the back-end and use canvas to put all the data together and generate a picture. The main parameters include background picture, commodity picture, TWO-DIMENSIONAL code, price, original price and title

Once you have the product image and qr code, you need to download them using the UNI-app API to write a download method and define the canvas component in the Template

<template> <canvas class="canvas" canvas-id="myCanvas" v-if="canvasStatus"></canvas> </template> onReady(){ this.downloadFileImg('','pic'); this.downloadFileImg('','code'); }, methods:{ downloadFileImg(url,name){ let self = this uni.downloadFile({ url: url, success: function(res) { self[name] = res.tempFilePath; }, fail: function(erros) { console.log(error) } }); }}Copy the code

This will save the image to a local temporary file

Uni. DownloadFile It is important to note that you need to configure the domain name whitelist before using the net-related apis when running each applets. On H5 it is cross-domain, and users need to deal with cross-domain issues.

Write down the canvas to generate the image method

@param string store_name = @param string price = @param string price @param string ot_price @param function successFn callback */ PosterCanvas: function(imgArr, store_name, price, ot_price, successFn) { let that = this; Uni.showloading ({title: 'poster is being generated ', mask: true}); const ctx = uni.createCanvasContext('myCanvas'); ctx.clearRect(0, 0, 0, 0); /** / ctx.fillstyle = '# FFF '; ctx.fillRect(0, 0, 750, 1150); uni.getImageInfo({ src: imgArr[0], success: function(res) { const WIDTH = res.width; const HEIGHT = res.height; ctx.drawImage(imgArr[1], 0, 0, WIDTH, WIDTH); ctx.save(); let r = 110; let d = r * 2; let cx = 480; let cy = 790; ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI); // ctx.clip(); ctx.drawImage(imgArr[2], cx, cy, d, d); ctx.restore(); const CONTENT_ROW_LENGTH = 20; let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name, CONTENT_ROW_LENGTH); if (contentRows > 2) { contentRows = 2; let textArray = contentArray.slice(0, 2); TextArray [textarray.length - 1] += '... '; contentArray = textArray; } ctx.setTextAlign('left'); ctx.setFontSize(36); ctx.setFillStyle('#000'); // let contentHh = 36 * 1.5; let contentHh = 36; for (let m = 0; m < contentArray.length; m++) { if (m) { ctx.fillText(contentArray[m], 50, 1000 + contentHh * m + 18, 1100); } else { ctx.fillText(contentArray[m], 50, 1000 + contentHh * m, 1100); } } ctx.setTextAlign('left') ctx.setFontSize(72); ctx.setFillStyle('#DA4F2A'); Ctx.filltext ('¥' + price, 40, 820 + contentHh); ctx.setTextAlign('left') ctx.setFontSize(36); ctx.setFillStyle('#999'); Ctx.filltext ('¥' + ot_price, 50, 876 + contentHh); var underline = function(ctx, text, x, y, size, color, thickness, offset) { var width = ctx.measureText(text).width; switch (ctx.textAlign) { case "center": x -= (width / 2); break; case "right": x -= width; break; } y += size + offset; ctx.beginPath(); ctx.strokeStyle = color; ctx.lineWidth = thickness; ctx.moveTo(x, y); ctx.lineTo(x + width, y); ctx.stroke(); } underline(CTX, '¥' + ot_price, 55, 865, 36, '#999', 2, 0) ctx.settextalign ('left') ctx.setfontsize (28); ctx.setFillStyle('#999'); Ctx.filltext (' long press or scan to view ', 490, 1030 + contentHh); ctx.draw(true, function() { uni.canvasToTempFilePath({ canvasId: 'myCanvas', fileType: 'png', destWidth: WIDTH, destHeight: HEIGHT, success: function(res) { uni.hideLoading(); successFn && successFn(res.tempFilePath); }})}); }, fail: function(err) { uni.hideLoading(); Thate.tips ({title: 'can't get image info'}); }})},Copy the code

First create a canvas canvas background image information to get the width and height to draw images and save the qr code and put the coordinate well and save in dealing with wrap text and set the color and size in setting prices and the corresponding mode of its color and size of the original coordinate Due to the price there are horizontal lines, I searched the Internet again for the horizontal line method and just looked at the method and finally generated the image information and used the uni.canvastotempFilepath method to export the contents of the specified area of the current canvas to generate the image of the specified size and return the file path. So we’ve got a.png temporary file and now the last thing we need to do is render the file into the component, and from the callback function we can go back to this method. For example, I wrote it into the public method and bound it to the Vue prototype so that we can use it later and write method calls now

HandelCanvas (){let imgArr = [' background path ',this.pic,this.code] This.$util.PosterCanvas(imgArr,' title ',' price ',' original price ',function(tempFilePath){console.log(tempFilePath)})}Copy the code

So you’ve got a temporary file that you’ve generated and now you can display it on a page and you can save the image. H5, you can save the image by holding down a long press

savePosterPath: function() { let that = this; uni.getSetting({ success(res) { if (! res.authSetting['scope.writePhotosAlbum']) { uni.authorize({ scope: 'scope. WritePhotosAlbum' success () {uni. SaveImageToPhotosAlbum ({filePath: 'canvas generated temporary pictures, success: function(res) { .... }, fail: function(res) {.... Failed}}); }}); } else {uni. SaveImageToPhotosAlbum ({filePath: 'canvas generated temporary pictures, success: function (res) {... }, fail: function(res) {.... Failed}}); }}}); },Copy the code

So the front – end poster generation is done, you learn to waste it?