current position:Home>Interesting CSS math functions
Interesting CSS math functions
2021-08-26 15:47:07 【alphardex】
Preface
Hello everyone , Here is CSS and WebGL Magic ——alphardex.
I've been playing three.js , Touched a lot of mathematical functions , Used them to create a lot of special effects . So I thought : Can it be in CSS These mathematical functions are also used in , But found CSS Not yet , It is said that the future new specifications will be incorporated into , I guess it will take a long time .
However , We can do it with a few tricks , To create something of your own CSS Mathematical functions , So as to achieve some interesting animation effects .
Let's get started !
CSS Mathematical functions
Be careful : The following functions use native CSS It can also be realized , Here we use SCSS Function is just for convenience of encapsulation , If encapsulated, it is more convenient to call
The absolute value
Is the absolute value positive or positive , Negative becomes positive
Can create 2 Number , One of them is the opposite of the other , Compare their maximum values , You can get the absolute value of this number
@function abs($v) {
@return max(#{$v}, calc(-1 * #{$v}));
}
Copy code
Median
Original number minus 1 And multiply by half
@function middle($v) {
@return calc(0.5 * (#{$v} - 1));
}
Copy code
The distance between two points on the number axis
The distance between two points on the number axis is the absolute value of the difference between the numbers represented by two points , With the above absolute value formula, you can write it directly
@function dist-1d($v1, $v2) {
$v-delta: calc(#{$v1} - #{$v2});
@return #{abs($v-delta)};
}
Copy code
Trigonometric functions
In fact, the author will not realize ~ But I've seen it before Good friends chokcoco An article from Wrote about how to CSS Trigonometric function in , Thank you
@function fact($number) {
$value: 1;
@if $number>0 {
@for $i from 1 through $number {
$value: $value * $i;
}
}
@return $value;
}
@function pow($number, $exp) {
$value: 1;
@if $exp>0 {
@for $i from 1 through $exp {
$value: $value * $number;
}
} @else if $exp < 0 {
@for $i from 1 through -$exp {
$value: $value / $number;
}
}
@return $value;
}
@function rad($angle) {
$unit: unit($angle);
$unitless: $angle / ($angle * 0 + 1);
@if $unit==deg {
$unitless: $unitless / 180 * pi();
}
@return $unitless;
}
@function pi() {
@return 3.14159265359;
}
@function sin($angle) {
$sin: 0;
$angle: rad($angle);
// Iterate a bunch of times.
@for $i from 0 through 20 {
$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
}
@return $sin;
}
@function cos($angle) {
$cos: 0;
$angle: rad($angle);
// Iterate a bunch of times.
@for $i from 0 through 20 {
$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
}
@return $cos;
}
@function tan($angle) {
@return sin($angle) / cos($angle);
}
Copy code
Example
The following animation effects demonstrate the role of the above mathematical functions
One dimensional interlaced animation
The initial state
Create a row of elements , Fill... With internal shadows , Prepare our mathematical functions
<div class="list">
<div class="list-item"></div>
...( Omit here 14 individual list-item)
<div class="list-item"></div>
</div>
Copy code
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: #222;
}
:root {
--blue-color-1: #6ee1f5;
}
( Copy and paste all the above mathematical formulas here )
.list {
--n: 16;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
&-item {
--p: 2vw;
--gap: 1vw;
--bg: var(--blue-color-1);
@for $i from 1 through 16 {
&:nth-child(#{$i}) {
--i: #{$i};
}
}
padding: var(--p);
margin: var(--gap);
box-shadow: inset 0 0 0 var(--p) var(--bg);
}
}
Copy code
Apply animation
This is used here. 2 An animation :grow Responsible for scaling out elements ;melt be responsible for “ melt ” Elements ( That is, the diffusion radius of eliminating shadows )
<div class="list grow-melt">
<div class="list-item"></div>
...( Omit here 14 individual list-item)
<div class="list-item"></div>
</div>
Copy code
.list {
&.grow-melt {
.list-item {
--t: 2s;
animation-name: grow, melt;
animation-duration: var(--t);
animation-iteration-count: infinite;
}
}
}
@keyframes grow {
0% {
transform: scale(0);
}
50%,
100% {
transform: scale(1);
}
}
@keyframes melt {
0%,
50% {
box-shadow: inset 0 0 0 var(--p) var(--bg);
}
100% {
box-shadow: inset 0 0 0 0 var(--bg);
}
}
Copy code
Interlace animation
- Calculate the median of the element subscript
- Calculate each element id The distance to this median
- Calculate the scale according to the distance
- Calculate... According to the proportion delay
<div class="list grow-melt middle-stagger">
<div class="list-item"></div>
...( Omit here 14 individual list-item)
<div class="list-item"></div>
</div>
Copy code
.list {
&.middle-stagger {
.list-item {
--m: #{middle(var(--n))}; // Median , Here is 7.5
--i-m-dist: #{dist-1d(var(--i), var(--m))}; // Calculate each id The distance to the median
--ratio: calc(var(--i-m-dist) / var(--m)); // Calculate the scale according to the distance
--delay: calc(var(--ratio) * var(--t)); // Calculate... According to the proportion delay
--n-delay: calc((var(--ratio) - 2) * var(--t)); // negative delay Indicates that the animation starts in advance
animation-delay: var(--n-delay);
}
}
}
Copy code
Address :Symmetric Line Animation
2D interlaced animation
The initial state
How to turn one-dimensional into two-dimensional ? Apply grid system
<div class="grid">
<div class="grid-item"></div>
...( Omit here 62 individual grid-item)
<div class="grid-item"></div>
</div>
Copy code
.grid {
$row: 8;
$col: 8;
--row: #{$row};
--col: #{$col};
--gap: 0.25vw;
display: grid;
gap: var(--gap);
grid-template-rows: repeat(var(--row), 1fr);
grid-template-columns: repeat(var(--col), 1fr);
&-item {
--p: 2vw;
--bg: var(--blue-color-1);
@for $y from 1 through $row {
@for $x from 1 through $col {
$k: $col * ($y - 1) + $x;
&:nth-child(#{$k}) {
--x: #{$x};
--y: #{$y};
}
}
}
padding: var(--p);
box-shadow: inset 0 0 0 var(--p) var(--bg);
}
}
Copy code
Apply animation
As like as two peas
<div class="grid grow-melt">
<div class="grid-item"></div>
...( Omit here 62 individual grid-item)
<div class="grid-item"></div>
</div>
Copy code
.grid {
&.grow-melt {
.grid-item {
--t: 2s;
animation-name: grow, melt;
animation-duration: var(--t);
animation-iteration-count: infinite;
}
}
}
Copy code
Interlace animation
- Calculate the median of grid rows and columns
- Computing grid xy The distance from the coordinates to the median and sum
- Calculate the scale according to the distance
- Calculate... According to the proportion delay
<div class="grid grow-melt middle-stagger">
<div class="grid-item"></div>
...( Omit here 62 individual grid-item)
<div class="grid-item"></div>
</div>
Copy code
.grid {
&.middle-stagger {
.grid-item {
--m: #{middle(var(--col))}; // Median , Here is 7.5
--x-m-dist: #{dist-1d(var(--x), var(--m))}; // Calculation x The distance from the coordinates to the median
--y-m-dist: #{dist-1d(var(--y), var(--m))}; // Calculation y The distance from the coordinates to the median
--dist-sum: calc(var(--x-m-dist) + var(--y-m-dist)); // The sum of distances
--ratio: calc(var(--dist-sum) / var(--m)); // Calculate scale based on distance and
--delay: calc(var(--ratio) * var(--t) * 0.5); // Calculate... According to the proportion delay
--n-delay: calc(
(var(--ratio) - 2) * var(--t) * 0.5
); // negative delay Indicates that the animation starts in advance
animation-delay: var(--n-delay);
}
}
}
Copy code
Address :Symmetric Grid Animation
Another animation
You can change the animation shuffle( shuttle ), Will produce another strange effect
<div class="grid shuffle middle-stagger">
<div class="grid-item"></div>
...( Omit here 254 individual grid-item )
<div class="grid-item"></div>
</div>
Copy code
.grid {
$row: 16;
$col: 16;
--row: #{$row};
--col: #{$col};
--gap: 0.25vw;
&-item {
--p: 1vw;
transform-origin: bottom;
transform: scaleY(0.1);
}
&.shuffle {
.grid-item {
--t: 2s;
animation: shuffle var(--t) infinite ease-in-out alternate;
}
}
}
@keyframes shuffle {
0% {
transform: scaleY(0.1);
}
50% {
transform: scaleY(1);
transform-origin: bottom;
}
50.01% {
transform-origin: top;
}
100% {
transform-origin: top;
transform: scaleY(0.1);
}
}
Copy code
Address :Shuffle Grid Animation
Cosine wave animation
The initial state
establish 7 A different color ( The rainbow color is directly selected here ) list , Each list has 40 Sub elements , Each child element is a dot
Let this 7 A list is arranged on a line , And z The distance on the axis is staggered , Set up the basic delay
<div class="lists">
<div class="list">
<div class="list-item"></div>
...( Omit here 39 individual list-item)
</div>
...( Omit here 6 individual list)
</div>
Copy code
.lists {
$list-count: 7;
$colors: red, orange, yellow, green, cyan, blue, purple;
position: relative;
width: 34vw;
height: 2vw;
transform-style: preserve-3d;
perspective: 800px;
.list {
position: absolute;
top: 0;
left: 0;
display: flex;
transform: translateZ(var(--z));
@for $i from 1 through $list-count {
&:nth-child(#{$i}) {
--bg: #{nth($colors, $i)};
--z: #{$i * -1vw};
--basic-delay-ratio: #{$i / $list-count};
}
}
&-item {
--w: 0.6vw;
--gap: 0.15vw;
width: var(--w);
height: var(--w);
margin: var(--gap);
background: var(--bg);
border-radius: 50%;
}
}
}
Copy code
Cosine permutation
Using the trigonometric function formula above , Let these dots be arranged in the shape of a part of the cosine
.lists {
.list {
&-item {
$item-count: 40;
$offset: pi() * 0.5;
--wave-length: 21vw;
@for $i from 1 through $item-count {
&:nth-child(#{$i}) {
--i: #{$i};
$ratio: ($i - 1) / ($item-count - 1);
$angle-unit: pi() * $ratio;
$wave: cos($angle-unit + $offset);
--single-wave-length: calc(#{$wave} * var(--wave-length));
--n-single-wave-length: calc(var(--single-wave-length) * -1);
}
}
transform: translateY(var(--n-single-wave-length));
}
}
}
Copy code
Wave animation
Apply up and down translation animation to each small circle point , The translation distance is the cosine wave distance
.lists {
.list {
&-item {
--t: 2s;
animation: wave var(--t) infinite ease-in-out alternate;
}
}
}
@keyframes wave {
from {
transform: translateY(var(--n-single-wave-length));
}
to {
transform: translateY(var(--single-wave-length));
}
}
Copy code
Interlace animation
Follow the above routine , The calculation starts in the middle delay, Then apply it to the animation
.lists {
.list {
&-item {
--n: #{$item-count + 1};
--m: #{middle(var(--n))};
--i-m-dist: #{dist-1d(var(--i), var(--m))};
--ratio: calc(var(--i-m-dist) / var(--m));
--square: calc(var(--ratio) * var(--ratio));
--delay: calc(
calc(var(--square) + var(--basic-delay-ratio) + 1) * var(--t)
);
--n-delay: calc(var(--delay) * -1);
animation-delay: var(--n-delay);
}
}
}
Copy code
Address :Rainbow Sine
Last
CSS Mathematical functions can achieve far more special effects than this , I hope this article can inspire you to create special effects ~
copyright notice
author[alphardex],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210826154700304e.html
The sidebar is recommended
- Crazy blessing! Tencent boss's "million JVM learning notes", real topic of Huawei Java interview 2020-2021
- JS JavaScript how to get the subscript of a value in the array
- How to implement injection in vuex source code?
- JQuery operation select (value, setting, selected)
- One line of code teaches you how to advertise on Tanabata Valentine's Day - Animation 3D photo album (music + text) HTML + CSS + JavaScript
- An article disassembles the pyramid architecture behind the gamefi outbreak
- BEM - a front-end CSS naming methodology
- [vue3] encapsulate custom global plug-ins
- Error using swiper plug-in in Vue
- Another ruthless character fell by 40000, which was "more beautiful" than Passat and maiteng, and didn't lose BMW
guess what you like
-
Huang Lei basks in Zhang Yixing's album, and the relationship between teachers and apprentices is no less than that in the past. Netizens envy Huang Lei
-
He was cheated by Wang Xiaofei and Li Chengxuan successively. Is an Yixuan a blessed daughter and not a blessed home?
-
Zhou Shen sang the theme song of the film "summer friends and sunny days" in mainland China. Netizen: endless aftertaste
-
Pink is Wangyuan online! Back to the peak! The new hairstyle is creamy and sassy
-
Front end interview daily 3 + 1 - day 858
-
Spring Webflux tutorial: how to build reactive web applications
-
[golang] walk into go language lesson 24 TCP high-level operation
-
August 23, 2021 Daily: less than three years after its establishment, Google dissolved the health department
-
The female doctor of Southeast University is no less beautiful than the female star. She has been married four times, and her personal experience has been controversial
-
There are many potential safety hazards in Chinese restaurant. The top of the program recording shed collapses, and the artist will fall down if he is careless
Random recommended
- Anti Mafia storm: He Yun's helpless son, Sun Xing, is destined to be caught by his dry son
- Introduction to flex flexible layout in CSS -- learning notes
- CSS learning notes - Flex layout (Ruan Yifeng tutorial summary)
- Today, let's talk about the arrow function of ES6
- Some thoughts on small program development
- Talk about mobile terminal adaptation
- Unwilling to cooperate with Wang Yibo again, Zhao Liying's fans went on a collective strike and made a public apology in less than a day
- JS function scope, closure, let, const
- Zheng Shuang's 30th birthday is deserted. Chen Jia has been sending blessings for ten years. Is it really just forgetting to make friends?
- Unveil the mystery of ascension
- Asynchronous solution async await
- Analysis and expansion of Vue infinite scroll source code
- Compression webpack plugin first screen loading optimization
- Specific usage of vue3 video play plug-in
- "The story of huiyeji" -- people are always greedy, and fairies should be spotless!
- Installing Vue devtool for chrome and Firefox
- Basic usage of JS object
- 1. JavaScript variable promotion mechanism
- Two easy-to-use animation JS that make the page move
- Front end Engineering - scaffold
- Java SQL Server intelligent fixed asset management, back end + front end + mobile end
- Mediator pattern of JavaScript Design Pattern
- Array de duplication problem solution - Nan recognition problem
- New choice for app development: building mobile applications using Vue native
- New gs8 Chengdu auto show announces interior Toyota technology blessing
- Vieira officially terminated his contract and left the team. The national security club sent blessings to him
- Less than 200000 to buy a Ford RV? 2.0T gasoline / diesel power, horizontal bed / longitudinal bed layout can be selected
- How does "heart 4" come to an end? Pinhole was boycotted by the brand, Ma Dong deleted the bad comments, and no one blessed him
- We are fearless in epidemic prevention and control -- pay tribute to the front-line workers of epidemic prevention!
- Front end, netty framework tutorial
- Xiaomi 11 | miui12.5 | android11 solves the problem that the httpcanary certificate cannot be installed
- The wireless charging of SAIC Roewe rx5 plus is so easy to use!
- Upload and preview pictures with JavaScript, and summarize the most complete mybatis core configuration file
- [25] typescript
- CSS transform Complete Guide (Second Edition) flight.archives 007
- Ajax foundation - HTTP foundation of interview essential knowledge
- Cloud lesson | explain in detail how Huawei cloud exclusive load balancing charges
- Decorator pattern of JavaScript Design Pattern
- [JS] 10. Closure application (loop processing)
- Left hand IRR, right hand NPV, master the password of getting rich