Invention Patent Publication -- CSS Animation Accurately Realizes the Clock

The last blog post [ setTimeout is not on time, CSS realizes the timer function accurately ] finally mentioned the way to realize the timer through CSS animation.

This article describes in detail how to fully realize the clock effect through CSS, which is also a content of the team's 21-year patent (patent publication number: CN114003087A).

This invention patent mainly solves the problem of inaccurate clock realized by javascript under the big screen. Timing is done through CSS animations to avoid synchronous blocking issues.

insert image description here

Pre-knowledge

pseudo element

Pseudo-elements allow you to modify styles for specific parts of selected elements.

::afterUsed to create a pseudo-element as the last child of the selected element. Attributes are usually used to contentadd decorative content to the element. This virtual element is an inline element by default.

Pseudo elements :beforeand :afteradded content are inline elements by default

  • Pseudo elements do not belong to the document , so js cannot manipulate it
  • The pseudo-element is part of the main element, so clicking on the pseudo-element triggers the click event of the main element
  • Only block-level elements can have :before, :after, which is actually inappropriate. Most row-level elements can also set pseudo-elements, but replaceable elements like img, because their appearance and size are determined by external resources, then if the external resources are correct Loading will replace its internal content, and the pseudo-element will also be replaced at this time, but when the external resource fails to load, the set pseudo-element can work.

example

a::after {
    
    
	content: "→";
}

data attribute data-*

HTML5 is designed to be extensible, it is intended that data should be associated with specific elements, but it does not require any definition. data-*Allows us to store additional information in HTML elements within the standard without using something like classList.

attr()

A CSS expression attr()is used to obtain an HTML attribute value of the selected element and use it for its style. It can also be used on pseudo-elements, the attribute value takes the element the pseudo-element is attached to.

attr()In theory, it can be used for all CSS properties, but currently only the content property of pseudo-elements is supported. Other properties and advanced features are currently experimental

example

Combining with data attributes, the corresponding effect display can be well realized.

hover to <a>the tag to display the corresponding data-hover content

<style>
  a:hover::after {
      
      
    content: attr(data-hover);
  }
</style>
<body>
	<a href="javascript:void(0);" data-hover="hover展示内容">hover</a>
</body>

css animation

The animation attribute is a shorthand attribute form of the animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, and animation-play-state attributes.

Attributes illustrate example
animation-name Specifies a sequence of animations to apply animation1,animation2
animation-duration Specify the duration of an animation cycle in s or ms 60s
animation-timing-function The cadence to execute in each animation cycle easelinearsteps(60)
animation-delay Define when the animation starts, in s or ms 100ms
animation-iteration-count Defines the number of times the animation will run before ending infinite(unlimited times),3
animation-direction Indicates whether the animation plays in reverse normalalternatereverse
animation-fill-mode Sets how CSS animations apply styles to their targets before and after execution forwardsbackwards
animation-play-state Defines whether an animation is running or paused runningpaused

steps(number_of_steps, direction): Defines a step function that divides the domain of output values ​​equidistantly.

example

The duration of the animation cycle is 10s, divided into 10 steps equidistantly, the timer is executed once per second, and the loop is executed infinitely.

animation: timer 10s infinite steps(10) forwards;

translate

transform: translate(x, y)/ translate: x y;translation transform.

example

a:hover {
    
    
  translate: 200px 50px;
  /*等价于*/
  transform: translate(200px, 50px);
}

Implementation ideas

insert image description here

Step 1: Define the DOM

DOM defines hours, minutes, and seconds, and binds related data through data attributes for hours, minutes, and secondsdata-*

<!-- 时 -->
<div class="card">
  <div class="card-hours"> <!-- 见步骤四其作用 -->
    <div class="hours" data-hours="18 19 20 21 22 23 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17"></div>
  </div>
</div>
<div class="card">:</div>
<!-- 分 -->
<div class="card">
  <div class="card-minutes">  <!-- 见步骤四其作用 -->
    <div class="minutes"
         data-minutes="58 59 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57">
    </div>
  </div>
</div>
<div class="card">:</div>
<!-- 秒 -->
<div class="card">
  <div class="seconds"
       data-seconds="50 51 52 53 54 55 56 57 58 59 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49">
  </div>
