This article brings you the content is about how to use CSS and D3 to achieve small fish swimming interactive animation (with code), there is a certain reference value, the need for a friend can refer to, I hope you have some help.
Effect Preview
Source code Download
Https://github.com/comehope/front-end-daily-challenges
Code interpretation
Defines the DOM, which contains child elements that represent the body, eyes, dorsal fin, and tail of the fish, respectively:
<div class= "Fish" > <span class= "Body" ></span> <span class= "Eye" ></span> <span class= "Fin" ></span> <span class= "tail" ></span></div>
To set the page style to full screen and no scroll bars:
body { margin:0; WIDTH:100VW; HEIGHT:100VH; Background-color: #222; Overflow:hidden;}
The container size of the fish --r
is defined as a unit of basic dimensions, and all subsequent dimensions are calculated based on it:
. fish { position:absolute; --R:15VW; Width:calc (Var (--r) + VAR (--r)/3); Height:calc (VAR (--r) * 2); left:50%; top:100px;}
Draw the body of the fish and declare the color of the fish in the parent class, as the following will also use this color:
. Fish { COLOR:HSL (0, 50%, 50%);}. Fish. body { position:absolute; Border:var (--R) solid transparent; Border-right-color:currentcolor; Border-left-style:none;}
To draw the eyes of a fish:
. 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%;}
Draw the dorsal fin of a fish:
. 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));}
To draw the tail of a fish:
. 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));}
Increase the animation effect that lets the fish swim, not loop execution, but only once:
. Fish { Right:calc (var (--r) *-1); Animation:run 3s linear forwards;} @keyframes Run {to { right:100%; }}
Then increase the animation effect of the swing when the fish swim:
. Fish { Animation: run 3s linear forwards, shake 0.3s linear Infinite;} @keyframes Shake { 50% { transform:rotatey ( -30deg); } 100% { Transform:rotatey (30deg); }}
Next, set up some variables to create fish of different looks:
The size of the fish variable, the larger the size of the larger --size
:
. fish { --size:5; --r:calc (VAR (--size) * 1vw);}
The color variable of the fish that --color
represents the angle of the hue ring:
. fish { --color:0; COLOR:HSL (Var (--color), 50%, 50%);}
The fish swims from the right to the left, and the shorter the length, the faster it swims:
. fish { --duration:3; Animation: Run Calc (var (--duration) * 1s) linear forwards, shake 0.3s linear Infinite;}
The height of the fish appears, the larger the data is closer to the lower part of the page:
. fish { --top:100; Top:calc (VAR (--top) * 1px);}
Next, use D3 to bulk process DOM elements and CSS variables.
Introducing the D3 Library:
<script src= "Https://d3js.org/d3.v5.min.js" ></script>
Delete the element in the HTML .fish
and the variable declaration code in the CSS file. Create a function that is used to generate a fish. CSS variable values are randomly generated, the value range is --size
5 ~ 8, the range is --color
-60 ~, the value range --duration
is 3 ~ 6, --top
the value range is 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, a) ()) . Style ('--duration ', D3.randomuniform (3, 6) ()) . Style ('--top ', D3.randomuniform ()); Fish.append (' span '). attr (' class ', ' body '); Fish.append (' span '). attr (' class ', ' eye '); Fish.append (' span '). attr (' class ', ' fin '); Fish.append (' span '). attr (' class ', ' tail ');}
Binds a mouse click event to generate a fish when the mouse is pressed:
function Buildfish (e) { ///slightly ..... Style ('--top ', E.clienty);} Window.addeventlistener (' click ', Buildfish);
And let the mouth of the fish and the position of the click on a horizontal line:
. Fish { Top:calc (var (--top) * 1px-var (--r));}
Finally, 3 fish are automatically generated when the page is loaded, so that the page is empty after loading:
function Buildfish (e) { ///slightly ..... Style ('--top ', E? E.clienty:d3.randomuniform (100, 300) ());} D3.range (3). ForEach (Buildfish);
Done!