按下右側的「點擊預覽」按鈕能夠在當前頁面預覽,點擊連接能夠全屏預覽。javascript
https://codepen.io/comehope/pen/yRYOwqcss
此視頻是能夠交互的,你能夠隨時暫停視頻,編輯視頻中的代碼。html
請用 chrome, safari, edge 打開觀看。前端
https://scrimba.com/p/pEgDAM/cBZ3Nt6java
每日前端實戰系列的所有源代碼請從 github 下載:git
https://github.com/comehope/front-end-daily-challengesgithub
定義 dom,容器中包含 1 個 .square
子容器,子容器中包含 4 個 <span>
,每一個 <span>
表明一個對角扇形:chrome
<figure class="container"> <div class="square"> <span></span> <span></span> <span></span> <span></span> </div> </figure>
居中顯示:app
body { margin: 0; height: 100vh; display: flex; align-items: center; justify-content: center; background-color: #222; }
設置容器的尺寸單位,1em
等於 8px
:dom
.container { font-size: 8px; }
子容器中的 4 個 <span>
不設寬高,只設邊框,其中第 1 個和第 4 個 <span>
只取左右邊框,第 2 個和第 3 個 <span>
只取上下邊框:
.square span { display: block; border: 2.5em solid transparent; color: #ddd; } .square span:nth-child(1), .square span:nth-child(4) { border-left-color: currentColor; border-right-color: currentColor; } .square span:nth-child(2), .square span:nth-child(3) { border-top-color: currentColor; border-bottom-color: currentColor; }
把邊框改成圓弧:
.square span { border-radius: 50%; }
在子容器中用 grid 佈局把 4 個 <span>
設置爲 2 * 2 的網格:
.square { display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 0.2em; padding: 0.1em; }
旋轉 4 個 <span>
,使它們圍合成一個正方形,看起來像一個花朵,算式的結果是 45 度,寫成這樣是爲了和接下來的動畫的算式的形式保持一致:
.square span { transform: rotate(calc(45deg + 90deg * 0)); }
增長讓 <span>
旋轉的動畫,整個動畫過程旋轉 4 次,每次旋轉 90 度,4 次旋轉以後即返回原位:
.square span { animation: rotation 2s ease-in-out infinite; } @keyframes rotation { 0% { transform: rotate(calc(45deg + 90deg * 0)); } 25% { transform: rotate(calc(45deg + 90deg * 1)); } 50% { transform: rotate(calc(45deg + 90deg * 2)); } 75% { transform: rotate(calc(45deg + 90deg * 3)); } 100% { transform: rotate(calc(45deg + 90deg * 4)); } }
使其中 2 個 <span>
朝相反的方向運動:
.square span:nth-child(2), .square span:nth-child(3) { animation-direction: reverse; }
至此,一個 .square
子容器的動畫已經完成,接下來製做 4 個 .square
的動畫。
在 dom 中再增長 3 組 .square
子容器:
<figure class="container"> <div class="square"> <span></span> <span></span> <span></span> <span></span> </div> <div class="square"> <span></span> <span></span> <span></span> <span></span> </div> <div class="square"> <span></span> <span></span> <span></span> <span></span> </div> <div class="square"> <span></span> <span></span> <span></span> <span></span> </div> </figure>
用 grid 佈局把 4 個 .square
佈局成網格狀,變量 --columns
是網格的邊長,即每邊有 2 個 .square
子容器:
.container { display: grid; --columns: 2; grid-template-columns: repeat(var(--columns), 1fr); }
如今看起來好像是有幾個黑色的小方塊在不停地移動,當 dom 元素越多時,動畫效果看起來就越壯觀,就像集體舞同樣,人越多越有氣勢。接下來用 d3 批量增長 dom 的元素。
引入 d3 庫:
<script src="https://d3js.org/d3.v5.min.js"></script>
聲明一個 COLUMNS
常量,表示網格的邊長:
const COLUMNS = 2;
刪除掉 html 文件中的 .square
子元素,改成用 d3 動態建立:
d3.select('.container') .selectAll('div') .data(d3.range(COLUMNS * COLUMNS)) .enter() .append('div') .attr('class', 'square');
繼續用連綴語法增長 <span>
子元素:
d3.select('.container') .selectAll('div') .data(d3.range(COLUMNS * COLUMNS)) .enter() .append('div') .attr('class', 'square') .selectAll('span') .data(d3.range(4)) .enter() .append('span');
刪除掉 css 文件中的 --columns
變量聲明,改成用 d3 動態聲明:
d3.select('.container') .style('--columns', COLUMNS) /*略*/
最後,把邊長改成 4,即讓 16 個 .square
一塊兒動畫:
const COLUMNS = 4;
大功告成!