CSS Paint API

Original author: Ruth John
  • Transfer
According to the author of the material, the translation of which we publish today, CSS Paint API is an incredibly interesting technology. Moreover, we are talking not only about its current capabilities, but also about the phenomena it represents, and that its appearance marks the beginning of quite remarkable changes in the world of CSS. Here we will talk about the CSS Paint API and the reasons for its appearance, tell you how to use it.



What is the Paint CSS API?


The API in question is just a small part of the new set of specifications that is being worked on as part of the CSS Houdini project. If you briefly describe this project, then its essence boils down to the fact that it gives developers low-level access to the internal mechanisms of CSS.

The API Paint API allows you to call a function paint()in situations where, under normal conditions, work would be carried out, for example, with a certain value describing an image. A typical example of this is a property background-image; when working with which, you can use a function url()to transfer a system reference to an image file:

area {
  background-image: url('assets/myimage.jpg');
}

API Paint CSS allows you to call, instead of a similar function, a function paint(), and pass it the so-called worklet (described by means of JavaScript). A worklet can be perceived as a kind of code fragment that allows the developer to programmatically draw almost anything he wants. And, since we are talking about JavaScript, the image can be made dynamic. By itself, this API is very similar to the HTML5 Canvas API and now we’ll talk about how it all works.

CSS Paint API Features


If you now have the feeling that all this sounds good, but it looks difficult, and you think that you are quite comfortable with using ordinary images, keep in mind that ordinary images do not lose their relevance with the advent of the new technology. To use them, just as it was always done, is perfectly normal. The fact that something new, and probably promising, appears on the horizon does not mean that everyone should immediately use this new to solve all existing problems. However, ordinary images are static. The new API attracts the idea of ​​creating dynamic images.

Consider the linear-gradient CSS function . Stuck is very powerful. Take a look at this , for example.. But can you imagine how much easier it would be to achieve the same effect created by the overlay of layers, if you would not have to use a lot of background images? However, it's not just that. If you delve into the CSS Paint API, you can figure out how such images are created during program execution, and this can be very useful (actually, we plan to do this here).

What about the conic-gradient CSS functions? It can be said, is not yet supported by browsers without a polyfill. Using the new API allows you to create conical gradients, adjust their parameters, which are not particularly different from what is in the specification. All this means that in practice, using the new API, you can create your own native polyfills. And this is just wonderful.

Do not forget that all this is part of a larger group of possibilities, known as CSS Houdini. This is what is written in the project documentation: “The goal of CSS-TAG Houdini Task Force (CSS Houdini) is to jointly develop mechanisms that break the veils of mystery from the technologies of styling web pages and building their layouts.”

Sounds good, right? And, in fact, these new mechanisms are aimed at allowing developers to extend the functionality of CSS itself, giving them more advanced style management tools, cross-browser support and the ability to create polyfills.

The process of standardization of new technologies may take some time. First, a new CSS feature is offered. Further - the specification is written, there are other processes. As a result, browser manufacturers implement new specifications. And, since developers often cannot wait to begin using new features as soon as possible, they have to take into account the fact that older browsers may not support innovations, and that if a certain specification is not yet fully implemented, it may, in the course of its development, seriously change. Perhaps nothing to talk about the typical nuances of the implementation of different technologies in different browsers. The Houdini project can go quite far in mitigating these problems, allowing us to develop browser-based functionality ourselves, use it and quietly wait for the appearance of the implementation of certain capabilities by browser manufacturers. Here are a couple of materials on this topic.The first is dedicated to the strengths of Houdini, and the second - the use of the possibilities of this project to create complex animation.

API support for Paint Paint browsers


Can I use the CSS Paint API today? We can give a positive answer to this question, although it should be noted that far from all browsers support this technology. In order to get information about the support of this API, you can use the resource caniuse.com .


API support for Paint Paint with various browsers (July 2018)

As you can see, this API is supported only by Chrome so far. But be that as it may, let's talk about how to use it. We will look at the software constructs needed to make the new API work. This includes new CSS features and some pretty recent JavaScript mechanisms. Our example will be divided into three steps.

Step # 1: CSS


Recall that the formation of the image when using the API CSS Paint responsible vorklety - fragments of JS-code. Therefore, we first need to give the name of the workpiece and call it in CSS. Let's call him awesomePattern. As a result, the CSS code will look like this:

section {
  background-image: url('fallback.png');
  background-image: paint(awesomePattern);
};

The preliminary preparations have been completed, but until the rest of our example is ready, all this will not work.

Step 2: JavaScript


Now we need to describe the workbench using JS. It shows how, in the main script, loading another script that implements the functionality we need.

CSS.paintWorklet.addModule('patternWorklet.js');

At this stage, again, nothing happens, since the most interesting is hidden in the file patternWorklet.js.

In the file patternWorklet.jswe need to register the class of the vorklet:

registerPaint('awesomePattern', Shape);

Here we call the function registerPaint()and pass to it what we consider to be a worklet, in this case it is awesomePattern. In addition, we give this function a reference to the class that we will write, in this case - Shape. This command must be added after the declaration of the corresponding class. When declaring and using classes, you cannot rely on something like a mechanism for lifting function declarations. Before you can use a class, you must declare it.

