【Html】Html+Less实现一个简单的加载动画

效果

在这里插入图片描述

运行环境

  • 系统:Win10系统
  • IDE:Visual Studio Code v1.79.2
  • VSCode插件:Easy LESS v2.0.0

index.html代码

<!DOCTYPE html>
<html>
    <head>
        <title>加载动画</title>
        <link rel="stylesheet" href="./index.css">
    </head>
    <body>
        <div class="loading">
            <!--Emmet 缩写 div.dot-->
            <!--Emmet 缩写 div.dot*36-->
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
        </div>
    </body>
</html>

index.less

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background: #66c7f4;
}

@ballSize: 10px;
//@halfBallSize: 5px;
@containerSize: 150px;
//@halfContainerSize: 75px;
@n:36;
@ani-diratoion:2000ms;
// @pdeg:360deg/@n;
// 当前less编译器不支持 混合运算如 360deg /36 | 150px/2
@pdeg:15deg;
.loading {
    width: @containerSize;
    height: @containerSize;
    margin: 50px auto;
    position: relative;
    //矩形倒角占比 - 50%为椭圆,长宽一样为圆
    border-radius: 50%;
    //与圆圈的颜色
    //outline: 1px solid #fff;

    .dot {
        //绝对位置
        position: absolute;
        left: 50%;
        top: 50%;
        //方块的宽度
        width: @ballSize;
        //方块的宽度
        height: @ballSize;
        margin-left: -(@ballSize/2);
        margin-top: -(@ballSize/2);
        //景深
        perspective: 70px;
        //景深-加强3D效果
        transform-style: preserve-3d;
        //方块的颜色
        //background: red;
         //黑白球的共有样式
        &::before,&::after{
            content: '';
            position: absolute;
            width: 100%;
            height: 100%;
            //矩形倒角占比 - 50%为椭圆,长宽一样为圆
            border-radius: 50%;
        }
        //黑色小球样式
        &::before{
            background: #000;
            top: -100%;
            animation: moveBlack @ani-diratoion infinite;
        }
        //白色小球样式
        &::after{
            background: #fff;
            top: 100%;
            animation: moveWhite @ani-diratoion infinite;
        }
    }
 
}

// 黑球动画
@keyframes moveBlack {
    0%{
        animation-timing-function: ease-in;
    }
    25%{
        transform: translate3d(0, 100% ,@ballSize);
        animation-timing-function: ease-out;
    }
    50%{
        transform: translate3d(0, 200% ,0);
        animation-timing-function: ease-in;
    }
    75%{
        transform: translate3d(0, 100% ,-@ballSize);
        animation-timing-function: ease-out;
    }
}
// 白球球动画
@keyframes moveWhite {
    0%{
        animation-timing-function: ease-in;
    }
    25%{
        transform: translate3d(0, -100% ,-@ballSize);
        animation-timing-function: ease-out;
    }
    50%{
        transform: translate3d(0, -200% ,0);
        animation-timing-function: ease-in;
    }
    75%{
        transform: translate3d(0, -100% ,@ballSize);
        animation-timing-function: ease-out;
    }
}

//循环生成 n 个黑白球
.loop(@i) when(@i<=@n){
    //获取第i个dot元素
    .dot:nth-child(@{i}){
       //transform: rotate(@pdeg * @i) translateY(-@halfContainerSize);
       //每个黑白球 设置旋转角度和Y方向便宜值
       transform: rotate(@pdeg * @i) translateY(-(@containerSize/2));
        //每个黑白球的动画启动延迟
        &::before, &::after{
            animation-delay: -((@ani-diratoion/@n) * 6 * @i);
        }
    }
    //递归调用
    .loop(@i+1);
}
.loop(1);
/*
.dot:nth-child(1) {
    transform: rotate(@pdeg) translateY(-@halfContainerSize);
}
.dot:nth-child(2) {
    transform: rotate(@pdeg*2) translateY(-@halfContainerSize);
}
.dot:nth-child(3) {
    transform: rotate(@pdeg*3) translateY(-@halfContainerSize);
}
*/

index.css

