background

Recently, in the development of small programs, CANVAS is the one I have contacted most. During this period, due to compatibility problems, I also experienced the replacement of new and old versions of the underlying API, and the pits I stepped on are impressive. The canvas of the small program (wechat) is quite different from the CANVAS of the HTML standard. Even the canvas underlying API of the small program itself is different from the two major versions (in fact, there was a version in ancient times, but it is too old to study it). The difference between the two versions currently in existence is whether they support “same-layer rendering”.

The render tree

Most of the content of the small program is rendered on the WebView, if the WebView is regarded as a separate layer, then the native components of the system are located in another higher level (such as Canvas, video). The two levels are completely independent, so you can’t simply control the relative level between native and non-native components by using z-Index. The only way to do this on top of a native component is with a cover-view and a cover-image. However, cover-View and Cover-Image support very limited CSS styles, and in practice, cover-View performance on some Android devices is really poor.

“Same layer rendering” is to render native components directly to the WebView hierarchy, you can control the hierarchy through a simple Z-index, and support CSS is very rich, Mommy no longer have to worry about the hierarchy problem I encountered! Doesn’t it look good? But the reality is harsh.

Problems with “same layer rendering”

First of all, according to the official article of the small program, almost the whole “native component” has been reconstructed. The usage mode and supported features are very different from those before, very similar to the standard Canvas API, and even the official claim that “most of the property methods of the standard Canvas are supported”. However, based on my actual project experience, the new Canvas API only works well on iOS, and there are a lot of weird behaviors on some Android machines. A simple example is when drawing multiple identical shapes, the brush seems to appear in “erratic” positions, resulting in an unpredictable end result. The other thing that’s really frustrating is the drawImage method. The first parameter of the new API drawImage must be an image instance. The createImage method can only be used to create an image instance. The simple method is implemented by calling drawImage again in its onLoad callback. And so on. But these can be overcome, and what ultimately led us to give up was the “uncertainty” on some Android devices. Given the choice between “new features” and “compatibility,” I think I’ll stick with “compatibility.” It’s like “graceful demotion” versus “progressive enhancement.” I prefer the latter.

“Same-layer Render” under “Compatibility”

I believe that most of the small programs that have done canvas correlation have hierarchical annoyance. Since it couldn’t be implemented using the new VERSION of the API, the problem had to be solved, and eventually we came up with a set of effects that could be implemented using the old VERSION of the API. At present, scenes that require “same-layer rendering” basically need to be flipped on canvas, so it is not necessary to operate canvas at the same time when covering canvas, because canvasToTempFilePath can be used to temporarily convert canvas into a picture and then hide canvas. Just display tempImage.

The light of the dawn

The new Canvas API is not all bad. One big change is that it no longer draws with physical dimensions, but with real ones. This makes drawing with the new API much higher resolution than the original, which is one of the few advantages. In addition, the new Canvas API works well on iOS. I hope the official can make the new Canvas API more compatible in the future, so that developers can get rid of these temporary schemes as soon as possible.