Next, we are going to use the ECMAScript 2015 class declaration syntax and write a class that will draw the background image. Since now this class is registered as a class of the vorklet, we can use in it some special mechanisms that will be available in it automatically.

classShape {
  paint(ctx, geom, properties) {
    ctx.strokeStyle = 'white';
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc( 200, 200, 50, 0, 2*Math.PI);
    ctx.stroke();
    ctx.closePath();
  }
}

The callback paint()has parameters ctx, geomand properties. The parameter ctxis the same as the 2D rendering context that can be obtained from the element <canvas>. Well, it's almost the same. The point is that the element <canvas>allows you to read pixel data, but CSS Paint API does not allow this. Despite the differences, using ctx, we can use the same methods of displaying graphical objects that are used when working with an element <canvas>. In this example, using the function, arc()we draw a circle.

The first two values ​​passed to the function.arc()- These are the X and Y coordinates of the center of the circle, in pixels, relative to the origin of coordinates, located in the upper left corner of the element. However, I want the circle to be in the center of the element. To solve this problem, we need a parameter geom. It gives access to the object PaintSize, which is a description of the image parameters. In particular, referring to it, we can read the parameters widthand height, and this is exactly what we need in order to center the circle.

As a result, we come to this code:

classShape {
  paint(ctx, geom, properties) {
    
    let x = geom.width/2;
    let y = geom.height/2;
    ctx.strokeStyle = 'white';
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc(x, y, 50, 0, 2*Math.PI);
    ctx.stroke();
    ctx.closePath();
    
  }
}
registerPaint('awesomePattern', Shape);

You can see the working version of the example on CodePen . As a matter of fact, this is what this code displays.


Circle created by CSS Paint API means

Everything is good, but our example is very simple. Let's, instead of the usual circle, draw something more interesting. For example - such an asterisk - the logo of the site css-tricks.com.


Asterisk, created by CSS Paint API tools.

Here is a project on CodePen that allows you to do this.

When you look at the JS-code of this project, pay attention to the methoddrawStar()and to the many functions, such as are used when working with the element<canvas>.

Step 3: Custom CSS Properties


Using new technology, we can go much further than drawing circles and stars. We can turn to the powerful capabilities of custom CSS properties (variables). They, by the way, even by themselves, are very interesting. In our case, they are especially useful.

Suppose we want to be able to change the size or color of a previously created logo. These parameters can be placed in the CSS-code in the form of custom properties, and then use them in the program through the third parameter passed to the callback paint(). This is a parameter properties.

Add a property to our CSS code --star-scalethat aims to control the resizing of the image, and the property--star-colordesigned to organize the change of the color of the logo directly in the CSS. Here's what we got:

section {
  --star-scale: 2;
  --star-color: hsla(200, 50%, 50%, 1);
  background-image: paint(awesomePattern)
};

Now back to the vorklet class. Here we need to interact with the above user properties. This is done using a method inputPropertiesthat gives us access to all CSS properties and their assigned values.

staticgetinputProperties() { return ['--star-scale','--star-color']; }

Now you can work with them in the method paint():

const size = parseInt(properties.get('--shape-size').toString());

Naturally, the obtained values ​​can be used in the code responsible for the formation of the image. This leads to the fact that if we, in the CSS code, change the value of a property --star-scaleor --start-color, it will immediately reflect on how the image will look.

image

The effect of custom CSS properties on the finished image

This functionality is implemented in the same project on CodePen, which we mentioned above.

Incidentally, it should be noted that when using the new API all the usual properties of CSS-related background setting items, such asbackground-size, andbackground-repeatwill work in the same way as before. They have not lost relevance.

Results


The CSS Paint API is a very powerful technology whose capabilities are not limited to creating background images.

Imagine that an element should have a special border, for example, one that is not fully visible, or double. Perhaps to achieve these effects, you usually use pseudo-elements, ::beforeor ::after, perhaps, a specially configured shadow box-shadow. Borders (and much more) can be implemented using CSS Paint API and properties border-image.

The Paint API API brings together many great mechanisms such as wormlets, ECMAScript 2015 classes, and element capabilities.<canvas>. In addition, it provides the developer with software tools for managing image creation based on JavaScript. For example, using the event mechanism, you can organize the update of user properties, which means the image itself, as, for example, done here , where the event clickstarts the process of updating properties in a function requestAnimationFrame, which allows you to create an animation each time a user clicks a button. Moreover, even the coordinates of the mouse pointer are taken into account when clicked.

At first glance, all this may seem a bit confusing, but let's take a look at some other parts of the Houdini project that we can meet with:

  • API CSS Layout allows the developer to do something like display: layout('myCustomLayout'). A typical example is the creation of custom layouts in the style of the Masonry library, but the range of use of this feature is much wider.
  • The CSS Properties and Values ​​API allows you to set custom property types.
  • The CSS Animation Worklet API takes animation processing operations outside the main stream, which should be expressed as perfectly smooth animations.

As a result, we can say that, literally before our eyes, technologies are emerging that open up many new possibilities for web developers. The processes of their standardization and implementation in browsers are not so fast, but they, quite possibly, will have a tremendous impact on everything related to the styling of web pages.

Dear readers! Which areas of the CSS Paint API do you find most interesting?


Also popular now: