ホームページ  >  記事  >  ウェブフロントエンド  >  純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

青灯夜游
青灯夜游転載
2022-01-27 10:52:592432ブラウズ

この記事では、純粋な CSS を使用してチャイニーズ ノットを段階的に描画し、このチャイニーズ ノットに赤い封筒の雨のアニメーション効果を追加する方法を説明します。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

春節は中国人にとって最も重要なお祭りであり、春節には東西南北で異なる多くの風習があります。 新年の雰囲気をさらに高めるために、各家庭では、赤い提灯、赤い対句、赤い祝福文字、赤い中国結びなど、家を繁栄させるためのさまざまな正月用品や装飾品を新年の間に購入します。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

チャイニーズノットの原材料はシンプルな赤いロープで、古代人の独創的な発想によってひし形の格子状に編み込まれています。格子上のロープはしっかりと結ばれており、家族の団結、調和、幸福を象徴しています。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

#それでは、CSS を使用してチャイニーズ ノットを実装するにはどうすればよいでしょうか? 最初に最終的な効果を見てみましょう。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

オンライン プレビュー Codepen アドレス:
https://codepen.io/cliea/pen/LYOPbBr

このような素晴らしいエフェクトを作成することもできます。早速始めてみましょう!

1. コーディングの前に

1. 材料を集めます。簡単なほど良いです。

まず、インターネットで中国結びの画像を検索します。スタイルは複数あります。チャイニーズノットの中でも、最も古典的なチャイニーズノットの織りスタイルの1つを選択します。 最終製品の品質は写真の品質によって決まりますが、以下は比較的きれいで鮮明な中国結びの写真です。 CSSを書く際の参考に。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

2. 詳細を観察し、実装の可能性を考える

画像を用意したので、コードを書き始めることができますか?もちろん違います。

まず、今何をしなければならないかを考えてください。CSS でチャイニーズノットを描画します。

本当に考えてみましたか?これは達成可能な目標ですか?リーダーがあなたにタスクを割り当てたときを想像してください。アプリのテーマカラーに合わせて電話ケースの色を変更します。コードを書き始めてみませんか?

あなたは 2 つの質問について考えます:

  • ソフトウェアとして、APP には携帯電話のケースと対話するためのインターフェイスがありますか?

  • 色の値を受け取った場合、携帯電話ケースの色はどのように変化しますか。

これは比較的極端な例であり、上記の 2 つの方法のどちらも実現できません。 CSS に戻って、この中国の結び目の画像を見てみましょう。最初に考える必要があるのは、この画像を実現するにはどの CSS テクニックを使用する必要があるかということです。さて、戻って上の写真をよく見てください。

短い観察の後、次のことがわかりました。 重要なポイント:

  • 中国結びのロープは次のように構成されています。濃い赤、薄い赤、濃い赤

  • 中央の主要部分は交差する22本のロープで構成されており、交差点を通過するたびに階層順序が入れ替わります。

  • いくつかのリング構造があり、色のグラデーションのプロセスは直線と同じです

  • 全体は赤で、黄色が入っています装飾

次に、##想像力##実装原理:

##線形カラーグラデーションを使用します
    linear-gradient
  • または

    repeat-linear-gradient

    リング グラデーション。
  • radial-gradient
  • を使用します。

    メッシュの交差には、
  • mask
  • マスクを使用して交差効果を実現します。

    4 分の 3 ループと 2 本の曲線ロープ下部で
  • clip-path
  • を使用します。 トリミングするには

    コーディングをより便利にするには、
  • SCSS
  • を使用します。

    多くの場所で使用できます
  • ::before
  • ::after 実装では、htmlcode##3 を削減します。構造を部分に分割する

  • 上記は技術的な観点からの全体的な観察ですが、次は全体の画像を分割し、最初にその
html

構造を決定します。

#中央のチェッカーボードのようなグリッド構造は html タグとして使用できます

  • # 周囲に 16 個の小さな半円を配置し、16 個のラベル配置を使用して

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

  • 2 つの 4 分の 3 の円をグループに入れ、同じスタイルを使用します。 2 番目は最初の
180deg

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

  • に基づいて回転されます<ul><li>2 つのクロスノットは同じスタイルなので、グループに配置されます</li></ul> <p><img src="https://img.php.cn/upload/image/416/367/771/164325081516452%E7%B4%94%E7%B2%8B%E3%81%AA%20CSS%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E4%B8%AD%E5%9B%BD%E3%81%AE%E7%B5%90%E3%81%B3%E7%9B%AE%E3%82%92%E6%8F%8F%E7%94%BB%E3%81%97%E3%80%81%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%8A%B9%E6%9E%9C%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%AE%B5%E9%9A%8E%E7%9A%84%E3%81%AB%E8%AA%AC%E6%98%8E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82" title="164325081516452純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。" alt="純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。"></p> <ul><li>上部の 3 つの小さな構造1 つのグループが配置され、外側のレイヤーの名前は <code>header

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

  • 左下の部分と右下の部分は非常に似ています。これも footer

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