此文件有index.less 通过 less编译器自动生成,html中引用了此文件

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background: #66c7f4;
}
.loading {
  width: 150px;
  height: 150px;
  margin: 50px auto;
  position: relative;
  border-radius: 50%;
}
.loading .dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  margin-top: -5px;
  perspective: 70px;
  transform-style: preserve-3d;
}
.loading .dot::before,
.loading .dot::after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}
.loading .dot::before {
  background: #000;
  top: -100%;
  animation: moveBlack 2000ms infinite;
}
.loading .dot::after {
  background: #fff;
  top: 100%;
  animation: moveWhite 2000ms infinite;
}
@keyframes moveBlack {
  0% {
    animation-timing-function: ease-in;
  }
  25% {
    transform: translate3d(0, 100%, 10px);
    animation-timing-function: ease-out;
  }
  50% {
    transform: translate3d(0, 200%, 0);
    animation-timing-function: ease-in;
  }
  75% {
    transform: translate3d(0, 100%, -10px);
    animation-timing-function: ease-out;
  }
}
@keyframes moveWhite {
  0% {
    animation-timing-function: ease-in;
  }
  25% {
    transform: translate3d(0, -100%, -10px);
    animation-timing-function: ease-out;
  }
  50% {
    transform: translate3d(0, -200%, 0);
    animation-timing-function: ease-in;
  }
  75% {
    transform: translate3d(0, -100%, 10px);
    animation-timing-function: ease-out;
  }
}
.dot:nth-child(1) {
  transform: rotate(15deg) translateY(-75px);
}
.dot:nth-child(1)::before,
.dot:nth-child(1)::after {
  animation-delay: -333.33333333ms;
}
.dot:nth-child(2) {
  transform: rotate(30deg) translateY(-75px);
}
.dot:nth-child(2)::before,
.dot:nth-child(2)::after {
  animation-delay: -666.66666667ms;
}
.dot:nth-child(3) {
  transform: rotate(45deg) translateY(-75px);
}
.dot:nth-child(3)::before,
.dot:nth-child(3)::after {
  animation-delay: -1000ms;
}
.dot:nth-child(4) {
  transform: rotate(60deg) translateY(-75px);
}
.dot:nth-child(4)::before,
.dot:nth-child(4)::after {
  animation-delay: -1333.33333333ms;
}
.dot:nth-child(5) {
  transform: rotate(75deg) translateY(-75px);
}
.dot:nth-child(5)::before,
.dot:nth-child(5)::after {
  animation-delay: -1666.66666667ms;
}
.dot:nth-child(6) {
  transform: rotate(90deg) translateY(-75px);
}
.dot:nth-child(6)::before,
.dot:nth-child(6)::after {
  animation-delay: -2000ms;
}
.dot:nth-child(7) {
  transform: rotate(105deg) translateY(-75px);
}
.dot:nth-child(7)::before,
.dot:nth-child(7)::after {
  animation-delay: -2333.33333333ms;
}
.dot:nth-child(8) {
  transform: rotate(120deg) translateY(-75px);
}
.dot:nth-child(8)::before,
.dot:nth-child(8)::after {
  animation-delay: -2666.66666667ms;
}
.dot:nth-child(9) {
  transform: rotate(135deg) translateY(-75px);
}
.dot:nth-child(9)::before,
.dot:nth-child(9)::after {
  animation-delay: -3000ms;
}
.dot:nth-child(10) {
  transform: rotate(150deg) translateY(-75px);
}
.dot:nth-child(10)::before,
.dot:nth-child(10)::after {
  animation-delay: -3333.33333333ms;
}
.dot:nth-child(11) {
  transform: rotate(165deg) translateY(-75px);
}
.dot:nth-child(11)::before,
.dot:nth-child(11)::after {
  animation-delay: -3666.66666667ms;
}
.dot:nth-child(12) {
  transform: rotate(180deg) translateY(-75px);
}
.dot:nth-child(12)::before,
.dot:nth-child(12)::after {
  animation-delay: -4000ms;
}
.dot:nth-child(13) {
  transform: rotate(195deg) translateY(-75px);
}
.dot:nth-child(13)::before,
.dot:nth-child(13)::after {
  animation-delay: -4333.33333333ms;
}
.dot:nth-child(14) {
  transform: rotate(210deg) translateY(-75px);
}
.dot:nth-child(14)::before,
.dot:nth-child(14)::after {
  animation-delay: -4666.66666667ms;
}
.dot:nth-child(15) {
  transform: rotate(225deg) translateY(-75px);
}
.dot:nth-child(15)::before,
.dot:nth-child(15)::after {
  animation-delay: -5000ms;
}
.dot:nth-child(16) {
  transform: rotate(240deg) translateY(-75px);
}
.dot:nth-child(16)::before,
.dot:nth-child(16)::after {
  animation-delay: -5333.33333333ms;
}
.dot:nth-child(17) {
  transform: rotate(255deg) translateY(-75px);
}
.dot:nth-child(17)::before,
.dot:nth-child(17)::after {
  animation-delay: -5666.66666667ms;
}
.dot:nth-child(18) {
  transform: rotate(270deg) translateY(-75px);
}
.dot:nth-child(18)::before,
.dot:nth-child(18)::after {
  animation-delay: -6000ms;
}
.dot:nth-child(19) {
  transform: rotate(285deg) translateY(-75px);
}
.dot:nth-child(19)::before,
.dot:nth-child(19)::after {
  animation-delay: -6333.33333333ms;
}
.dot:nth-child(20) {
  transform: rotate(300deg) translateY(-75px);
}
.dot:nth-child(20)::before,
.dot:nth-child(20)::after {
  animation-delay: -6666.66666667ms;
}
.dot:nth-child(21) {
  transform: rotate(315deg) translateY(-75px);
}
.dot:nth-child(21)::before,
.dot:nth-child(21)::after {
  animation-delay: -7000ms;
}
.dot:nth-child(22) {
  transform: rotate(330deg) translateY(-75px);
}
.dot:nth-child(22)::before,
.dot:nth-child(22)::after {
  animation-delay: -7333.33333333ms;
}
.dot:nth-child(23) {
  transform: rotate(345deg) translateY(-75px);
}
.dot:nth-child(23)::before,
.dot:nth-child(23)::after {
  animation-delay: -7666.66666667ms;
}
.dot:nth-child(24) {
  transform: rotate(360deg) translateY(-75px);
}
.dot:nth-child(24)::before,
.dot:nth-child(24)::after {
  animation-delay: -8000ms;
}
.dot:nth-child(25) {
  transform: rotate(375deg) translateY(-75px);
}
.dot:nth-child(25)::before,
.dot:nth-child(25)::after {
  animation-delay: -8333.33333333ms;
}
.dot:nth-child(26) {
  transform: rotate(390deg) translateY(-75px);
}
.dot:nth-child(26)::before,
.dot:nth-child(26)::after {
  animation-delay: -8666.66666667ms;
}
.dot:nth-child(27) {
  transform: rotate(405deg) translateY(-75px);
}
.dot:nth-child(27)::before,
.dot:nth-child(27)::after {
  animation-delay: -9000ms;
}
.dot:nth-child(28) {
  transform: rotate(420deg) translateY(-75px);
}
.dot:nth-child(28)::before,
.dot:nth-child(28)::after {
  animation-delay: -9333.33333333ms;
}
.dot:nth-child(29) {
  transform: rotate(435deg) translateY(-75px);
}
.dot:nth-child(29)::before,
.dot:nth-child(29)::after {
  animation-delay: -9666.66666667ms;
}
.dot:nth-child(30) {
  transform: rotate(450deg) translateY(-75px);
}
.dot:nth-child(30)::before,
.dot:nth-child(30)::after {
  animation-delay: -10000ms;
}
.dot:nth-child(31) {
  transform: rotate(465deg) translateY(-75px);
}
.dot:nth-child(31)::before,
.dot:nth-child(31)::after {
  animation-delay: -10333.33333333ms;
}
.dot:nth-child(32) {
  transform: rotate(480deg) translateY(-75px);
}
.dot:nth-child(32)::before,
.dot:nth-child(32)::after {
  animation-delay: -10666.66666667ms;
}
.dot:nth-child(33) {
  transform: rotate(495deg) translateY(-75px);
}
.dot:nth-child(33)::before,
.dot:nth-child(33)::after {
  animation-delay: -11000ms;
}
.dot:nth-child(34) {
  transform: rotate(510deg) translateY(-75px);
}
.dot:nth-child(34)::before,
.dot:nth-child(34)::after {
  animation-delay: -11333.33333333ms;
}
.dot:nth-child(35) {
  transform: rotate(525deg) translateY(-75px);
}
.dot:nth-child(35)::before,
.dot:nth-child(35)::after {
  animation-delay: -11666.66666667ms;
}
.dot:nth-child(36) {
  transform: rotate(540deg) translateY(-75px);
}
.dot:nth-child(36)::before,
.dot:nth-child(36)::after {
  animation-delay: -12000ms;
}
/*
.dot:nth-child(1) {
    transform: rotate(@pdeg) translateY(-@halfContainerSize);
}
.dot:nth-child(2) {
    transform: rotate(@pdeg*2) translateY(-@halfContainerSize);
}
.dot:nth-child(3) {
    transform: rotate(@pdeg*3) translateY(-@halfContainerSize);
}
*/