</div>

About data-hours, data-minutes, data-secondsdata are initialized with the current time (dynamic form). For the above example, the initial time is: 18:58:50

For the above, for minutes and hours, there is an additional layer of DOM, <div class="card-hours">and <div class="card-minutes">subsequent interpretation ( see step 4 ).

Step 2: Display the basic definition of the area

Here for: unified setting of hour, minute and second.

insert image description here

Set a fixed size font-sizeto ensure that only one number can be displayed in each line; at the same time, specify line-heightto ensure that only one number is displayed in the visible area. (preparing for the follow-up animation)

body {
    
    
  font-size: 48px;
}
.card {
    
    
  display: inline-block;
  height: 68px;
  overflow: hidden;
}
.hours, .minutes, .seconds {
    
    
  width: 68px;
  line-height: 68px;
}
  • font-size, line-heightattribute, with inheritance, runs through the entire web page
  • font-size, line-heightattributes, and font width have no necessary conversion relationship; if you want the font to be of equal width, you need to use equal width fonts (such as: Consolas, Monaco, monospace)

Step 3: Realize "seconds"

Each cycle is 60s, divided into 60 equidistant parts (sexagesimal), each part is 1s, and then the next value is displayed translateby .

insert image description here

.seconds:after {
    
    
  display: block;
  content: attr(data-seconds);
  animation: counter 60s steps(60) infinite forwards;
}
@keyframes counter {
    
    
  from {
    
    
    translate: 0 0;
  }
  to {
    
    
    translate: 0 -100%;
  }
}

Step 4: Realize "minutes and hours"

For minutes and hours, the logic of scrolling display is the same as that of seconds, but the number of cuts and unit time need to be determined according to the actual situation.

  • Minutes: equidistant 60 parts (sexadecimal), a cycle 60 ∗ 60 = 3600 60 * 60 = 36006060=3600
  • Hours: 24 equidistant (24 hexadecimal), one cycle $ 24 * 60 * 60 = 86400$
.minutes:after {
    
    
  display: block;
  content: attr(data-minutes);
  animation: counter 3600s steps(60) infinite forwards;
  animation-delay: 10s;	/* 延后执行 */
}

.hours:after {
    
    
  display: block;
  content: attr(data-hours);
  animation: counter 86400s infinite steps(24) forwards;
  animation-delay: 70s; /* 延后执行 */
}

The difference between minutes, hours and seconds is that the probability of the first base is not 60 or 24.

Explain with the above example: the current second is 50, and after another 10s (calculation method: $ 60 - 50 ), the minute should become 59; similarly, after another 70 seconds (calculation method: ), the minute should become 59; Similarly, after another 70s (calculation method:), the minute should become 59 ; similarly, after another 70 s (calculation method: 3600 - 58*60 - 50 $), the hour should become 19.

Therefore, the above animation-delayis to let the fixed-period animation start later, and the waiting time is calculated based on the initial time.

animation-delaySpecifies the amount of time to wait between applying an animation and before the element starts animating

The role of the delay is clearly explained, but the question is: how does the first animation perform? (The above animationis from the full cycle after the wait)

Step one, mentioned in <div class="card-hours">, <div class="card-minutes">is for this.

.card-minutes {
    
    
  height: 136px;
  overflow: hidden;
   /* 60-pastSeconds */
  animation: delay-counter 10s steps(1) 1 forwards;
}

.card-hours {
    
    
  height: 136px;
  overflow: hidden;
  /* 3600-pastMinutes*60-pastSeconds */
  animation: delay-counter 70s steps(1) 1 forwards;
}
@keyframes delay-counter {
    
    
  from {
    
    
    translate: 0 0;
  }
  to {
    
    
    translate: 0 -50%;
  }
}

The above animation is executed only once (initialization)

Summarize

CSS animations work well, even on low performance systems. Rendering engines use frame skipping or other techniques to keep animations as smooth as possible.

At the same time, the animation also provides corresponding events in each execution stage, which will not be expanded here for the time being. Those who have appeals can check the relevant MDN AnimationEvent .

Guess you like

Origin blog.csdn.net/ligang2585116/article/details/130640692