• Programmatically generate images with CSS Painting API
  • Viduni Wickramarachchi
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Hoarfroster
  • Proofread by: Zenblo, LSvih

Images add color and content to applications. However, if a large number of high-resolution images are embedded in a web page, it will greatly increase the load time of page resources and seriously affect the user experience. For images that show essential content such as products, solutions, etc., we have no choice but to embed these images in the normal way and optimize the application by caching them. However, if we need a geometric image in our application, we no longer need to load it as a resource.

We can use the CSS Painting API to generate geometric images in real time.

Let’s walk through the API and learn how to use it to generate images

An introduction to the CSS Painting API

Developers can use the CSS Painting API to draw images into CSS properties such as background-image and border using written JavaScript functions. It provides a set of apis that enable developers to access CSSOM, part of CSS Houdini (Houdini) — a collection of new browser apis that provide developers with lower-level access to CSS itself.

The traditional way to embed an image is as follows.

div {
    background-image: url('assets/background.jpg');
}
Copy the code

Using the CSS Painting API, we simply call paint() and pass in a JavaScript declared Worklet:

div {
    background-image: paint(background);
}
Copy the code

This string of code works like this:

There seems to be some arcane terminology in the above text. For example, we mentioned worklet?

In short, the JavaScript code that lets your program automatically generate images is called a Paint Worklet. Worklet is an extension to the browser rendering pipeline. In addition to Paint Worklets, there are other types of worklets, such as Animation Worklet and Layout Worklet.

Now, let’s take a look at a step-by-step approach to generating images programmatically.

Use the CSS Painting API in practice

In this article, we will explore how to create a bubble background

Step 1: Add the CSS paint() function

To get started, we need to add the paint() function to the CSS properties where we want to add the image.

.bubble-background {
    width: 400px;
    height: 400px;
    background-image: paint(bubble);
}
Copy the code

Bubble is the Worklet that we’re going to generate the image in a second, and to generate the Worklet, it’s only a few short steps.

Step 2: Define the Worklet

The Worklet needs to be saved in an external JavaScript file, and the Painting Worklet should be a class such as Class Bubble {… }, and then the Worklet needs to be registered with the registerPaint() function.

class Bubble {
    paint(context, canvas, properties) {
        / *TODO:. * /
    }
}

registerPaint('bubble', Bubble);
Copy the code

The first argument to the registerPaint() function is the reference name we want to use in our CSS.

Now let’s draw the background!

class Bubble {
    paint(context, canvas, properties) {
        const circleSize = 10;
        const bodyWidth = canvas.width;
        const bodyHeight = canvas.height;

        const maxX = Math.floor(bodyWidth / circleSize);
        const maxY = Math.floor(bodyHeight / circleSize);

        for (let y = 0; y < maxY; y++) {
            for (let x = 0; x < maxX; x++) {
                context.fillStyle = '#eee';
                context.beginPath();
                context.arc(x * circleSize * 2 + circleSize, y * circleSize * 2 + circleSize, circleSize, 0.2 * Math.PI, true);
                context.closePath();
                context.fill();
            }
        }
    }
}

registerPaint('bubble', Bubble);
Copy the code

The operation to create the image is done inside the paint() function. We will need some knowledge of Canvas to draw the above image. If not, we can actually look at the Canvas API documentation.

Step 3: Call the Worklet

The last step is to call the Worklet in the HTML file.


<div class="bubble-background"></div>

<script>
    CSS.paintWorklet.addModule('https://codepen.io/viduni94/pen/ZEpgMja.js');
</script>
Copy the code

That’s it!

You now have a program that automatically generates an image in three steps.

Generated image

The code we write should look like this:

What else can we do with the CSS Painting API?

The power of the CSS Painting API is not over yet. There are more things you can do with it.

1. We can create giFs

For example, we can change the color of bubbles dynamically, and CSS variables serve this purpose. In order to use CSS variables, browsers should first understand that we are using them. We can do this using the inputProperties() function.

registerPaint('bubble'.class {
    static get inputProperties() {
        return ['--bubble-size'.'--bubble-color'];
    }

    paint() {
        / *... * /}});Copy the code

Variables can be passed to the paint() method as a third argument

paint(context, canvas, properties)
{
    const circleSize = parseInt(properties.get('--bubble-size').toString());
    const circleColor = properties.get('--bubble-color').toString();
    const bodyWidth = canvas.width;
    const bodyHeight = canvas.height;

    const maxX = Math.floor(bodyWidth / circleSize);
    const maxY = Math.floor(bodyHeight / circleSize);

    for (let y = 0; y < maxY; y++) {
        for (let x = 0; x < maxX; x++) {
            context.fillStyle = circleColor;
            context.beginPath();
            context.arc(x * circleSize * 2 + circleSize, y * circleSize * 2 + circleSize, circleSize, 0.2 * Math.PI, true); context.closePath(); context.fill(); }}}Copy the code

We can use itMath.random()paint()Function to generate random images

body {
    width: 200px;
    height: 200px;
    background-image: paint(random);
}
Copy the code
function getRandomHexColor() {
    return The '#' + Math.floor(Math.random() * 16777215).toString(16)}class Random {
    paint(context, canvas) {
        const color1 = getRandomHexColor();
        const color2 = getRandomHexColor();

        const gradient = context.createLinearGradient(0.0, canvas.width, 0);
        gradient.addColorStop(0, color1);
        gradient.addColorStop(1, color2);

        context.fillStyle = gradient;
        context.fillRect(0.0, canvas.width, canvas.height);
    }
}

registerPaint('random', Random);
Copy the code

If you’re wondering how to do this, please post your questions in the comments section.

This is great!

However, every good thing has a bad side, and the API is currently only fully supported by some browsers.

Browser support

Most browsers, including Firefox, do not support the CSS Painting API. So far, only Chromium-based browsers have fully supported this feature, so hopefully browser support will improve in the near future.

Abstract

The CSS Painting API is useful for reducing the response time of network requests because images are generated programmatically rather than fetching network data.

Above all, I think the main benefits are as follows.

  • Ability to create fully customizable images instead of static images.
  • It creates images that are resolution-independent (so that we no longer have poor quality images on our site).

It is important to note that libraries such as Polyfill can be used as a solution to support browsers such as Firefox that do not yet implement the CSS Painting API.


If you have any questions or thoughts about this article, let us know in the comments section! Thanks for reading!

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.