A preface

Today I will share a small program to generate watermark tips – Canvas drawing background, next I will describe the details of drawing. Hope to develop the micro channel small program students can collect the article, so that if the future encounter similar needs, can be turned out as a reference.

The plug-in in this paper is also applicable to Taro, UniAPP, native and other small program projects built. The project demo is built with Taro-Vue.

So let’s see what the demo looks like.

Realization of two principles

The principle behind the Canvas background is essentially simple, like putting an elephant in the refrigerator in three steps ๐Ÿ˜‚๐Ÿ˜‚.

  • The first step is to open the refrigerator door. Since this function is realized at the front end and drawn by canvas, we need the basic configuration of the poster, such as canvas poster width and height, text content, text color, and rotation Angle of the poster text, etc.

  • The second step is to put the elephant ๐Ÿ˜ in, the Canvas is configured, and draw the watermark base image.

So the question is, is the base map we draw the whole watermark base map?

The answer is no. We only need to draw a template picture, as shown below:

But in order to make the watermark fill the entire phone screen, we need to use the watermark image as the background image, and then set background-repeat:repeat; That will do.

  • The third step is to close the refrigerator door and fill the whole screen with images generated by Canvas.

Three detail implementation

The demo sample

Next we start implementing the details. First we put a

on the page.

<view
    class="markBox"
    :style="{ backgroundImage: `url(${url})` }"
>  
    <canvas
      v-show="isShow"
      :id="settings.id"
      type="2d"
      :class="settings.id"
      :style="{ width:settings.width + 'px' , height : settings.height + 'px' }"
    />
</view>
Copy the code
  • It is important to note that the canvas type = ‘2d’ should not be used in the canvasId mode, including fetching canvas instance, calling canvasToTempFilePathapi, etc. Otherwise, it may fail. Here, we use the ID method to obtain the Canvas instance.

  • When we’re done, hide the canvas and set the View container to the background image, which is the image that the canvas is drawing.

  • The canvas width and height are added according to the canvas configuration, so we dynamically set the width and height using the style property.

Configuration items

export default {
   /* Generate watermark in front */
   name:"MakeWaterMark".data(){
       return {
           isShow:true.url:' '.settings: {
                'id': 'waterMark'./* canvas id */
                'content': 'I am not an alien'./* Watermark content */
                'width': 200./* Image/Canvas width */
                'height': 200./* Image/Canvas height */ 
                'rotate': -45./* Watermark copy rotation Angle */ 
                'left':60./* Watermark copy relative to the image horizontal offset */
                'top':80./* Watermark copy relative to the image vertical offset */
                'fontSize': '15px'./* Watermark text size */
                'fontFamily': 'Microsoft JhengHei'./* Watermark text style */
                'bg': '#fff'./* Image background color */ 
                'color': '#ccc'./* Watermark text color */
                'fontWeight': 'normal'./* Watermark text width */}}}},Copy the code

Style to deal with

.markBox{
    position: fixed;
    left:0;
    right:0;
    bottom: 0;
    top:0;
    background-repeat:repeat ;
}
Copy the code
  • Style the outer container to make the watermark image tile the entire page.

Plug-in core code

The core function of the plug-in is to generate watermark images, in addition to meeting two requirements:

  • The plug-in itself is low coupled to the page/component. The plug-in itself can be used in any component.
  • Plug-ins are not limited by the platform they are built on, which means they can be used in native wechat applets as well as inTaro.uniappEtc.

Let’s look at the details:

function createPromise(callback){
    return new Promise((resolve,reject) = >{
        callback(resolve,reject)
    })
}

