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

您的位置:首頁技術(shù)文章
文章詳情頁

通過CSS數(shù)學(xué)函數(shù)實現(xiàn)動畫特效

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

    前言

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

    CSS 數(shù)學(xué)函數(shù)

    注意:以下的函數(shù)用原生 CSS 也都能實現(xiàn),這里用 SCSS 函數(shù)只是為了方便封裝,封裝起來的話更方便調(diào)用

    絕對值

    絕對值就是正的還是正的,負(fù)的變?yōu)檎?br>可以創(chuàng)造 2 個數(shù),其中一個數(shù)是另一個數(shù)的相反數(shù),比較它們的最大值,即可獲得這個數(shù)的絕對值

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

    中位數(shù)

    原數(shù)減 1 并乘以一半即可

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

    數(shù)軸上兩點距離

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

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

    三角函數(shù)

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

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

    例子

    以下的幾個動畫特效演示了上面數(shù)學(xué)函數(shù)的作用

    一維交錯動畫

    初始狀態(tài)

    創(chuàng)建一排元素,用內(nèi)部陰影填充,準(zhǔn)備好我們的數(shù)學(xué)函數(shù)

    <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;}(這里復(fù)制粘貼上文所有的數(shù)學(xué)公式).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);  }}

    應(yīng)用動畫

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

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

    地址:Symmetric Line Animation

    二維交錯動畫

    初始狀態(tài)

    如何將一維的升成二維?應(yīng)用網(wǎng)格系統(tǒng)即可

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

    應(yīng)用動畫

    跟上面的動畫一模一樣

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

    地址:Symmetric Grid Animation

    另一種動畫

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

    <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

    余弦波動動畫

    初始狀態(tài)

    創(chuàng)建 7 個不同顏色的(這里直接選了彩虹色)列表,每個列表有 40 個子元素,每個子元素是一個小圓點
    讓這 7 個列表排列在一條線上,且 z 軸上距離錯開,設(shè)置好基本的 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%;    }  }}

    余弦排列

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

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

    波動動畫

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

    .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,再應(yīng)用到動畫上即可

    .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

    到此這篇關(guān)于通過CSS數(shù)學(xué)函數(shù)實現(xiàn)動畫特效的文章就介紹到這了,更多相關(guān)CSS實現(xiàn)動畫特效內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

    標(biāo)簽: CSS HTML
    相關(guān)文章:
    主站蜘蛛池模板: 最新精品国产 | 欧美日韩一区二区综合 | 看国产一级片 | 自拍视频啪 | 欧美真人视频一级毛片 | 国内真实愉拍系列情侣自拍 | 国产91专区| 日韩毛片在线免费观看 | 国产只有精品 | 女在床上被男的插爽叫视频 | 美女张开腿让人桶 | 国产精品久久久久久一级毛片 | 亚洲国产99| 国产一级一片免费播放刺激 | 久久久久久久久网站 | xxxwww欧美性 | 免费观看成人www精品视频在线 | 黄在线观看网站 | 男女性高清爱潮视频免费观看 | 久草国产视频 | 女人张开双腿让男人桶完整 | 男女性高清爱潮视频免费观看 | 欧美视频精品 | 性色午夜视频免费男人的天堂 | 在线高清国产 | 男人天堂成人 | 国内自拍第五一页 | 萌白酱白丝护士服喷水铁牛tv | 韩国精品一区二区三区在线观看 | 日韩一区二区免费看 | 日韩一级黄色 | 欧美一级片免费在线观看 | 手机看成人免费大片 | 91精品国产高清久久久久久io | 国内真实愉拍系列情侣 | 欧美日本综合一区二区三区 | 国产免费影院 | 欧美高清在线精品一区二区不卡 | 欧美 亚洲 中文字幕 | 91精品国产爱久久久久 | 中文国产成人精品少久久 |