Transition and animation are important attributes in CSS3 for animation of DOM elements. However, they can only deal with some conventional requirements, and they are powerless for the transition of attributes of non-DOM elements. So the next step is to simply implement the principle of animation with JS (basically, using JavaScript to manipulate the target transition property value indirectly and update it every once in a while) to make the animation more flexible and controllable, rather than telling the hateful PM what the effect is and cutting it off, depending on the required usage scenario of course

First give a demo: for such requirements how to achieve?

You can’t do it with CSS.

A brief overview of the GIF above, the layout uses D3 implementation, for this demand, conventional visual graphics plug-ins (such as ECharts, IchartJS, etc.), through simple configuration may not be able to do, even if it can achieve flexibility is bound to be limited. For those familiar with D3, it will not be too complicated to implement. The figure is mainly about how to realize the effect of the change of numbers and the gradual change of arc color, as well as the overall linkage. The following describes the principle of animation through JS, making it easier to master CSS transition and animation

There are many articles about the transition and animation propertiesCSS3 animation properties

We’ll simply use JS to create an animation that changes the width property of the div element from 20px to 200px

The HTML code

<div id="motionPath"></div>
Copy the code

CSS code

#motionPath {
  width: 20px;
  height: 100px;
  color:# 333;
  background-color: red;
}
Copy the code

CubicBezier is a js library for CubicBezier curves, which is also used in the following animation functions. Equivalent CSS transition-timing-function and animation-timing-function

First define several parameters of the transition animation:

  1. Paused: Controls the animation pause flag
  2. Duration: animation transition time
  3. Easing: Animation transition curve, configure the normal animation transition curve reference easing function
  4. Update: Callback function for animation updates
var BezierEasing = require('bezier-easing')
var tween = {
  paused: false,
  duration: 6000,
  easing: BezierEasing(0, 0, 1, 0.5),
  update: function(v) {// Anim is an object defined below that describes the animation anim.target.innerhtml = v}}Copy the code

Define an animation start function play()

var raf = null
function play() {
  raf = requestAnimationFrame(function (t) {
    step(t);
  })

  function step(t) {
    if(! tween.paused) {setInstanceProgress(t);
      play();
    } else{ raf = cancelAnimationFrame(raf); }}}Copy the code

Step () is the entry point for the animation, which uses the requestAnimationFrame keyframe animation function. SetTimeout can also be used to simulate the implementation, but requestAnimationFrame is more recommended. Read requestAnimationFrame for an in-depth understanding. The setInstanceProgress() function is called during each animation keyframe cycle. Let’s look at the implementation of setInstanceProgress()

function setInstanceProgress(engineTime) {
  var insTime = engineTime;

  if (insTime > tween.duration) {
    tween.paused = true;
  }

  var currentTime = Math.min(Math.max(insTime, 0), tween.duration);
  
  setAnimationsProgress(currentTime);
}
Copy the code

The setInstanceProgress() function modifies the animation time and determines whether the animation should end, passing the modified time to the setAnimationsProgress() function, We know that animation is actually a function of “displacement” with respect to “time” : s=f(t) Associate animation function with time and calculate animation property value f(t) at time t.

Next, define an object that describes the animation with the following parameters:

  1. Target: The transition target object, currently the div element
  2. Type: The target attribute type of the transition. The width of the element is incorporated into CSS
  3. Property: The name of the target transition property, which is the element’s width
  4. FromNumber: Transition attribute starting value 20px
  5. ToNumber: End value of the transition property 200px
var anim = {
  target: document.getElementById('motionPath'),
  type: 'css',
  property: 'width',
  fromNumber: 20,
  toNumber: 200
}
Copy the code

SetAnimationsProgress () function

function setAnimationsProgress(insTime) {
  var elapsed = insTime / tween.duration;

  var eased = tween.easing(elapsed);

  var value = anim.fromNumber + (eased * (anim.toNumber - anim.fromNumber))

  setProgressValue[anim.type](anim.target, anim.property, value);
  
  tween.update(value);
}
Copy the code

The setAnimationsProgress() function is the core of the animation. It combines the time with the transition function, calculates the value of time t, and then sets the value to the target object property of the transition. Setting the width property is the same as setting the style property

var setProgressValue = {
  css: function (t, p, v) {
    t.style[p] = v + 'px'
  },
  plainkey: function (t, p, v) {
    t[p] = v
  }
}
Copy the code

Finally, you just need to run the play() function and a simple animation is created, which looks like this:

If we want to transition an object from plain={key: 0} with the key property value from 0 to 100, would we change the anim parameter as follows:

var plain = {key: 0}
var anim = {
  target: plain,
  type: 'plainkey',
  property: 'key',
  fromNumber: 0,
  toNumber: 200
}
Copy the code

I will not give the renderings of the key value changes, in short, through such a simple configuration to solve the CSS can not achieve similar requirements, the beginning of the article said that the effect of the number changes is perfect to solve

Finally, how to achieve the gradient effect of the sector at the beginning of the article? In fact, it is very simple. The sector is made by stitching together several small sectors, and then setting the corresponding color.

For example: Change the color from # e8CF22 to #48b532, apply the above transition animation principle, # E8CF22 corresponding RGB format is RGB (232, 207, 34), #48b532 corresponding RGB format is RGB (72, 181, 50), Then, the values of R, G and B are respectively transited according to their corresponding starting value and corresponding end value (R: from 232 to 72, G: from 207 to 181, B: From 34 to 50), the corresponding RGB value is combined again in the transition process is the corresponding color value of the transition, this is the color transition gradient principle, the following use animeJS library to achieve, the principle is the same

The HTML code

<div id="motionPath"></div>
Copy the code

CSS code

#motionPath {
  color: blue;
  height: 100px;
}
Copy the code

Js code

var oDev = document.getElementById('motionPath')
anime({
  targets: '#motionPath',
  duration: 6000,
  backgroundColor: ['rgb(232, 207, 34)'.'rgb(72, 181, 50)']
  easing: 'easeInOutQuad',
  update: function(instance) { oDev.innerHTML = instance.animations[0].currentValue; }});Copy the code

The effect is as follows:

To sum up: now that we know how to implement js animation, let’s look at an example using CSS3 animation. Example code:

// div
<div class="animation"></div> // css .animation { width: 100px; height: 100px; background: red; position: relative; animation: myfirst 4s; Animation - timing - function: cubic - the bezier (0.42,,0.58 0, 1); } @keyframes myfirst { 0% {background:red; left:0px; top:0px; } 25% {background:yellow; left:200px; top:0px; } 50% {background:blue; left:200px; top:200px; } 75% {background:green; left:0px; top:200px; } 100% {background:red; left:0px; top:0px; }} /* Cubic bezier(0.42,0,0.58,1) is used to change the color and position of a 100px div element at different time stages. Is the transition function cubic-bezier(0.42,0,0.58,1) applied to the entire transition period of 4s or to a complete transition at each stage? Answer: n% refers to the percentage of transition time duration, 0%~25%, that is, from 0s to 1s, then combined with the time t on the transition function cubic-bezier(0.42,0,0.58,1) to calculate the corresponding position point value and color value */Copy the code

The last

Animejs: Animejs: animejs: Animejs: Animejs: Animejs: Animejs: Animejs: Animejs: Animejs

In dealing with some requirements proposed by PM, as long as we clearly know which specific attribute needs to be transited, which initial state needs to be changed to a specified state, and then in what way (transition function) to transition, combined with the transition time duration, we believe that such an idea will be easily solved

About us

The front end team of Kuaigou Taxi focuses on sharing front-end technology and regularly pushes high-quality articles, which are welcome to be praised.