1. The background

This article is a technical summary and sharing of an H5 dynamic activity recently developed by netease LOFTER. The purpose is to share and exchange common front-end H5 dynamic effect scheme principle and application scenarios, as well as some H5 activity development adaptation and optimization skills. If you are interested, you can click the link below to experience it. Please open it on the mobile terminal.

Admission Notice Activity

2. The directory

  • Animation effect implementation scheme comparison
  • Mobile adaptation
  • Video preloading
  • Learning Materials recommendation

3. Comparison of animation effect implementation schemes

3.1 Horizontal motion animation

Pure CSS implementation scheme

Rough code

.animate. P3_d {animation: p3D 1s ease-in 0.1s forward; } @keyframes p3D { 0% { transform: translate3d(24rem, 0, 0); Transform: translate3D (7.2rem, 0, 0); } 100% {transform: translate3D (8.2rem, 0, 0); }}Copy the code

Implementation effect address

It can be seen that the overall animation effect is not flexible enough and looks stiff. The two key factors that affect the animation effect are keyframes and transition-timing-function of the animation. Ease-in is used here. Generally good transition effect will be achieved with Bezier curve (feel can write a separate article on the effect of bezier curve on animation, space reasons do not expand).

If the designer can help with these two key factors, use CSS. If not, consider another solution

Implemented using dynamics.js

Dynamics.js, a library that allows you to create realistic physics animations

const p30 = document.querySelector('.p3_0'); Dynamics. Animate (p30, {translateX: '1.7rem'}, {type: dynamics. Spring, Frequency: 40, friction: 200, duration: 1000, delay: 0.2});Copy the code

This language has been basically replaced by TS. If you think it can’t meet the requirements, it may be difficult to change the source code. Let’s take a look at the effect achieved by using dynamics

Implementation effect address

In fact, animation effect is like this, at first glance to achieve the effect are almost the same, but look carefully, there will be a lot of subtle differences between them, often these small differences, worth our in-depth study, so that the animation effect appears more flexible, realistic.

3.2 Random motion animation

Approach 1: Pure CSS for similar motion (not random)

You can refer to this example, although this example is not really random motion, but the implementation effect is also good, so as a reference case is also included in the comparison.

If you look at the implementation of optionFloatAniP2Key, you can see that there are a lot of keyframes in order to smooth the motion, which is very dependent on the visual export of the keyframes to the front end. The front end may not be able to achieve such a smooth animation by itself.

Method 2: Use JS to achieve random motion

First of all, let’s determine the direction in which the choice starts

We want the option to start moving in a random direction, up, down, left, or right:

  1. Generate a random number from 0 to 9 (other numbers are also acceptable, make sure the probability is 50%) and check whether it is an even number. If it is an even number, it moves in a positive direction and if it is an odd number, it moves in a negative direction
function randomDirection(velocity) {
    const isEventNum = Math.floor(Math.random() * 10) % 2;

    return isEventNum == 0 ? velocity : -velocity;
}

const velocityX = randomDirection(0.2)
const velocityY = randomDirection(0.2)
Copy the code

In this way, each option will have four choices at the beginning of [X, y], [-x, y], [x, -y], [-x, -y], realizing the randomness of the initial direction of motion.

  1. Set the maximum movement range for options

As shown, the red box is the range of motion of the option (this is just for demonstration purposes, the actual range will be much smaller).

If the range of motion is fixed, the motion is rigid, and you can make the range of motion random

function randomMax(num) {
    return num - Math.floor(Math.random() * num);
}

randomMax(25)
Copy the code

When the object reaches the range of motion, let it move in the opposite direction, and call the function again to update the range of motion distance. For example, the positive motion range of the x axis of the object is elemet.originLeft(the original coordinate value remains unchanged) + 25. After reaching this coordinate position, the object moves in the negative direction of the X axis and updates the x coordinate value of the motion range. Then, when the object moves in the positive direction of x axis next time, it may move to the position of Elemet. originLeft + 20 and move in the negative direction, which realizes the random movement distance.

Encapsulate the function of random motion, and all options are available.

advantage

The nice thing about this implementation is that it doesn’t require any designer support, as not every designer can export keyframes from their animations in AE.

All we need to do is adjust the speed and maximum distance of the object.

Video effect address

Implementation method 1: dom manipulation

At the beginning, I thought that it could be realized by manipulating DOM, but after thinking about it, if a timer is turned on and the translateX, translateY transformation of DOM is frequently used, there may be performance problems on low-end Android phones with a large number of DOM elements. I abandoned this implementation for a better user experience.

Implementation method 2: Canvas drawing

The performance of canvas drawing is better than that of DOM operation. Knowing the idea of random motion, it is not difficult to realize, except to call drawImage() method to draw. I will not repeat it here, but canvas drawing has a certain learning cost.

Sketching not clear

Today’s mainstream phones have high-definition screens, and a dot on the screen needs to be drawn with three pixels. In order to display the hd page, all our activities use a 3x image with width of 1125 for the visual draft. Canvas drawing also needs similar processing, please refer to the following article

Canvas drawing blur processing

Canvas click event handling

The graph drawn by Canvas cannot be bound with some click events like DOM. If interactive operations such as clicking are needed for the graph drawn, it can be judged according to the coordinates of clicking

// let clickElements = [a, b, c, d] function onClick(clientX, clinetY) { clickElements.forEach((element) => { if ( clinetY > element.top && clinetY < element.top + element.height && ClientX > clientx.left && clientX < element.left + element.width) {// Select object, do some operations}})}Copy the code

3.3 the frame animation

Click the option on p4 page, and there will be a Sprite animation, which works like this:

Sprite preview

ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
Copy the code

Sx and SY are the x and Y coordinates drawn, for example, area 1 in the first frame is drawn, area 2 in the second frame is drawn, and so on. Animation will be generated when the number of frames is switched, so this effect is called frame animation.

The animation Steps for CSS are the same.

Video effect address

3.4 Lottie animation

When it comes to animation effects, lottie-Web has to be mentioned. Designers often use AE software to create animation. They can export the animation to a JSON file and use Lottie-Web to restore the animation perfectly.

lottie.loadAnimation({ renderer: 'svg', loop: false, autoplay: false, container: document.querySelector('.p6_a'), name: 'p6a', animationData: p6aJson // json});Copy the code

The animation effects that Lottie-Web can achieve are:

  • translation
  • amplification
  • rotating
  • The fading
  • Various animations of SVG

. , etc.

It can basically meet most of the animation scenes, the biggest benefit is to save a lot of development time and time to coordinate with designers.

When I think about animation before, I think about how the implementation of the effects class can take a lot of time to develop and debug. Using Lottie-Web can really improve efficiency.

The volume of this library is also relatively mini, only about 67KB, compatibility is also better, the pro test in Android 4.4 version animation can also run.

Lottie – web defects

Some effects of special effects classes cannot be implemented

Like this effect

Clicking on elements that need to switch images is not easy to achieve

Lottie – Web mainly does animations for display purposes. Some animations that require interaction may need to be considered carefully, such as the option on p3 page, which requires switching images after clicking. This can be done if the element is a solid color, such as having the designer use SVG instead of image, and the SVG color can be inherited from the parent element. It can be done by clicking on the element and then switching colors.

3.5 Video Animation

Some special effects can be considered as background videos, such as transitions on page 1

Video effect address

The advantage of using video for animation is that the effect is cool and the access cost is low. If some dynamic effects cannot be realized by technical means, video access can be considered. Such dynamic effects cannot have interactive operation, so they are generally used as the background.

3.6 Animated graph to achieve animation

The topic on page 8 uses APNG. Click to switch colors. Let’s see the effect first

Video effect address

What is the default unselected state? Saturate (0) and Brightness (0) are set to 0 to change them to black, and when they are selected to 1 to change them to cyan.

.img { filter: saturate(0) brightness(0); Img {filter: saturate(1) Brightness (1); }Copy the code

3.7 Applicable scenes and summary of animation effects

3.7.1 CSS animation summary

If just some simple animation effects, using CSS directly is the most convenient.

If the effect is more complicated, it is better for the designer to provide keyframes and transition-timing function. If it is not possible, other schemes can be considered, or it may take more time to coordinate with the designer to achieve the effect.

If you have performance issues on your Android machine and need to optimize your performance, you can do so in the following two ways.

Transform: translate3d(0,0,0); // Mode 2: will-change: auto;Copy the code

3.7.2 Lottie Animation Summary

It can perfectly restore the animation produced by designers on AE, greatly saving the development and time of joint mobilization. It is often used for the display type of animation, and it is recommended to use the elements that need interaction as appropriate.

3.7.3 JS animation summary

CSS implementation of animation movement is fixed, js computing power can be used to make the animation effect, there are more abundant, such as generating random Numbers to realize random motion object, the object if we can add a downward displacement acceleration of gravity can be better, the effect of the simulation objects falling object movement speed, collision to wall springback by the motion of air resistance, The elastic effect of objects, etc.

Js animation can be implemented in two ways:

  1. If there are not many moving elements and performance requirements are not particularly high, you can use dom manipulation to achieve this, because you can easily bind events such as clicks
  2. The performance of canvas animation is excellent, and it can be considered when there are many animation elements on the page, but it has a certain learning cost. 2D animation is also ok, and further realization of 3D effects requires some knowledge of graphics, with a steep learning curve.

3.7.4 Frame animation summary

Frame animation effect is more natural, all kinds of effects can be achieved, but limited by the size of the picture, more suitable for small objects with fewer frames of animation, such as topic options, gestures, etc.. Because if the frame number is too many, the image is larger, rendering pressure on the phone.

3.7.5 Video animation summary

Special effects that are technically difficult to achieve can be made into videos. However, the playback of videos will often encounter some difficulties on mobile terminals. The size of videos should also be considered, and pre-loading should be done as required.

3.7.6 Animation summary of GIF

This kind of animation, like frame animation, is limited by the size of the picture and is suitable for the animation of small objects. The difference is that the animation realized by the GIF can only be played in a loop, while the frame animation is not subject to this limitation. There are two commonly used formats for the GIF:

  1. Apng format

It can make the background color transparent, which GIF can’t do

It is worth noting that using APNG requires compatibility issues, especially on android machines

As you can see, ios support for APNG is quite good, android is not so good, after the test students test Android 5 does not support APNG, but images can still be displayed, just can not move.

  1. WebP images with the same quality have smaller image volume and no obvious quality change after compression, which can also perfectly support lossless images, but also pay attention to compatibility problems

Android support is good, but ios support is not so good.

Generally speaking, I am quite optimistic about WebP, because APNG has not been officially approved by PNG organization at present, while WebP has excellent performance except compatibility problems. I believe WebP will become more and more popular with the upgrade of browser version.

4. Mobile page adaptation

Although the rem layout is used on the mobile end, there are still some special scenarios that need to be adapted. For example, the page is truncated at the bottom of the page in the simulator environment of Google iphone5

The performance on the real phone was even worse.

To adapt to such a small screen, we might think of using CSS media queries. Through observation, we can see that the spacing of elements is quite large, and we can adjust the spacing to achieve the purpose of adaptation.

coding…

// iphone 5 @media only screen and (min-device-width : 320px) and (max-device-height : 568px) { div1 { margin-top: xxx; }}Copy the code

It’s a great idea, but our activities need to be implemented in a variety of environments. In the Native Android browser, there are areas at the bottom for operations like back and forward, which undoubtedly makes the display area of the screen smaller. Even on larger phones, elements at the bottom are cut off. Moreover, we only adapted the size of iphone5. I realized that there are many sizes of phones in the market. If there is a problem, it is not an elegant solution to write a media query for this size of phone.

Use Flex layout adaptation

First let’s take a look at some flex properties

  • Flex-grow: Defines the scale of the project. Default is 0, and no scale is used even if there is free space
  • Flex-shrink: defines the size of a project. The default value is 1. If there is insufficient space, the project shrinks
  • Flex-basis: Defines the principal axis space that the project occupies before allocating extra space. From this property, the browser calculates whether the main axis has extra space. The default value is Auto, which is the original size of the project

Now look at the page

In the picture: parts 1, 2, 3 and 4 can be dynamically reduced according to the size of the screen. Elements such as serial number, title, picture and sealing line should not be reduced. In addition, the display area of title options, as the most important part of the page, should be dynamically adjusted with the larger screen of the mobile phone. Once you have an idea, start implementing it

// Use flex layout and set the main axis to vertical. page {display: flex; flex-direction: column; width: 100%; height: 100%; } // The area identified as 1 is filled with div. div1 {flex-basis: 0.95rem; flex-shrink: 1; } // The default size of the title display area is 13.36rem, and it does not shrink even if there is insufficient space, and the remaining space increases. flex-grow: 1; The flex - basis: 13.36 rem; }... The other elements are similarCopy the code

Flex-shrink can also define the shrink priority, such as Flex-shrink = 1 for div1 and Flex-shrink = 2 for div2, which gives priority to shrink the height of Div2

Flex-basis is a key attribute, and the Flex-basis browser allows for more accurate allocation of space to projects. In ios 10.3, if you use a height instead of flex-basis, elements will not be able to shrink.

Look at the end result

With Autoprefixer, flex layouts are compatible. Let’s take a look at device compatibility using the autopreFixer generated compatibility code display: -webkit-box

You can see the compatibility is pretty good

Summarize the two options

  • Media query is suitable for a single channel, such as only in an app, and there are not many models with layout problems, simple operation, adjust the elements of the problem
  • Flex layouts are recommended for a variety of scenarios and are compatible with Autoprefixer

5. Video preloading

Since there are several videos in the background of an event, it is common for developers to preload videos to give users a better look and feel. Here are two ways to preload videos.

Method 1: Load the video one page ahead

If your page follows a fixed access order, such as P1 => P2 => P3, you can consider adding a p2 video tag when accessing P1, and add preload=”auto” to the tag, and so on, to achieve a preload purpose. But this way is relatively restrictive.

  • The page access sequence must be fixed
  • Some mobile browsers force the preload attribute to None for user traffic, which defeats the purpose of preloading

Method 2: Request video resource data in advance

axios({ method: 'get', url: 'video url', responseType: 'blob'}).then(res => {const blobUrl = url.createObjecturl (res) // Generate the video tag and set SRC = blobUrl})Copy the code

The bloB is the raw data of the video. With createObjectURL, we can generate a BLOB URL and create the video tag, which is used for preloading purposes.

If that’s not enough, you can also listen for the Video TAB’s CanPlayThrough event, which is triggered when the browser determines that the video canplay smoothly without buffering.

this.video.addEventListener('canplaythrough', () => {
  callback && callback()
});
Copy the code

Imagine that there is a loading at the beginning of the activity, the video is preloaded behind it, and the page is officially entered after the loading. Such user experience is better.

This implementation can be applied to a variety of video playback scenarios, but it is worth noting that cross-domain issues need to be addressed if you want to request off-site video resources.

Video played by the pit

Required after the video tag is generated

this.video.load()
Copy the code

The load() method resets the media to the initialized state. If the video is played multiple times in Chrome and the load() method is not called, the video may not play.

In the wechat browser on the mobile end, some ios phones cannot trigger the CanPlayThrough event without calling the load() method.

Some Android phones will have a black screen for decoding before playing the video. You can overlay the first frame image on the video, listen for the timeUpdate event of the video, and hide the image when the currentTime property of the video has a value to prove that the video is playing.

Pseudo-code implementation, can do reference.

This article is published by the front-end team of Netease Yuanqi Business Division. Any unauthorized reprinting of this article is prohibited. Welcome to share with us the technical problems and experience related to the front-end. Meanwhile, the team and department are recruiting developers for front-end, server and client positions. You can contact [email protected] for the above information.