国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

通過CSS數學函數實現動畫特效

瀏覽:302日期:2022-06-03 11:08:24
目錄
  • 前言
  • CSS 數學函數
    • 絕對值
    • 中位數
    • 數軸上兩點距離
    • 三角函數
  • 例子
    • 一維交錯動畫
      • 初始狀態
      • 應用動畫
      • 交錯動畫
    • 二維交錯動畫
      • 初始狀態
      • 應用動畫
      • 交錯動畫
    • 另一種動畫
      • 余弦波動動畫
        • 初始狀態
        • 余弦排列
        • 波動動畫
        • 交錯動畫

    前言

    大家好,這里是 CSS 兼 WebGL 魔法使——alphardex。
    之前一直在玩 three.js ,接觸了很多數學函數,用它們創造過很多特效。于是我思考:能否在 CSS 中也用上這些數學函數,但發現 CSS 目前還沒有,據說以后的新規范會納入,估計也要等很久。
    然而,我們可以通過一些小技巧,來創作出一些屬于自己的 CSS 數學函數,從而實現一些有趣的動畫效果。
    讓我們開始吧!

    CSS 數學函數

    注意:以下的函數用原生 CSS 也都能實現,這里用 SCSS 函數只是為了方便封裝,封裝起來的話更方便調用

    絕對值

    絕對值就是正的還是正的,負的變為正的
    可以創造 2 個數,其中一個數是另一個數的相反數,比較它們的最大值,即可獲得這個數的絕對值

    @function abs($v) {  @return max(#{$v}, calc(-1 * #{$v}));}

    中位數

    原數減 1 并乘以一半即可

    @function middle($v) {  @return calc(0.5 * (#{$v} - 1));}

    數軸上兩點距離

    數軸上兩點距離就是兩點所表示數字之差的絕對值,有了上面的絕對值公式就可以直接寫出來

    @function dist-1d($v1, $v2) {  $v-delta: calc(#{$v1} - #{$v2});  @return #{abs($v-delta)};}

    三角函數

    其實這個筆者也不會實現~不過之前看到過好友 chokcoco 的一篇文章寫到了如何在 CSS 中實現三角函數,在此表示感謝

    @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);}

    例子

    以下的幾個動畫特效演示了上面數學函數的作用

    一維交錯動畫

    初始狀態

    創建一排元素,用內部陰影填充,準備好我們的數學函數

    <div>  <div></div>  ...(此處省略14個 list-item)  <div></div></div>
    body {  display: flex;  justify-content: center;  align-items: center;  min-height: 100vh;  margin: 0;  background: #222;}:root {  --blue-color-1: #6ee1f5;}(這里復制粘貼上文所有的數學公式).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);  }}

    應用動畫

    這里用了 2 個動畫:grow 負責將元素縮放出來;melt 負責“融化”元素(即消除陰影的擴散半徑)

    <div>  <div></div>  ...(此處省略14個 list-item)  <div></div></div>
    .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);  }}

    交錯動畫

    1. 計算出元素下標的中位數
    2. 計算每個元素 id 到這個中位數的距離
    3. 根據距離算出比例
    4. 根據比例算出 delay
    <div>  <div></div>  ...(此處省略14個 list-item)  <div></div></div>
    .list {  &.middle-stagger {    .list-item {      --m: #{middle(var(--n))}; // 中位數,這里是7.5      --i-m-dist: #{dist-1d(var(--i), var(--m))}; // 計算每個id到中位數之間的距離      --ratio: calc(var(--i-m-dist) / var(--m)); // 根據距離算出比例      --delay: calc(var(--ratio) * var(--t)); // 根據比例算出delay      --n-delay: calc((var(--ratio) - 2) * var(--t)); // 負delay表示動畫提前開始      animation-delay: var(--n-delay);    }  }}

    地址:Symmetric Line Animation

    二維交錯動畫

    初始狀態

    如何將一維的升成二維?應用網格系統即可

    <div>  <div></div>  ...(此處省略62個 grid-item)  <div></div></div>
    .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);  }}

    應用動畫

    跟上面的動畫一模一樣

    <div>  <div></div>  ...(此處省略62個 grid-item)  <div></div></div>
    .grid {  &.grow-melt {    .grid-item {      --t: 2s;      animation-name: grow, melt;      animation-duration: var(--t);      animation-iteration-count: infinite;    }  }}

    交錯動畫

    1. 計算出網格行列的中位數
    2. 計算網格 xy 坐標到中位數的距離并求和
    3. 根據距離算出比例
    4. 根據比例算出 delay
    <div>  <div></div>  ...(此處省略62個 grid-item)  <div></div></div>
    .grid {  &.middle-stagger {    .grid-item {      --m: #{middle(var(--col))}; // 中位數,這里是7.5      --x-m-dist: #{dist-1d(var(--x), var(--m))}; // 計算x坐標到中位數之間的距離      --y-m-dist: #{dist-1d(var(--y), var(--m))}; // 計算y坐標到中位數之間的距離      --dist-sum: calc(var(--x-m-dist) + var(--y-m-dist)); // 距離之和      --ratio: calc(var(--dist-sum) / var(--m)); // 根據距離和計算比例      --delay: calc(var(--ratio) * var(--t) * 0.5); // 根據比例算出delay      --n-delay: calc((var(--ratio) - 2) * var(--t) * 0.5      ); // 負delay表示動畫提前開始      animation-delay: var(--n-delay);    }  }}

    地址:Symmetric Grid Animation

    另一種動畫

    可以換一種動畫 shuffle(穿梭),會產生另一種奇特的效果

    <div>  <div></div>  ...(此處省略254個 grid-item )  <div></div></div>
    .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);  }}

    地址:Shuffle Grid Animation

    余弦波動動畫

    初始狀態

    創建 7 個不同顏色的(這里直接選了彩虹色)列表,每個列表有 40 個子元素,每個子元素是一個小圓點
    讓這 7 個列表排列在一條線上,且 z 軸上距離錯開,設置好基本的 delay

    <div>  <div>    <div></div>    ...(此處省略39個 list-item)  </div>  ...(此處省略6個 list)</div>
    .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%;    }  }}

    余弦排列

    運用上文的三角函數公式,讓這些小圓點以余弦的一部分形狀進行排列

    .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));    }  }}

    波動動畫

    對每個小圓點應用上下平移動畫,平移的距離就是余弦的波動距離

    .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));  }}

    交錯動畫

    跟上面一個套路,計算從中間開始的 delay,再應用到動畫上即可

    .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);    }  }}

    地址:Rainbow Sine

    到此這篇關于通過CSS數學函數實現動畫特效的文章就介紹到這了,更多相關CSS實現動畫特效內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

    標簽: CSS HTML
    相關文章:
    主站蜘蛛池模板: 91久久精一区二区三区大全 | 久久香蕉国产精品一区二区三 | 亚洲国产二区三区 | 2018久久久国产精品 | 在线观看亚洲成人 | 亚洲免费专区 | 国产精品国产高清国产专区 | 亚洲欧美色视频 | 日韩三级免费观看 | 国产精品视频一区二区猎奇 | 精品国产自在现线看久久 | 国产成人午夜福在线观看 | 久久一日本道色综合久久 | 女人把腿劈开让男人桶的网站 | 亚洲精品在线看 | 欧美性妇| 国产一级在线 | 天堂男人2021av | 国产成人久久精品激情91 | 日韩午夜在线观看 | 草久视频在线观看 | 午夜视频在线观看一区 | 欧美中文字幕一区 | 澳门一级特黄真人毛片 | 国产aaa级一级毛片 国产aaa毛片 | 女在床上被男的插爽叫视频 | 偷拍精品视频一区二区三区 | 一级在线毛片 | 女在床上被男的插爽叫视频 | 亚洲理论在线观看 | a中文字幕1区 | 国产成人精品日本亚洲专一区 | 亚洲国产精品自在现线让你爽 | 97视频在线视频 | 精品国产系列 | 国产精品久久久久久久久久久不卡 | 亚洲毛片在线 | 日本综合欧美一区二区三区 | 手机在线观看一级午夜片 | 欧美色成人综合 | 97香蕉久久夜色精品国产 |