I. Requirement scenario

1. Front-end dynamic TWO-DIMENSIONAL code combination

For many marketing activities, the need to provide users with a downloadable TWO-DIMENSIONAL code, but the two-dimensional code to combine some specific business information, and then easy for users to share, spread, to achieve the marketing effect. This kind of picture download has a feature, two-dimensional code contains user information, so everyone’s two-dimensional code is not the same, and the business background is the same, and the user download the final picture style can be determined, at this time the front end needs their own ability to combine two pictures, download to the user.


2. Watermarking technology

Some website information content patent, anti-theft requirements, in order to let users download and share the content is not free to share, it is necessary to users download pictures covered with a layer of signature information, so as to prevent someone download pictures posing as the author, infringement of the author’s rights and interests.

3. There are many more scenarios…

Second, solutions

The premise of the solution is to use the ability of the client, pure front-end to solve. As a front-end developer, Canvas is fully capable of drawing, both 2D and 3D can be completed. My solution here is to use Canvas to do it. First of all, we need to make use of the drawing ability of Canvas. On the premise that the relative position and size of two images to be merged need to be known first, which requires you to communicate with visual students first. The actual canvas APIS involved include the following three: getContext, drawImage and toDataURL.

1. GetContext method

var ctx = canvas.getContext(contextType, contextAttributes);Copy the code
HTMLCanvasElement. GetContext () method returns the current canvas context, pay attention to is HTMLCanvasElement element method, can be a tag on the page, It can also be an element created by javascript’s createElement method.
Looking at the parameters to the getContext method, contextType is the type you want to draw on the canvas
2d,webgl,webgl2And so on.


The parameter value

meaning

2d Create CanvasRenderingContext2D, the type of choice for 2d Spaces like images.
webgl/experimental-webgl Create WebGLRenderingContext 3d render context object, suitable for 3d animation production development.
webgl2/experimental-webgl2 Create a 3d render context object called WebGL2RenderingContext, an updated version of WebGL.
bitmaprenderer Will create will be replaced with the specified canvas content ImageBitmap function ImageBitmapRenderingContext, canvas and the formation of a bitmap, the author also didn’t contact.


2. DrawImage method

The drawImage method is used in the context of getContext above, but it can only be called when contextType is 2D, i.e., when the contextType is 2d, and can be used to draw, compose, or cut images according to its call parameter control.

void ctx.drawImage(image, x, y);Copy the code

On the canvas, the image is positioned to the length of x coordinate and y coordinate, and the size of the picture drawn is the size of the picture itself and cannot be controlled.

void ctx.drawImage(image, x, y, width, height);Copy the code

Position the image image on the canvas to the x coordinate length and y coordinate length, and specify the width and height of the image image.

void ctx.drawImage(image, x, y, width, height, dx, dy, dWidth, dHeight);Copy the code

Position the image image to the x coordinate length and y coordinate length on the canvas, and specify the width and height of the image image, then cut it, put it at the coordinate of (dx,dy), and specify the width and height, feeling that you can quickly make a text magnifying glass.


3. ToDataURL method

canvas.toDataURL(type, encoderOptions);Copy the code

ToDataURL method also is provides HTMLCanvasElement element method, when the HTMLCanvasElement. ToDataURL () method, returns a contains pictures show the data of the URL, Format data like this :[

][;base64],
.

This method can take two arguments.

Type: Generate dataURL type, default is image/ PNG type, if need to generate JPG or other type can be passed in.

EncoderOptions: The generated dataURL quality parameter, which defaults to 0.92, can be passed in decimal numbers between 0 and 1. The larger the mass, the longer the string information is generated.


Three, the implementation process

1. Generate canvas

Form a canvas and put the first picture, usually a background picture, into the canvas. Note that the first argument to the drawImage method is the HTMLImageElement. You can get the IMG tag element on the page using Document. querySelector or generate it using createElement(‘img’). It depends on whether your image is displayed on the page.

// html
<img id="img" />
// javascript
class Canvas {
  / / create a canvas
  constructor (config = {}) {
    this.canvas = document.createElement('canvas');
    this.canvas.width = config.bgWidth;
    this.canvas.height = config.bgHeight;
    this.ctx = this.canvas.getContext('2d');
  }
  // Draw onto canvas
  async run(config) {
    // Images is the HTMLImageElement, not the link address
    const image = await getImage(config.src);
    this.ctx.drawImage(image, config.x, config.y, config.width, config.height);
  }
  // Verify use to render the produced graph on the page
  print() {
    document.querySelector('#img').setAttribute('src'.this.canvas.toDataURL()); }}/ / call
