Vue实现IOS原生loading效果

文章目录

  • 前言
  • 效果图
  • 资源地址
  • 安装
  • 原理解析
    • html源码
    • scss源码
    • 解析

前言

无论是在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;
         }
     }
    

你可能感兴趣的:(前端)