という名前の 1 つのグループに配置されます。このようにして、html

の構造を取得します。
<div class="chinese-knot">
  <div class="grid"></div>
  <div class="ring-small">
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
    <i></i>
  </div>
  <div class="ring-big">
    <i><b></b></i>
    <i><b></b></i>
  </div>
  <div class="cross-node">
    <div class="node">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
    </div>
    <div class="node">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
    </div>
  </div>
  <div class="header">
    <i></i>
    <b></b>
    <span></span>
  </div>
  <div class="footer">
    <b></b>
    <b></b>
    <div class="tassels">
      <i></i>
      <i></i>
    </div>
  </div>
</div>

実際のエンコードでは、html 一度書いたわけではありませんが、何度も調整を繰り返した結果、上記のようになりました。

2. CSS はチャイニーズ ノット コンポーネントを 1 つずつ実装します

1. グリッド

グリッドの最終的な効果はひし形、つまり正方形が回転します45 度、最初に回転させずに、どのようになるかを確認します。

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

まず、ロープ##の幅を表す変数を設定します。 #、-- width に設定しましょう。このサイズは非常に重要です 重要、後続のすべてのサイズはこの幅に基づくため、後でグラフィック全体のサイズを調整できます。これを --width に変更します。

:root {
  --width: 1.7vh;
}

11 のロープが縦と横にあります。ロープ間の隙間はロープの幅の約 0.5 倍です。つまり、ロープの幅と高さはグリッドを取得できます。どちらもロープ幅の 11 0.5 * 10 = 16 倍なので、次のように記述できます。

:root {
  --width: 1.7vh;
  --grid-width: calc(var(--width) * 16);
}
.grid {
  width: var(--grid-width);
  height: var(--grid-width);
}

Add some Styles to

body to centerボックスに暗い背景

body{
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #1d1e22;
  overflow: hidden;
}

を追加し、次に白い背景色を

.grid に追加してテストします。

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。# #これで画面は正しくなります 中央に白い四角が表示されます 次に、白い背景を

11