const mycanvas = new Canvas({
   bgWidth: 500.bgHeight: 600
})
mycanvas.run({
  src: 'https://n.sinaimg.cn/ent/transform/460/w630h630/20180824/Zaob-hicsiaw3749625.jpg'.x: 0.y: 0.width: 250.height: 600
}).then((a)= > {
  // Draw it on the page
  mycanvas.print()
})Copy the code

2, the assembly

Perform two times on the same CTX. Merge the two images and drawImage to complete the merge.

// html<img id="img" />
// javascript
// Canvas composition operation
class Canvas {... async run2(img1, img2) {const images = [img1, img2];
    const imgSrcs = images.map(({ src }) = > getImage(src));    
    const imgEles = await Promise.all(imgSrcs);    
    imgEles.map((ele, i) = > {      
       if (ele) {        
          const { x = 0, y = 0, width = 0, height = 0 } = images[i];        
          this.ctx.drawImage(ele, x, y, width, height); }}); }... }/ / call
const mycanvas = new Canvas({  
  bgWidth: 500.bgHeight: 600
})
mycanvas.run({
  src: 'https://n.sinaimg.cn/ent/transform/460/w630h630/20180824/Zaob-hicsiaw3749625.jpg'.x: 0.y: 0.width: 250.height: 600
}, {
  src: 'https://n.sinaimg.cn/ent/transform/460/w630h630/20180824/Zaob-hicsiaw3749625.jpg'.x: 250.y: 0.width: 250.height: 600
}).then((a)= > {
  // Draw it on the page
  mycanvas.print()
})Copy the code

3. The call result is as follows

4. Implement the download method

class Canvas {... download() {// File streaming download
    this.canvas.toBlob(blob= > {
      const a = document.createElement('a');
      a.download = 'image.png';
      a.style.display = 'none';
      a.href = URL.createObjectURL(blob);
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a); }); }... }Copy the code

Publish to NPM, open source sharing

At present, I have made the above function of combining pictures into open source package and uploaded it to NPM source. If necessary, you can use the following command directly.

NPM package address

https://www.npmjs.com/package/composite-image

Issue address

https://github.com/FantasyGao/composite-image/issues


// Use NPM/CNPM I --save composite-image // also use <script SRC = in HTML file'node_module/composite-image/composite-image.js'></script>Copy the code


Welcome to use and make some suggestions, thank you.



recruitment

Front-end Engineer:

  • At least 2 years working experience, bachelor degree or above.

  • Have good HTML/CSS/JS front-end foundation, have react/Vue and other mainstream framework development experience, and have a deep understanding of its principle, familiar with Webpack, Rollup packaging tools.

  • Strong interest in Internet products and Web technology, strong self-drive ability, learning ability and strong initiative.

  • Good basic knowledge of computer network.

  • (plus) Experience in server-side development.

  • (Bonus points) Proficient in mobile TERMINAL H5 / Hybrid development;

  • (Bonus points) Have sufficient practices and methods for mobile front-end performance optimization;

  • (bonus points) Familiar with small program development experience.

  • Be familiar with Node.js asynchronous programming, and understand the basic operation principle of NodeJS.

  • (Bonus points) Basic knowledge of finance, knowledge of payment related technology is preferred.


JAVA Engineer (Finance)


  • Participate in the research and development of new ant financial products, integrate with existing digital finance sectors, and create a more flexible and inclusive payment life experience;

  • Participate in the design, development and implementation of related applications and functional modules;

  • Ability to solve technical or business problems in the above areas in innovative ways.

  • At least 3 years of distributed system development experience in large and medium-sized Internet companies;

  • Front-end skills are preferred;

  • Clear and quick thinking, good communication and coordination ability and strong decision making ability.

  • Entrepreneurial spirit, can always maintain passion and sense of responsibility in the face of uncertainty and change.


The intern

Graduating students, no actual requirements, as long as you have a certain computer field knowledge, there is a certain strength, you can add my wechat, send your resume to me, help you evaluate, if appropriate will help you deliver.


The above positions, P6-P8 all have positions, the base location can be Hangzhou or Beijing, welcome to add my friends to send resume oh ~