/** * Make watermark image */
class MarkwaterMark{
    constructor(options){
        /* Initial configuration */
       this.platform  = null 
       this.pixelRatio = null
       this.context = null
       this.options = options 
       this.ready = createPromise(this._init.bind(this))   
       /* Generate component methods */
       this.make = (cb) = > { 
          if(this.context){
             this._markPicture(cb)
          }else{
              this.ready.then(() = >{
                 this.context && this._markPicture(cb)
              })
          }    
       }
    }
    /* Initialization method */
    _init(next,fail){
       const { platform , pixelRatio } = wx.getSystemInfoSync()
       this.platform = platform
       this.pixelRatio = pixelRatio
       const query = wx.createSelectorQuery()
       query.select(The '#' + this.options.id ).fields({
        node: true.size: true
      }).exec((res) = >{
        let {
            node,
        } = res[0) | | {}if(! node)return fail && fail()
        this.context = node.getContext('2d')    
        this.node = node
        next()
      })
    }
    /* Make watermark image */
    _markPicture(cb){
       const { width , height , bg ,color ,fontSize, fontFamily,fontWeight ,content , left, top ,rotate } = this.options
       this.node.width = (width || 200) * this.pixelRatio
       this.node.height =( height || 200) * this.pixelRatio
       this.context.scale(this.pixelRatio,this.pixelRatio)
       this.context.fillStyle = bg || '#fff'
       this.context.fillRect(0.0, width, height)
       this.context.fillStyle = color || '# 000'
       this.context.save()
       this.context.translate(left,top)
       this.context.rotate(Math.PI * rotate / 180 )
       this.context.font =  `${fontWeight} 400 ${fontSize} ${fontFamily}`
       this.context.fillText(content, 0.0)
       this.context.restore() 
       this._savePicture(cb)
    }
    /* Generate image */
    _savePicture(cb){
     const { width , height  } = this.options
       wx.canvasToTempFilePath({
          x:0.y:0,
          width,
          height,
          destWidth:width*1.destHeight:height*1.canvas:this.node,
          success:function(res){
             cb && cb(res.tempFilePath)
          }
       })
    }
}
/ * * * *@param {*} Options Configuration options */
function makeWatermark(options){
  if(! wx)return null
  return new MarkwaterMark(options) 
}

module.exports = makeWatermark
Copy the code

Core function process analysis:

  • Step 1: Expose the makeWatermark interface. You can instantiate a MarkwaterMark object, initializing itself during the instantiation process and wrapping a Promise layer around it to create images. Since many of the canvas methods are asynchronous, the createPromise method is used to broker a layer of Promises.

  • Step 2: On the MarkwaterMark object, there is the make method, which will get the canvas instance, then set the width, height and zoom ratio of the canvas, and draw the watermark canvas.

  • Step 3: Convert the Canvas into a temporary image using the canvasToTempFilePath interface, and pass the temporary image path to the business component or page in the form of callback.

The plug-in USES

In the business component (demo above), we can use the plugin above. Specific reference is as follows:

 mounted(){ 
       Taro.nextTick(() = >{
           /* Create a makeWatermark object
           const marker = makeWatermark(this.settings)
           /* Call make, generate image */
           marker.make((url) = >{
               /* The url is a temporary path */
               const fileManage = Taro.getFileSystemManager()
               let base64 = 'data:image/jpg; base64,' + fileManage.readFileSync(url,'base64');
               this.url = base64
               this.isShow  = false})})},Copy the code

Important details:

Another important detail here is that background images in applets are usually network images or Base64 images. Images with temporary paths are not displayed on real computers. To solve this problem, we need to convert the temporary image to a Base64 format image.

  • throughgetFileSystemManager ไปฅ base64Then return the base64 format. You can set the Base64 image as the background image.

Effect:

We’re done!!

Four summarizes

In this paper, we learn the micro channel small program to generate the watermark method and process. There are also some details in development. Those who are interested can collect them for a rainy day.

I wrote a little book on how to learn React systematically

In order to allow you to systematically learn React and the advanced React, the author recently wrote a small volume called “React Advanced Practice Guide”, which discusses the use guide and principle introduction of React in detail from five directions: basic advanced chapter, optimization advanced chapter, principle advanced chapter, ecology advanced chapter and practice advanced chapter.

  • In the basic advanced chapter, we will re-understand state, props, ref, context and other modules in React, and explain their basic use and advanced gameplay in detail.

  • In the Advanced optimization section, React performance tuning and detail processing will be discussed to make React write more elegant.

  • In the advanced chapter of Principles, the principles of several core modules of React will be expounded, and the React principles will be solved in one go.

  • In the advanced Chapter of Ecology, we will review the use of key ecology in React and analyze the internal operation mechanism from the perspective of principle.

  • In the practice of the advanced chapter, the first several modules will be connected to strengthen the practice.

As for the reason why the booklet is called the advanced practice guide, because in the advanced gameplay, there are also a lot of practical demos. There are also question-and-answer sessions in interviews that make readers stand out from the crowd.

Now, after completing the first 22 chapters, the small volume will be online soon. Those who want to advance React can check it out and follow the latest developments in the small volume.

Finally, send roses, hand left fragrance, feel that there is a harvest of friends can give the author thumbs up, concern a wave, one after another update front-end super-core articles.