扩展 关于Less四则运算除非处理

由于less编译器的版本问题可能会出现如下问题导致css生成的语句达不到预期效果如:

编写less代码

@containerSize: 150px;
@pdeg: 15deg;
@ani-diratoion: 2000ms;
@index: 2;
@count: 36;

.dot{
    width: @containerSize/2;
}

.dot:nth-child(1) {
    transform: rotate(@pdeg * @index) translateY(-@containerSize/2);
    &::before, 
    &::after {
        animation-delay: -@ani-diratoion / (@count * 6 * @index);
    }
}

生成css代码

其中150px/2-150px/2-2000ms / 432 ,这些并不能被浏览器识别,然后渲染。为什么会出现这种情况,是因为less编译器的版本、不同系统Windows、Mac等的语法兼容性导致的。

.dot {
  width: 150px/2;
}
.dot:nth-child(1) {
  transform: rotate(30deg) translateY(-150px/2);
}
.dot:nth-child(1)::before,
.dot:nth-child(1)::after {
  animation-delay: -2000ms / 432;
}

解决方案 将除号和参与运算的变量或数字用小括号()包起来

Less 代码
@containerSize: 150px;
@pdeg: 15deg;
@ani-diratoion: 2000ms;
@index: 2;
@count: 36;

.dot{
    width: (@containerSize/2);
}

.dot:nth-child(1) {
    transform: rotate(@pdeg * @index) translateY(-(@containerSize/2));
    &::before, 
    &::after {
        animation-delay: -(@ani-diratoion / @count * 6 * @index);
    }
}
CSS 代码
.dot {
  width: 75px;
}
.dot:nth-child(1) {
  transform: rotate(30deg) translateY(-75px);
}
.dot:nth-child(1)::before,
.dot:nth-child(1)::after {
  animation-delay: -666.66666667ms;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值