前言
无论是在web端还是app端,当页面内需要请求网络资源或者执行比较耗时的操作的时候,都应该显示一个加载中的状态,以获得更好的用户体验。本文主要基于Vue,讲解IOS原生Loading效果的实现原理。
效果图
资源地址
1. 演示地址(gitee)
2. 演示地址(github)
3. Github代码地址
安装
- npm安装plain-loading
npm i plain-loading -S
- 使用plain-loading
import Vue from 'vue' import PlainLoading from 'plain-loading' import 'plain-loading/dist/PlainLoading.css' Vue.use(PlainLoading)
<pl-loading/>
- 更多使用方式请看:npm
原理解析
html源码
<template>
<div class="pl-loading-alpha" :class="[`pl-loading-alpha-color-${color}`]">
<span class="pl-loading-alpha-tag"><span class="pl-loading-tag" v-for="i in [1,2,3,4,5,6,7,8,9,10,11,12]" :key="i"></span></span>
</div>
</template>
scss源码
.pl-loading-alpha {
display: inline-block;
vertical-align: middle;
$size: plVar(icon-size);
height: $size;
width: $size;
.pl-loading-alpha-tag {
$centerRadius: (0.5*$size)/1.2;
$itemWidth: (0.35*$size)/1.2;
$itemHeight: (0.1*$size)/1.2;
$width: $centerRadius + $itemWidth * 2;
$height: $width;
width: $width;
height: $height;
position: relative;
display: block;
.pl-loading-tag {
display: inline-block;
width: $itemWidth;
height: $itemHeight;
margin-top: $itemHeight / 2 * -1;
margin-left: $centerRadius / 2;
top: 50%;
left: 50%;
position: absolute;
transform-origin: ($centerRadius / 2 * -1) ($itemHeight / 2);
border-radius: 1px;
@for $i from 1 through 12 {
&:nth-child(#{$i}) {
transform: rotate(($i - 1) * 30deg);
animation: pl-loading-alpha-tag 1s linear infinite #{-1 + $i / 12}s;
}
}
@keyframes pl-loading-alpha-tag {
0% {
opacity: 1;
}
@for $i from 1 through 11 {
#{$i / 12 * 100}% {
opacity: 1 - $i / 12;
}
}
100% {
opacity: 1;
}
}
}
}
@include pl-colors(pl-loading-alpha) {
.pl-loading-tag {
background-color: $colorDeep;
}
}
&.pl-loading-alpha-color-white {
.pl-loading-tag {
background-color: white;
}
}
}
解析
- 首先需要有一个父元素:pl-loading-alpha-tag,然后在这个父元素节点下创建12个子元素;
- 父元素相对定位,子元素绝对定位,通过设置top,margin-top,left以及margin-left调整子元素在父元素中的位置,这时候,所有子元素的位置都是在同一个位置,是重叠的;
- 设置子元素的transform-origin为:( c e n t e r R a d i u s / 2 ∗ − 1 ) ( centerRadius / 2 * -1) ( centerRadius/2∗−1)(itemHeight / 2),这个位置为父元素的中间位置,然后依序设置每个子元素的旋转角度,这样所有子元素就散开变成了一朵花形状;
- 设置一个透明度变化动画animation:
@keyframes pl-loading-alpha-tag { 0% { opacity: 1; } @for $i from 1 through 11 { #{$i / 12 * 100}% { opacity: 1 - $i / 12; } } 100% { opacity: 1; } }
- 设置每个子元素都使用这个动画,但是每个子元素的动画都有一定的延迟,序号越大的子元素延迟越大:
@for $i from 1 through 12 { &:nth-child(#{$i}) { transform: rotate(($i - 1) * 30deg); animation: pl-loading-alpha-tag 1s linear infinite #{-1 + $i / 12}s; } }