Have you also been teased by the UI and server for the blurring of images generated by front-end plug-ins?

Are you still sad because you can’t get along with little sister UI?

Are you frustrated that you can’t help your administrative sister?

Take a look at this Node-based screenshot plugin

Demand Background:

Recently little sister design and our R & D students put forward a demand. When the user previews the sharing component, a poster image is dynamically generated and then jS-SDK is called to share

The design drawing is as follows:

  • You can see that there are a lot of UI elements in the design, and the images and text are dynamically retrieved. It’s obviously not the best option to just ask the designer to draw

  • The first technical solution: We are rn development, using the view-shop plug-in to intercept a view to generate pictures. The disadvantage is that the resulting image is not captured in full screen but in a View box, so it inevitably stretches and blurs. Give up

  • There are many schemes to generate images by relying on the front end, such as generating IMG through canvas painting or exporting HTML screenshots to IMG. Finally, I export an image using nodejs+puppeteer

Puppeteer is a Node library that provides a high-level API for controlling Chromium or Chrome via the DevTools protocol

All we need to do is simulate a browser in the Node layer, open the HTML, take a screenshot, and output img

    // npm install puppeteer
    
    // index.js
    const Koa = require('koa');
    const Router = require('koa-router');
    const fs = require('fs');
    const path = require('path');
    
    router.get('/job-view'.async (ctx, next) => {
        // Pre-written pages with design styles
        const jobHtml = fs.readFileSync('./index.html'.'utf-8');
        ctx.body = jobHtml
        await next()
    })
    
    router.get('/job-view-to-img'.async (ctx, next) => {
        const browser = await puppeteer.launch({
            defaultViewport: {
              width: 450.height: 800.isMobile: true.deviceScaleFactor: 3}});const page = await browser.newPage();
        const url = `http://localhost:3031/job-view?${ctx.querystring}`
        await page.goto(url);
        // Get an img buffer
        const imgBuffer = await page.screenshot({});
        // The important thing is: Buffer can be used as the SRC attribute of the image, so we can use this interface as the SRC attribute of the IMG tag
        ctx.type = 'image/png';
        ctx.body = imgBuffer;
        await browser.close();
        await next()
    })
    
    app.use(router.routes())
    app.listen(3031)
Copy the code
    // index.jsx
    render() {
        // Since the interface defined in node layer returns images, it can be used directly
        const url = `http://localhost:3031/job-view-to-img?${queryString}`
        return (
            <img src={url} />)}Copy the code
  • These two pieces of code already satisfy this requirement. Get a url path that can be displayed through the Node middle tier

  • Consider: What if the next iteration requires a CDN link?

    // We modify the route in the code above
    router.get('/job-view-to-img'.async (ctx, next) => {
        const browser = await puppeteer.launch({
            defaultViewport: {
              width: 450.height: 800.isMobile: true.deviceScaleFactor: 3}});const page = await browser.newPage();
        const url = `http://localhost:3031/job-view?${ctx.querystring}`
        await page.goto(url);
        const imgBuffer = await page.screenshot({});
        // Save the image locally
        const filePath = await path.join(`./view-shopThe ${new Date().valueOf()}.png`)
        fs.writeFileSync(filePath, imgBuffer)
        // formData is not supported in node
        const formData = new FormData()
        formData.append('type'.'files')
        formData.append('file', fs.createReadStream(filePath))
        const {url} = await fetch('/upload', {body: formData})
        
        ctx.body = {
            status: 'ok! '.data: {url}
        }
        await browser.close();
        await next()
    })
Copy the code

What are the thoughts that come with this requirement? 🤔

  1. How can we better respond to the need for demanding, dynamic UI design?
  2. For a growth/marketing team, how can the front end help UI sister or operations sister be more efficient?
  3. More and more, I realized that the front end is not just about cutting graphics, but about using expertise to help the team become more efficient

So I plan to do an engineering, a suitable for the partial growth team (I have worked in the partial user operation team before, where there are a lot of requirements for generating pictures, fission and so on. More UI based design for each scene/user.)

He can satisfy:

  • N marketing pictures of different users can be generated locally through running scripts
  • Sharing images can be generated in the front end without being affected by the terminal
  • Image elements are retrieved from the back-end interface

So what are the scenarios:

  1. There are 20 students in my wechat group. Could you generate a picture with a sense of ceremony for all of them?
  2. Administrative little sister: I want to make the picture of noon menu every day, very tired, can generate automatically