效果展示
Demo代碼
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<section><span></span></section>
</body>
</html>
CSS
html, body {
margin: 0;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background: #263238;
}
section {
width: 650px;
height: 300px;
padding: 10px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
/* 紅色邊框僅作提示 */
border: 2px solid red;
}
span {
width: 96px;
height: 96px;
display: inline-block;
position: relative;
color: white;
animation: rotation 1s linear infinite;
}
span::before, span::after {
content: '';
position: absolute;
width: 48px;
height: 48px;
top: 50%;
left: 50%;
transform: scale(0.5) translate(0, 0);
background-color: white;
border-radius: 50%;
animation: animloader 2s infinite ease-in-out;
}
span::before {
background-color: red;
transform: scale(0.5) translate( -96px, -96px);
}
@keyframes rotation {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(360deg)
}
}
@keyframes animloader {
50% {
transform: scale(1) translate(-50%, -50%)
}
}
原理詳解
步驟1
使用span標簽啦桌,設置為
- 寬度、高度均為96px
- 背景色:quamarine(這里只是為了先顯示span及皂,后面會刪除的)
- 相對定位
span {
width: 96px;
height: 96px;
position: relative;
background-color: aquamarine;
}
效果圖如下
步驟2
使用span::before甫男、span::after偽類元素
設置
- 絕對定位(top:50% left:50%)
- 寬度、高度均為48px
- 背景色:白色
span::before, span::after {
content: '';
position: absolute;
width: 48px;
height: 48px;
top: 50%;
left: 50%;
background-color: white;
}
效果圖如下
步驟3
將span::before验烧、span::after同比例縮小為原來的50%
transform: scale(0.5) ;
效果圖如下
步驟4
分離span::before板驳、span::after
再對span::before進行設置
- 背景色變?yōu)榧t色
- 向左上角移動
span::before {
background-color: red;
/*這里有點需要注意*/
/*下面代碼并不是先縮小50% 再左移、上移96px*/
/*而是縮小50% 再左移碍拆、上移48px*/
transform: scale(0.5) translate( -96px, -96px);
}
效果圖如下
步驟5
對span::before若治、span::after圓角化
border-radius: 50%;
效果圖如下
步驟6
取消span背景色
效果圖如下
步驟7
為span::before、span::after添加動畫
動畫需要實現(xiàn)的效果
- 紅色小球向右下角移動 白色小球向左上角移動 倔监,在原兩小球距離中間點重合直砂,然后再原路返回
- 初始大小為0.5 再不斷變大 到重合的位置為1 (相對于原大小)浩习,然后再逆向變化
span::before, span::after {
animation: animloader 2s infinite ease-in-out;
}
@keyframes animloader {
50% {
transform: scale(1) translate(-50%, -50%)
}
}
效果圖如下(僅該動畫生效時)
動畫理解
對于白球來說
- 開始(0%) 是位于translate(0, 0)静暂,也就是不移動,待在原來位置谱秽;
- 50% 時位于translate(-50%, -50%)洽蛀,也就是向左移摹迷、上移相對于自身寬度(或高度)的50%,也就是左移郊供、上移24px峡碉;
- 100%時,又回到原位置
對于紅球來說
- 開始(0%) 由ranslate(0, 0)的位置移動至驮审;ranslate(-96px, -96px)鲫寄,也就是已經(jīng)左移、上移96px疯淫;
- 50% 時位于translate(-50%, -50%)地来,意思是相對于translate(0, 0)的位置,只需要左移熙掺、上移自身的50%未斑,也就是24px;
- 100%時币绩,又回到原位置
記住translate(-50%, -50%)執(zhí)行時蜡秽,參照的是元素的最開始的位置
步驟8
為span添加動畫
- 順時針旋轉(zhuǎn)(0-360度) 無限循環(huán)
效果圖如下(僅該動畫生效時)
步驟9
將步驟8、步驟9的動畫同時疊加
效果圖如下
疑點
步驟4中的 transform: scale(0.5) translate( -96px, -96px);
為什么實際只移動了48px缆镣?
這里海轟還是有一點點的懵 芽突, 不是非常確定真正的理由是什么
下面就說說自己的理解吧
首先,若執(zhí)行 transform: scale(1) translate( -96px, -96px);
注:span邊長為96px 费就, 紅色诉瓦、白色部分邊長為48px
原after不縮放的情況下
當原after縮放50%時
我們可以發(fā)現(xiàn)
對于span::before, span::after中設置的縮放不影響之后單獨對before設置的影響
代碼的執(zhí)行原理
執(zhí)行 transform: scale(.5) translate( -96px, -96px);
(原after不縮放時)
可以理解為
scale(.5) 不僅對圖像的大小進行了縮放,還對translate( -96px, -96px);進行了等比例的縮放
也就是實際左移力细、上移都是48px
然后再執(zhí)行 scale(.5)對原來圖像的縮放
不知道這樣理解對不對~