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:

  • idRather thancanvas-id
  • Pay attention to the statementtype="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,

          successres= > {

            // Returns the temporary file path

            console.log(1231312312, res)

            resolve(res.tempFilePath)

          },

          failerr= > {

            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.
  1. Note the order in which the values of the attributes in the font are set; the wrong order can have different results
  2. 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 ofcanvasToTempFilePathTo 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[0Since 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[0Since 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