ルート行: <pre class="brush:css;toolbar:false;">:root{ --width: 1.7vh; --red-1: #f40001; --red-2: #d40000; --red-3: #8c0703; --rope: var(--red-3), var(--red-2) calc(var(--width) * 0.25), var(--red-1) calc(var(--width) * 0.45), var(--red-1) calc(var(--width) * 0.55), var(--red-2) calc(var(--width) * 0.75), var(--red-3) var(--width); --grid-width: calc(var(--width) * 16); --bg-line: linear-gradient(90deg, var(--rope), transparent var(--width)) 0 0 / calc(var(--width) * 1.5) calc(var(--width) * 1.5); } .grid{ width: var(--grid-width); height: var(--grid-width); background: var(--bg-line); }</pre> のスタイルに変更すると、次の効果が得られます:

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。もしかしたら、少し混乱しているかもしれません。どうしたの?

物事を簡単にしましょう。まずグラデーションなしで赤い線を描きましょう:

.grid{
  background: linear-gradient(
    90deg, 
    var(--red-1), 
    var(--red-1) var(--width), 
    transparent var(--width)
  );
}

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。最初に線形グラデーション

linear-gradient

次に、回転角度を 90deg に設定し、左から右への勾配を付けて (デフォルトは下から上)、開始値を --red-1 (red-1 から red-3 がどこから来たのか尋ねられましたか?これはレンダリングから描画されました)、また、--width に設定されています。 --red-1 なので、幅 --width の赤い線が表示されます。しかし、これはまだ終わっていません。--width から右端まで塗りつぶされないように、透明な transpanrent--width に追加する必要があります。グラフィックの側面の色。 しかし、これはロープのようには見えないので、赤い線の勾配を付けます:

.grid{
  background: linear-gradient(
    90deg, 
    var(--red-3), 
    var(--red-2) calc(var(--width) * 0.25), 
    var(--red-1) calc(var(--width) * 0.45), 
    var(--red-1) calc(var(--width) * 0.55), 
    var(--red-2) calc(var(--width) * 0.75), 
    var(--red-3) var(--width), 
    transparent var(--width)
  );
}

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。こうすることで、小さな 3 の付いたロープが得られます。立体的な効果。しかし、

0.5

--width の間隔で、水平方向に 11 回繰り返すにはどうすればよいでしょうか?以下のコードを見てください: <pre class="brush:css;toolbar:false;">.grid{ background: linear-gradient( 90deg, var(--red-3), var(--red-2) calc(var(--width) * 0.25), var(--red-1) calc(var(--width) * 0.45), var(--red-1) calc(var(--width) * 0.55), var(--red-2) calc(var(--width) * 0.75), var(--red-3) var(--width), transparent var(--width) ) 0 0 / calc(var(--width) * 1.5) calc(var(--width) * 1.5); }</pre> 欠点を見つけてみましょう: このコードと前のコードの違いは何ですか?鋭い観察力のある方は、余分な行があることに気づいたかもしれません:

0 0 / calc(var(--width) * 1.5) calc(var(--width) * 1.5)

/

を境界線として、左側の意味は background-positoin です。 、右側の意味は background-size です。

0 0

は左上隅です。 calc(var(--width) * 1.5) calc(var(--width) * 1.5) は、ロープ幅の 1.5 倍の幅を持つ正方形です。

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。# このような小さな正方形を垂直方向と水平方向に繰り返すと、必要な結果が得られます。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。しかし、私たちが望んでいるのは

grid

であり、今ではせいぜい単なるグリッドにすぎません。 次に、疑似クラスを使用して

90deg

をコピーして回転します: <pre class="brush:css;toolbar:false;">:root{ --width: 1.7vh; --red-1: #f40001; --red-2: #d40000; --red-3: #8c0703; --rope: var(--red-3), var(--red-2) calc(var(--width) * 0.25), var(--red-1) calc(var(--width) * 0.45), var(--red-1) calc(var(--width) * 0.55), var(--red-2) calc(var(--width) * 0.75), var(--red-3) var(--width); --grid-width: calc(var(--width) * 16); --bg-line: linear-gradient(90deg, var(--rope), transparent var(--width)) 0 0 / calc(var(--width) * 1.5) calc(var(--width) * 1.5); } .grid { width: var(--grid-width); height: var(--grid-width); background: var(--bg-line); &amp;:after { content: &quot;&quot;; display: block; width: var(--grid-width); height: var(--grid-width); background: var(--bg-line); transform: rotate(90deg); } }</pre>

1純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。参照画像を比較します:

不能说完全不相干,但是人家一看就经过了能工巧匠的编织,咱们这只能算简单的叠加,怎么才能让上面变成下面呢?

经过仔细的观察,发现只要把上面一层横着的线,稍加一些遮挡就能实现交叉编织的效果。用哪个css属性实现呢?那就只有mask 了。

下图蓝色框是需要遮挡的部分,绿色框是需要重复的部分。

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

仔细分析一下绿框的构成:

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

本质上是在一个3×3的正方形上挖两个1×1的小洞,位置分别是0 01.5 1.5。我们要如何画这样一张图?并把这张图应用到mask上呢?

mask是通过传入的图片进行遮罩处理,而背景图除了传入一张png以外,CSS还内置了几个生成背景图的函数:

  • linear-gradient:线性渐变
  • repeating-linear-gradient:重复线性渐变
  • radial-gradient:径向渐变
  • conic-gradient:圆锥渐变

这些函数都可以和mask配合。这里我们使用conic-gradient实现上面的图形。

conic-gradient 实现上图,思路要反着来:不是在方形上挖孔,而是用多个矩形将要渲染的部分填充颜色,剩下的部分自然就是透明的:

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

CSS实现如下:

:root{
    ...
    --conic: #000 0 90deg, transparent 0 100%;
}

.grid {
  ...
  &:after {
    ...
    -webkit-mask: conic-gradient(from 0deg at var(--width) calc(var(--width) * 1.5), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 90deg at calc(var(--width) * 2.5) 0, var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 180deg at calc(var(--width) * 1.5) var(--width), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 90deg at 0 calc(var(--width) * 2.5), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3);
  }
}

预览效果

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

目前为止完整代码

:root{
  --width: 1.7vh;
  --red-1: #f40001;
  --red-2: #d40000;
  --red-3: #8c0703;
  --rope: 
    var(--red-3), 
    var(--red-2) calc(var(--width) * 0.25), 
    var(--red-1) calc(var(--width) * 0.45), 
    var(--red-1) calc(var(--width) * 0.55), 
    var(--red-2) calc(var(--width) * 0.75), 
    var(--red-3) var(--width);
  --grid-width: calc(var(--width) * 16);
  --bg-line: linear-gradient(90deg, var(--rope), transparent var(--width)) 0 0 / calc(var(--width) * 1.5) calc(var(--width) * 1.5);
  --conic: #000 0 90deg, transparent 0 100%;
}
body{
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #1d1e22;
  overflow: hidden;
}
.grid {
  width: var(--grid-width);
  height: var(--grid-width);
  background: var(--bg-line);
  &:after {
    content: "";
    display: block;
    width: var(--grid-width);
    height: var(--grid-width);
    background: var(--bg-line);
    transform: rotate(90deg);
    -webkit-mask: conic-gradient(from 0deg at var(--width) calc(var(--width) * 1.5), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 90deg at calc(var(--width) * 2.5) 0, var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 180deg at calc(var(--width) * 1.5) var(--width), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3),
      conic-gradient(from 90deg at 0 calc(var(--width) * 2.5), var(--conic)) 0 0 / calc(var(--width) * 3) calc(var(--width) * 3);
  }
}
<div class="grid"></div>

没错,这个图形,只用了.grid这一个标签!

但是只有网格还不够,让我们继续。

2. 半圆环

回头看一下参考图:

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

嗯,环形渐变,那就是radial-gradient了:

  <div class="ring-small">
    <i></i>
  </div>
.ring-small {
  i {
    position: absolute;
    width: calc(var(--width) * 2.5);
    height: calc(var(--width) * 1.5);
    background: radial-gradient(
        circle at 50% 100%, 
        transparent calc(var(--width) * 0.25), 
        var(--red-3) calc(var(--width) * 0.25), 
        var(--red-2) calc(var(--width) * (0.25 + 0.25)),
        var(--red-1) calc(var(--width) * (0.25 + 0.45)), 
        var(--red-1) calc(var(--width) * (0.25 + 0.55)), 
        var(--red-2) calc(var(--width) * (0.25 + 0.75)),
        var(--red-3) calc(var(--width) * (0.25 + 1)), 
        transparent calc(var(--width) * (0.25 + 1))
    );
  }
}

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

这样就得到了半个环形图,让我们使用定位把它和网格结合看看

/* 先给最外层加个相对定位,后面的绝对定位都相对这一层 */
.chinese-knot {
  width: var(--grid-width);
  height: var(--grid-width);
  position: relative;
}
.ring-small {
  i {
    position: absolute;
    top: calc(var(--width) * -1.5);
    left: calc(var(--width) * 3);
  }
}

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

对比素材图,发现环形不是直接紧贴在网格上的,而是先延伸了一小段直线,再接的曲线。那我们就给它增个高吧:

.ring-small {
  i {
    &:before,
    &:after {
      content: "";
      position: absolute;
      bottom: calc(var(--width) * -0.5 + 1px);
      width: var(--width);
      height: calc(var(--width) * 0.5);
      background: var(--bg-line);
    }
    &:after {
      right: 0;
    }
  }
}

上面使用两个伪类,为半圆环加了两截高度为 0.5--width的增高垫,效果如下图

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

接着复制16个这样的图形,分别定位到各自的位置上:

<div class="grid"></div>
<i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i> <i></i>
.ring-small {
  i {
    position: absolute;
    width: calc(var(--width) * 2.5);
    height: calc(var(--width) * 1.5);
    background: radial-gradient(
        circle at 50% 100%, 
        transparent calc(var(--width) * 0.25), 
        var(--red-3) calc(var(--width) * 0.25), 
        var(--red-2) calc(var(--width) * (0.25 + 0.25)),
        var(--red-1) calc(var(--width) * (0.25 + 0.45)), 
        var(--red-1) calc(var(--width) * (0.25 + 0.55)), 
        var(--red-2) calc(var(--width) * (0.25 + 0.75)),
        var(--red-3) calc(var(--width) * (0.25 + 1)), 
        transparent calc(var(--width) * (0.25 + 1))
    );
    &:before,
    &:after {
      content: "";
      position: absolute;
      bottom: calc(var(--width) * -0.5 + 1px);
      width: var(--width);
      height: calc(var(--width) * 0.5);
      background: var(--bg-line);
    }
    &:after {
      right: 0;
    }
    &:nth-child(-n + 4) {
      top: calc(var(--width) * -2 + 2px);
    }
    &:nth-child(1) {
      left: calc(var(--width) * 3);
    }
    &:nth-child(2) {
      left: calc(var(--width) * 6);
    }
    &:nth-child(3) {
      left: calc(var(--width) * 9);
    }
    &:nth-child(4) {
      left: calc(var(--width) * 12);
    }
    &:nth-child(-n + 8):nth-child(n + 5) {
      bottom: calc(var(--width) * -2 + 2px);
      transform: rotate(180deg);
    }
    &:nth-child(5) {
      left: calc(var(--width) * 1.5);
    }
    &:nth-child(6) {
      left: calc(var(--width) * 4.5);
    }
    &:nth-child(7) {
      left: calc(var(--width) * 7.5);
    }
    &:nth-child(8) {
      left: calc(var(--width) * 10.5);
    }
    &:nth-child(-n + 12):nth-child(n + 9) {
      left: calc(var(--width) * -2.5 + 2px);
      transform: rotate(-90deg);
    }
    &:nth-child(9) {
      top: calc(var(--width) * 3.5);
    }
    &:nth-child(10) {
      top: calc(var(--width) * 6.5);
    }
    &:nth-child(11) {
      top: calc(var(--width) * 9.5);
    }
    &:nth-child(12) {
      top: calc(var(--width) * 12.5);
    }
    &:nth-child(-n + 16):nth-child(n + 13) {
      right: calc(var(--width) * -2.5 + 2px);
      transform: rotate(90deg);
    }
    &:nth-child(13) {
      top: calc(var(--width) * 2);
    }
    &:nth-child(14) {
      top: calc(var(--width) * 5);
    }
    &:nth-child(15) {
      top: calc(var(--width) * 8);
    }
    &:nth-child(16) {
      top: calc(var(--width) * 11);
    }
  }
}

就得到了这样的效果

2純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

哈哈,很像下水管道~

3. 四分之三圆环

还是先看素材:

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

嗯,不得不怀疑网易云的 LOGO 的灵感是不是就是中国结。

30-純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

单个环形已经实现了,两个环也不难吧:

<div class="ring-big">
    <i><b></b></i>
</div>
.ring-big {
  i {
    position: absolute;
    width: calc(var(--width) * 6);
    height: calc(var(--width) * 6);
    b {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background: radial-gradient(
        circle at 50% 50%,
        transparent calc(var(--width) * 0.5),
        var(--red-3) calc(var(--width) * 0.5),
        var(--red-2) calc(var(--width) * (0.5 + 0.25)),
        var(--red-1) calc(var(--width) * (0.5 + 0.45)),
        var(--red-1) calc(var(--width) * (0.5 + 0.55)),
        var(--red-2) calc(var(--width) * (0.5 + 0.75)),
        var(--red-3) calc(var(--width) * (0.5 + 1)),
        transparent calc(var(--width) * (0.5 + 1)),
        transparent calc(var(--width) * 2),
        var(--red-3) calc(var(--width) * 2),
        var(--red-2) calc(var(--width) * (2 + 0.25)),
        var(--red-1) calc(var(--width) * (2 + 0.45)),
        var(--red-1) calc(var(--width) * (2 + 0.55)),
        var(--red-2) calc(var(--width) * (2 + 0.75)),
        var(--red-3) calc(var(--width) * (2 + 1)),
        transparent calc(var(--width) * (2 + 1))
      );
    }
  }
}

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

为什么 <i></i> 标签里要再套一个标签呢,因为接下来我们要执行 clip-path,还要给圆环增高,而clip-path 会给增高的部分也裁剪掉,所以只能再套一层,让内层的 <b></b> 自己 clip,增高则使用 <i></i> 的伪类实现。下面就是将圆环右下角 1/4 裁剪掉并且加一个增高垫的代码:

.ring-big {
  i {
    ...
    b {
      ...
      clip-path: polygon(0 0, 100% 0, 100% 50%, 50% 50%, 50% 100%, 0 100%);
    }
    &:before,
    &:after {
      content: "";
      position: absolute;
      top: calc(var(--width) * 3 - 1px);
      left: calc(var(--width) * 3.5);
      width: calc(var(--width) * 2.5);
      height: calc(var(--width) * 0.5 + 2px);
      background: repeating-linear-gradient(
        90deg, 
        var(--red-3), 
        var(--red-2) calc(var(--width) * 0.25), 
        var(--red-1) calc(var(--width) * 0.45), 
        var(--red-1) calc(var(--width) * 0.55), 
        var(--red-2) calc(var(--width) * 0.75), 
        var(--red-3) var(--width), 
        transparent var(--width), 
        transparent calc(var(--width) * 1.5)
      );
    }
    &:after {
      transform: rotate(90deg);
      transform-origin: left top;
      top: calc(var(--width) * 3.5);
      left: calc(var(--width) * 3.5 + 1px);
    }
  }
}

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

复制一份并定位:

.ring-big {
  i {
    ...
    &:nth-child(1) {
      left: calc(var(--width) * -3.5);
      top: calc(var(--width) * -3.5);
    }
    &:nth-child(2) {
      left: auto;
      top: auto;
      right: calc(var(--width) * -3.5);
      bottom: calc(var(--width) * -3.5);
      transform: rotate(180deg);
    }
  }
}

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

到这里,工作的一半就已经完成了~继续

4. 十字结

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

这个图形,相对于上面几个,已经没什么难度了,五个1×1 的正方形,中间的渐变方向和周围四个垂直。

中间的正方形,用父级本身实现,里面周围四个,用四个子<i></i>标签实现:

<div class="cross-node">
    <div class="node">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
    </div>
    <div class="node">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
    </div>
  </div>
.cross-node {
  .node {
    position: absolute;
    z-index: 2;
    width: var(--width);
    height: var(--width);
    background: var(--bg-line);
    i {
      position: absolute;
      width: var(--width);
      height: var(--width);
      background: var(--bg-line);
      transform: rotate(90deg);
      &:nth-child(1) {
        left: calc(var(--width) * -1);
      }
      &:nth-child(2) {
        left: var(--width);
      }
      &:nth-child(3) {
        top: calc(var(--width) * -1);
      }
      &:nth-child(4) {
        top: var(--width);
      }
    }
    &:nth-child(1) {
      right: calc(var(--width) * -1);
      top: calc(var(--width) * -1);
    }
    &:nth-child(2) {
      left: calc(var(--width) * -1);
      bottom: calc(var(--width) * -1);
    }
  }
}

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

5. 挂绳

前面我们都是让中国结处于一个斜躺的姿态,写头部和尾部之前,让我们先把它摆正:

.chinese-knot {
  ...
  transform: rotate(-45deg) translate(calc(var(--width) * 4), calc(var(--width) * -4));
}

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

回头看素材图:

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

先确定一下html结构:

<div class="header">
    <i></i>
    <b></b>
    <span></span>
</div>

i 是上面的吊绳,b 是圆环,span 是衔接处的短绳,带点黄色装饰。为了方便调整定位,我们从下往上实现,先写短绳:

:root {
  --yellow-1: #fced00;
  --yellow-2: #f28a00;
  --yellow-3: #da571b;
  --bg-yellow: linear-gradient(
    90deg,
    var(--yellow-3),
    var(--yellow-2) 20%,
    var(--yellow-1) 40%,
    var(--yellow-1) 60%,
    var(--yellow-2) 80%,
    var(--yellow-3) 100%
  );
}
.header {
  position: absolute;
  right: 0;
  top: 0;
  transform: rotate(45deg);
  i {
    position: absolute;
    bottom: calc(var(--width) * 1);
    left: calc(var(--width) * -0.5);
    width: calc(var(--width) * 1);
    height: calc(var(--width) * 2);
    background: var(--bg-line);
    &:before {
      content: "";
      display: block;
      height: calc(var(--width) * 0.5);
      background: var(--bg-yellow);
    }
  }
}

然后是圆环:

.header {
  ...
  b {
    position: absolute;
    bottom: calc(var(--width) * 3);
    left: calc(var(--width) * -1.5);
    width: calc(var(--width) * 3);
    height: calc(var(--width) * 3);
    background: radial-gradient(
      circle at 50%,
      transparent calc(var(--width) * 0.75),
      var(--red-3) calc(var(--width) * 0.75),
      var(--red-2) calc(var(--width) * (0.75 + 0.15)),
      var(--red-1) calc(var(--width) * (0.75 + 0.3)),
      var(--red-1) calc(var(--width) * (0.75 + 0.45)),
      var(--red-2) calc(var(--width) * (0.75 + 0.6)),
      var(--red-3) calc(var(--width) * (0.75 + 0.75)),
      transparent calc(var(--width) * (0.75 + 0.75))
    );
  }
}

最后是长的吊绳:

.header {
  ...
  span {
    position: absolute;
    bottom: calc(var(--width) * 5);
    left: calc(var(--width) * -0.25);
    width: calc(var(--width) * 0.5);
    height: calc(var(--width) * 30);
    background: linear-gradient(90deg, var(--red-2), var(--red-1) 20%, var(--red-2) 70%, var(--red-3));
    border-radius: calc(var(--width) * 0.25);
  }
}

单独效果

3純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

整体效果

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

6. 流苏

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

确定html结构:

<div class="footer">
    <b></b>
    <b></b>
    <div class="tassels">
      <i></i>
      <i></i>
    </div>
</div>

可以看到,流苏部分,有两个弯曲的 1/8 环,我们用两个b 标签来表示。这个形状依然还是先画一个完整的环,然后裁剪来实现:

.footer {
  position: absolute;
  left: 0;
  bottom: 0;
  b {
    position: absolute;
    width: calc(var(--width) * 15);
    height: calc(var(--width) * 15);
    background: radial-gradient(
      circle at 50%,
      transparent calc(var(--width) * 6.5),
      var(--red-3) calc(var(--width) * 6.5),
      var(--red-2) calc(var(--width) * (6.5 + 0.25)),
      var(--red-1) calc(var(--width) * (6.5 + 0.45)),
      var(--red-1) calc(var(--width) * (6.5 + 0.55)),
      var(--red-2) calc(var(--width) * (6.5 + 0.75)),
      var(--red-3) calc(var(--width) * (6.5 + 1)),
      transparent calc(var(--width) * (6.5 + 1))
    );
  }
}

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

加上裁剪并定位:

.footer {
  ...
  b {
    ...
    &:nth-child(1) {
      left: calc(var(--width) * -8.5);
      top: calc(var(--width) * 1);
      clip-path: polygon(50% 0, 50% 50%, 10% 0);
    }
    &:nth-child(2) {
      left: calc(var(--width) * -16);
      top: calc(var(--width) * -6.5);
      clip-path: polygon(100% 50%, 50% 50%, 100% 90%);
    }
  }
}

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

两个小尾巴就实现了。

最后是流苏。先画一下背景上的垂直细线,这里我们用 repeating-linear-gradient 实现,每隔 2px 画一条 1px 宽的透明度为 0.2 的黑线:

.footer {
  .tassels {
    i {
      position: absolute;
      width: calc(var(--width) * 2.5);
      height: calc(var(--width) * 14);
      background: var(--red-2) repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.2) 1px, transparent 1px, transparent 3px) 50% 50% / 3px 1px;}
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

再蒙上一层黄色的装饰:

.footer {
  .tassels {
    i {
      ...
      &:before {
        content: "";
        position: absolute;
        top: calc(var(--width) * 0.5);
        width: 100%;
        height: calc(var(--width) * 3.6);
        background: var(--bg-yellow);
        clip-path: polygon(0 0, 100% 0, 100% 10%, 0 10%, 0 15%, 100% 15%, 100% 85%, 0 85%, 0 90%, 100% 90%, 100% 100%, 0 100%, 0 0);
      }
  }
}

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

上面代码中使用 clip-path 对黄色背景裁剪,露出两条红线,裁剪路径可以用下图表示:

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

最终效果:

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

三、加点动画

本来到这里就应该结束了。但是我想让这个中国结有点实际用途,比如加点交互什么的。

红包也是春节的习俗之一,那就加一个拉一下中国结掉落红包雨的特效吧~

1. 拉一下

给中国结在:active状态下加个位移即可实现:

.chinese-knot {
  width: var(--grid-width);
  height: var(--grid-width);
  position: relative;
  transform: rotate(-45deg) translate(calc(var(--width) * 4), calc(var(--width) * -4));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: all 0.5s;
  &:active {
    transform: rotate(-45deg) translate(calc(var(--width) * 2), calc(var(--width) * -2));
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

2. 画个红包

先搜索一个红包素材:

4純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

观察一下红包结构,深红背景,浅红弧形开口,加一个黄色圆形封口,上面写着一个繁体的开字。

我们可以先确定 html 结构。.rain 作为外层,代表整个红包雨,一个i标签代表一个红包:

<div class="rain">
  <i></i>
</div>

一个标签怎么实现上面提到的三种元素呢?看代码:

.rain {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  i {
    position: relative;
    display: block;
    width: calc(var(--width) * 5);
    height: calc(var(--width) * 8);
    background: var(--red-3);
    border-radius: calc(var(--width) * 0.4);
    overflow: hidden;
    box-shadow: 0 calc(var(--width) * 1) calc(var(--width) * 1) rgba(0, 0, 0, 0.3);
    &:before {
      content: "";
      position: absolute;
      left: 50%;
      transform: translate(-50%, -50%);
      width: calc(var(--width) * 8);
      height: calc(var(--width) * 8);
      background: var(--red-1);
      opacity: 0.5;
      border-radius: 50%;
    }
    &:after {
      content: "開";
      position: absolute;
      left: 50%;
      transform: translate(-50%, 140%);
      width: calc(var(--width) * 2);
      height: calc(var(--width) * 2);
      background: var(--yellow-2);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-style: normal;
      font-size: calc(var(--width) * 0.5);
      color: var(--yellow-1);
      text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.1);
    }
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

使用i标签自身实现红包主体,:before 伪类实现弧形的开口,:after 伪类实现黄色圆形封口,在content中写上字。

一个红包完成了,再复制 9 个:

<div class="rain">
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
  <i></i>
</div>

5純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

这样就得到了 10 个固定在顶部,并且整齐排列的红包了。

3. 红包雨动画

下雨嘛,从上往下运动就好了:

.rain {
  ...
  i {
    ...
    animation: fall 3s ease-in infinite;
  }
}
@keyframes fall {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, 100vh);
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

聪明的你估计已经猜到了这样的结果:谁家的雨是这样齐刷刷的下来的?

那我们就红包的垂直位置错落一点,使用 sassrandom 函数来实现随机:

.rain {
  ...
  i {
    ...
    @for $i from 1 through 10 {
      &:nth-child(#{$i}) {
        top: random(60) + vh;
      }
    }
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

额,效果怎么和想象的不一样。依旧还是齐刷刷下落,只不过是"错落"的齐刷刷。

那我们让每个红包的开始时间也随机不就行了嘛:

.rain {
  ...
  i {
    ...
    @for $i from 1 through 10 {
      &:nth-child(#{$i}) {
        top: random(60) + vh;
        animation-delay: random(30) * 0.1s;
      }
    }
  }
}

5純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

嗯,好了一点点。但是有一个问题,屏幕上的雨点,有时候很多,有时候很少,不够均匀。那我们把动画的持续时间也随机会怎么样呢?

.rain {
  ...
  i {
    ...
    @for $i from 1 through 10 {
      &:nth-child(#{$i}) {
        top: random(60) + vh;
        animation-delay: random(30) * 0.1s;
        animation-duration: random(10) * 0.1s + 2s; /* 2s ~ 3s 之间随机 */
      }
    }
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

终于更像雨了~

但是现在雨滴是凭空出现的,很生硬,我们只要把开始的位置挪到负一屏,然后让它下落到正二屏就行了:

.rain {
  ...
  top: -100vh;
}
@keyframes fall {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, 200vh);
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

这样就有了源源不断下落的效果。

4. 拉一下触发红包雨

CSS 不是 JS ,怎么触发点击事件呢?

我们就要运用 CSS 本身的特性了,checkbox 复选框有个选中状态 :checked,而复选框可以用点击切换这个状态,再使用 CSS 的兄弟选择器 element ~ element 即可实现点击添加样式的效果。

样式可以触发了,那如何触发动画呢?

animation 属性添加到元素上后,播放状态默认是 running ,我们需要先把初始播放状态改为 paused (暂停), 然后通过上面的方法,把元素的播放状态改回 running 来实现播放动画的效果:

<input type="checkbox" id="switch">
<label class="chinese-knot" for="switch">...</label>
<div class="rain">...</div>
.rain {
  ...
  i {
    ...
    animation: fall 3s ease-in infinite;
    /* 默认不播放动画 */
    animation-play-state: paused;
  }
}

#switch {
  visibility: hidden;
  pointer-events: none;
}
/* checkbox 选中时播放动画 */
#switch:checked ~ .rain i {
  animation-play-state: running;
}
/* 点击时重置动画,否则取消checkbox选中状态,动画会中止并停留在当前位置 */
.chinese-knot:active ~ .rain i {
  animation: none;
}

上面的 html 中,我们让.chinese-knotdiv 改为 label 来指向 checkbox,方法是 labelforcheckboxid 设为相同的值。

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

效果很不错,我们再给红包雨下落时加个背景,以提醒用户当前的状态。并且下红包雨时,调低中国结的透明度,以突出红包的存在感。

<input type="checkbox" id="switch">
<div class="bg"></div>
<label class="chinese-knot" for="switch">...</label>
<div class="rain">...</div>
.bg {
  position: absolute;
  left: 0;
  top: 0;
  height: 100vh;
  width: 100vw;
  background: linear-gradient(0deg, #171a4b, #96367f);
  opacity: 0;
  transition: all 0.5s;
}
#switch:checked ~ .bg {
  opacity: 1;
}
#switch:checked ~ .chinese-knot {
  opacity: 0.2;
  &:hover {
    opacity: 0.5;
  }
}

純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。

完结撒花~~~

总结

这篇文章整理了我从搜集素材开始,创作一个作品的全部过程,代码写了一天,这篇文章写了半天。希望能让 CSS 初学者对 CSS 燃起兴趣,也希望让接触了一段时间 CSS 的朋友获得一些灵感和帮助。

(学习视频分享:css视频教程

以上が純粋な CSS を使用して中国の結び目を描画し、アニメーション効果を追加する方法を段階的に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。