Vue实现IOS原生loading效果

前言

无论是在web端还是app端,当页面内需要请求网络资源或者执行比较耗时的操作的时候,都应该显示一个加载中的状态,以获得更好的用户体验。本文主要基于Vue,讲解IOS原生Loading效果的实现原理。

效果图

在这里插入图片描述

资源地址

1. 演示地址(gitee)
2. 演示地址(github)
3. Github代码地址

安装

  1. npm安装plain-loading
    npm i plain-loading -S
    
  2. 使用plain-loading
    import Vue from 'vue'
    import PlainLoading from 'plain-loading'
    import 'plain-loading/dist/PlainLoading.css'
    
    Vue.use(PlainLoading)
    
    <pl-loading/>
    
  3. 更多使用方式请看: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;
            }
        }
    }

解析

  1. 首先需要有一个父元素:pl-loading-alpha-tag,然后在这个父元素节点下创建12个子元素;
  2. 父元素相对定位,子元素绝对定位,通过设置top,margin-top,left以及margin-left调整子元素在父元素中的位置,这时候,所有子元素的位置都是在同一个位置,是重叠的;
  3. 设置子元素的transform-origin为:( c e n t e r R a d i u s / 2 ∗ − 1 ) ( centerRadius / 2 * -1) ( centerRadius/21)(itemHeight / 2),这个位置为父元素的中间位置,然后依序设置每个子元素的旋转角度,这样所有子元素就散开变成了一朵花形状;
  4. 设置一个透明度变化动画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;
        }
    }
    
  5. 设置每个子元素都使用这个动画,但是每个子元素的动画都有一定的延迟,序号越大的子元素延迟越大:
    @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;
         }
     }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值