Wechat applet -canvas2D- Poster – Android adaptation
preface
The official documentation is a long story, but this article records the various problems and solutions encountered in the practical experience of canvas2D
canvas2D
Reason for use: official announcement: 2.9.0 supports a new Canvas 2D interface (type attribute needs to be specified), and supports the same layer rendering. The original interface is no longer maintained. Use:
<canvas type="2d" id="myCanvas"></canvas>
Copy the code
Note:
id
Rather thancanvas-id
- Pay attention to the statement
type="2d"
- Wx. CanvasToTempFilePath failed to debug the real machine, there is no specific solution yet, official maintenance staff: go preview debugging, the real machine does not work, specific reason: official is so bad
- When converting cavnas to images with ‘canvasToTempFilePath’, the canvas must appear in the page structure, otherwise it will fail no image, also must give it width and height, do not use %. Here it is :(use vw,vh,px)
<! -- BAD -->
<canvas type="2d" id="myCanvas" style="width:100%; height:100%;"></canvas>
Copy the code
<! -- GOOD -->
<canvas type="2d" id="myCanvas" style="with:100vw; height:100vh;"></canvas>
Copy the code
- Ctx.drawimage () uses the following:
const img = canvas.createImage()
img.src = that.data.erCodeImage.path
img.onload = (a)= > {
ctx.drawImage(img, 540 * unit, 860 * unit, 165 * unit, 165 * unit)
}
Copy the code
- Notice The network image must be HTTPS and downloaded to a local PC.
/ * *
* @description: encapsulates the download image function
* @params:
* @return {type}
* /
downLoadImage(url) {
return new Promise((resolve, reject) = > {
// console.log(" Images to download ", url)
wx.getImageInfo({
src: url,
success(res) {
// console.log(" Download ok ", res.path)
// resolve(res.path)
resolve(res)
},
fail(err) {
reject(err)
}
})
})
},
/ * *
* @description: encapsulated function to download cloud storage files
* @params:
* @return {type}
* /
downLoadCloudFile(id) {
return new Promise((resolve, reject) = > {
wx.cloud.downloadFile({
fileID: id,
success: res= > {
// Returns the temporary file path
console.log(1231312312, res)
resolve(res.tempFilePath)
},
fail: err= > {
console.log('err', err)
}
})
})
},
Copy the code
- Some setFillStyle use method has been modified, the specific use of Baidu
Poster generation project begins
Build the canvas
<canvas type="2d" id="myCanvas" style="width: 750px; height: 1125px; border:1px solid blue;; margin:auto;"></canvas>
Copy the code
Canvas element, same as canvas in HTML
Initialize the canvas
- Create a DOM element node finder
/ / in the page
const query = wx.createSelectorQuery()
Copy the code
/ / components
const query = wx.createSelectorQuery().in(this)
Copy the code
- Select our Canvas node
query.select('#myCanvas')
Copy the code
- Initialize the base parameters of the Canvas canvas
Attention should be paid to: DPR device pixel ratio, in order to adapt to various Android devices, it is recommended to use DPR =1, otherwise, Will appear as follows a similar error canvasToTempFilePath: fail: convert native buffer parameter fail. The native buffer exceed the size limit,
initCanvas() {
const query = wx.createSelectorQuery().in(this) // Create a DOM element node finder
query.select('#myCanvas') // Select our canvas node
.fields({ // Node information to be obtained
node: true.// Whether to return the Node instance corresponding to the Node
size: true // Whether to return the node size (width height)
}).exec((res) = > { Exec ((res) => {alpiny})
const dom = res[0] // Since there is only one canvas on the page, the DOM data we need is the first element of the RES array
const canvas = dom.node // Canvas is the canvas node we are manipulating
const ctx = canvas.getContext('2d') // In 2D mode, get the context object of a canvas node
// const DPR = wx.getSystemInfoSync().pixelRatio
const dpr = 1
// The size of DPR affects the resolution of the image display, which can be understood as affecting the size of the pixel, the larger the value, the higher the hd, but I guess it will affect the rendering efficiency or increase the burden of small program operation
// const unit = 2
canvas.width = 750 * dpr
canvas.height = 750 * 1.5 * dpr
ctx.scale(dpr,dpr)
this.setData({
canvasDom: dom, // Place the Canvas DOM object globally
canvas: canvas, // Put the canvas node globally
ctx: ctx, // Put the canvas 2D context globally
dpr: dpr // Screen pixel ratio
}, function () {
console.log('Start drawing')
this.drawWork() // Start drawing
})
})
},
Copy the code
As for canvas.width and canvas.height Settings, it is mainly for the convenience of controlling the size of the drawing image. The width and height of canvas are not the same as width and height in style. CSS element width and height == CTX: refers to the 2D context, which can be understood as a brush for drawing
- Special attention should be paid to the text drawing. The font must be existing in the system, otherwise the text cannot be drawn, and some Android phones may blink back. The recommended operation code is as follows, and the recommended font is Arial.
- Note the order in which the values of the attributes in the font are set; the wrong order can have different results
- Some may be caused by not setting the font
ctx.font = '56px Arial';
Copy the code
// BAD
// Set bold text
ctx.font = '56px bold Arial';
Copy the code
// GOOD
// Set bold text
ctx.font = 'bold 56px Arial';
Copy the code
- In the use of
canvasToTempFilePath
To convert the image into a temporary file and save it on the phone, set the output width (destWidth) and output height (destWidth). Otherwise, when viewing the image on the phone, you will find that the image is stretched or clipped in a certain direction. Please refer to the canvas document for detailscanvasToTempFilePath
SetData () set up the canvas, CTX
The following Settings are recommended for using setData() when assigning canvas, CTX objects to data on android (directly assigning to this object can also be used globally in JS)
// BAD
query.select('#myCanvas') // Select our canvas node
.fields({ // Node information to be obtained
node: true.// Whether to return the Node instance corresponding to the Node
size: true // Whether to return the node size (width height)
}).exec((res) = > {
const dom = res[0] Since there is only one canvas on the page, we need the dom count
const canvas = dom.node // Canvas is the canvas node we are manipulating
const ctx = canvas.getContext('2d') // In 2D mode, get a canvas
// This operation will report an error
that.setData({
canvasDom:dom
canvas:canvas
ctx: ctx
})
// this.drawWork()
})
Copy the code
// GOOD
query.select('#myCanvas') // Select our canvas node
.fields({ // Node information to be obtained
node: true.// Whether to return the Node instance corresponding to the Node
size: true // Whether to return the node size (width height)
}).exec((res) = > {
const dom = res[0] Since there is only one canvas on the page, we need the dom count
const canvas = dom.node // Canvas is the canvas node we are manipulating
const ctx = canvas.getContext('2d') // In 2D mode, get a canvas
// If you use setData on android, you will get an error
that.canvasDom = dom
that.canvas = canvas
that.ctx = ctx
// this.drawWork()
})
Copy the code
DrawImage Draws many images
When canvas draws too many pictures, some pictures saved in the mobile phone may not be displayed. The specific reason is that the pictures are generated before they are all drawn. Asynchronous processing is required to generate and save the pictures after they are all drawn