如何使用CSS和D3實現小魚遊動的互動動畫(附代碼)

來源:互聯網
上載者:User
本篇文章給大家帶來的內容是關於如何使用CSS和D3實現小魚遊動的互動動畫(附代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。

效果預覽

原始碼下載

https://github.com/comehope/front-end-daily-challenges

代碼解讀

定義 dom,容器中包含的子項目分別代表魚的身體、眼睛、背鰭和尾巴:

<div class="fish">    <span class="body"></span>    <span class="eye"></span>    <span class="fin"></span>    <span class="tail"></span></div>

設定頁面樣式為全屏且沒有捲軸:

body {    margin: 0;    width: 100vw;    height: 100vh;    background-color: #222;    overflow: hidden;}

定義魚的容器尺寸,--r 是一個基本尺寸單位,後續所有尺寸都是基於它計算的:

.fish {    position: absolute;    --r: 15vw;    width: calc(var(--r) + var(--r) / 3);    height: calc(var(--r) * 2);    left: 50%;    top: 100px;}

畫出魚的身體,同時把魚的顏色聲明到父類中,因為下面還會用到這個顏色:

.fish {    color: hsl(0, 50%, 50%);}.fish .body {    position: absolute;    border: var(--r) solid transparent;    border-right-color: currentColor;    border-left-style: none;}

畫出魚的眼睛:

.fish .eye {    position: absolute;    --r1: calc(var(--r) / 4);    width: var(--r1);    height: var(--r1);    background-color: #111;    border-radius: 50%;    top: 35%;    left: 30%;}

畫出魚的背鰭:

.fish .fin {    position: absolute;    --r2: calc(var(--r) / 2);    border-bottom: var(--r2) solid;    border-left: var(--r2) solid transparent;    filter: brightness(2.5);    left: calc(var(--r) - var(--r2));}

畫出魚的尾巴:

.fish .tail {    position: absolute;    --r3: calc(var(--r) / 3);    border: var(--r3) solid transparent;    border-right-color: currentColor;    border-left-style: none;    right: 0;    top: calc(var(--r) - var(--r3));}

增加讓魚遊動的動畫效果,不是迴圈執行,而是只執行一次:

.fish {    right: calc(var(--r) * -1);    animation: run 3s linear forwards;}@keyframes run {    to {        right: 100%;    }}

再增加魚遊動時搖擺的動畫效果:

.fish {    animation:         run 3s linear forwards,        shake 0.3s linear infinite;}@keyframes shake {    50% {        transform: rotateY(-30deg);    }    100% {        transform: rotateY(30deg);    }}

接下來設定一些變數,以便建立不同樣子的魚:

魚的大小的變數 --size,數值越大尺寸越大:

.fish {    --size: 5;    --r: calc(var(--size) * 1vw);}

魚的顏色變數 --color,表示色相環的角度:

.fish {    --color: 0;    color: hsl(var(--color), 50%, 50%);}

魚從右側遊到左側的時間長度,時間長度越短遊得越快:

.fish {    --duration: 3;    animation:         run calc(var(--duration) * 1s) linear forwards,        shake 0.3s linear infinite;}

魚出現的高度,資料越大越靠近頁面下部:

.fish {    --top: 100;    top: calc(var(--top) * 1px);}

接下來用 d3 來批量處理 dom 元素和 css 變數。
引入 d3 庫:

<script src="https://d3js.org/d3.v5.min.js"></script>

刪除掉 html 中的 .fish 元素和 css 檔案中的變數聲明代碼。建立一個函數,用於產生一條魚。css 變數的值均為隨機產生,--size 的取值範圍是 5 ~ 8,--color 的取值範圍是 -60 ~ 15,--duration 的取值範圍是 3 ~ 6,--top 的取值範圍是 100 ~ 300:

function buildFish() {    let fish = d3.select('body')        .append('p')        .attr('class', 'fish')        .style('--size', d3.randomUniform(5, 8)())        .style('--color', d3.randomUniform(-60, 15)())        .style('--duration', d3.randomUniform(3, 6)())        .style('--top', d3.randomUniform(100, 300)());        fish.append('span').attr('class', 'body');    fish.append('span').attr('class', 'eye');    fish.append('span').attr('class', 'fin');    fish.append('span').attr('class', 'tail');}

綁定按一下滑鼠事件,當按下滑鼠時就產生一條魚:

function buildFish(e) {    //略....    .style('--top', e.clientY);}window.addEventListener('click', buildFish);

並且讓魚的嘴部和點擊的位置在一條水平線上:

.fish {    top: calc(var(--top) * 1px - var(--r));}

最後,在頁面載入時自動產生 3 條魚,以免頁面載入後一片空白:

function buildFish(e) {    //略....    .style('--top', e ? e.clientY : d3.randomUniform(100, 300)());}d3.range(3).forEach(buildFish);

大功告成!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.