使用

这里的使用都以单独引入为例,全局引入使用类似。

WebLoading

无论是DOM还是FULLMINI最终都会走WebLoading

import type { LoadingType } from "web-loading";
import { initLoading } from 'web-loading'
let webLoading:LoadingType = initLoading({})
console.log(webLoading)

LoadingTypeloadingresizecloseupdategetOptionsgetLoadingId

loading

启动动画loading

  • 参数:

    • dom:HTMLElement
    • options?:OptionsType
  • 返回:void

调用loading函数,会先检查loadingId是否存在(是否还在绘制),只有无绘制状态才会启动。

loading参数2,可以覆盖初始化initLoadingoptions

resize

重新计算并绘制loading大小。

  • 参数:无
  • 返回:void

resize会从绑定的HtmlElement中重新获取大小并重新绘制,此函数不会重新实例WebLoadingloading业务场景不同,例如window.addEventListener('resize', loading.resize)可能会使用到。

close

关闭loading。

  • 参数:无
  • 返回:void

close首先会清空所有WebLoadingstore以及其他记录,并停止requestAnimationFrame调用,最后根据delayInto清除相关元素,关闭过程中WebLoading会使用hookCall触发hook关闭钩子函数(BEFORE_COLSE:关闭前,COLSED:关闭后,也就是清除元素后),以便于绘制model

update

动态绘制model,不能动态修改公共配置

  • 参数:
    • options?:OptionsType
  • 返回:void

update函数不会重新实例WebLoading,并通过参数options重新绘制model。业务场景与loading类似,但loading每次都会初始化WebLoading,只有每次关闭才能实现相应业务,所以在动态绘制model业务场景下推荐使用update

getOptions

获取当前options配置。

  • 参数:无

  • 返回:

    • options:OptionsType

getLoadingId

获取 loadingId

  • 参数:无

  • 返回:

    • loadingId:string | null

loadingId在初始化会赋值,close关闭后会赋值为null,因此,如果loadingIdnull当前无绘制状态,否则相反。

options

import { initLoading, MODEL_TYPES } from "web-loading";
let webLoading = initLoading({
    model:MODEL_TYPES.GEAR
})

公共

属性类型默认值备注
html?:string''html加载方式(优先级大于custom)
custom?:typeof BaseModel 或 nullnull自定义model(优先级大于model)
type?:LOADING_TYPESLOADING_TYPES.DOM启动方式
extendClass?:string 或 null 或 undefinedextend启动方式为MINIFILL时的class
model?:MODEL_TYPESMODEL_TYPES.RINGmodel模块
text?:string加载中...字体内容
textGap?:number8字体间距
fontSize?:number12字体大小
fontFamily?:stringMicrosoft YaHei字体类型
delay?:number65动画延迟
delayInto?:number320进入/关闭 动画延迟
notFeelnumber0无感刷新(300:300毫秒以内调用close不绘制loading)
optimization?:booleanfalse优化处理(暂不支持)
zIndex?:string2001loading层级
themeColor?:stringrgba(64,158,255,1)主题色
bgColor?:stringrgba(0, 0, 0, 0.8)背景色
shadowColor?:stringrgba(64,158,255,0.6)阴影色
shadowOffsetX?:number2阴影X
shadowOffsetY?:number2阴影Y
shadowBlur?:number5阴影范围
pointerEvents?:booleanfalse事件穿透(DOM方式)
toast?:booleantrue是否显示提示
  • LOADING_TYPES
属性枚举值备注
DOMdom元素
FULLfull全屏
MINImini移动端
  • MODEL_TYPES

支持的model

model

model配置详情

custom自定义model

TypeScript项目例子

  • 自定义
import type { OptionsType, LimitType, ElementType } from "web-loading";
import { BaseModel } from "web-loading";
// 1?.如果model中options需要自定义参数,定义options类型
interface CustomOptionsType extends OptionsType {
  size?: number;
}
// 2?.自定义model默认参数(如果无需自定义options参数,使用OptionsType即可)
// 2.1?. 定义默认值
let modelDefOptions: CustomOptionsType = {
  size: 10,
};
// 2.2?.限制值的大小
let limits: Array<LimitType> = [
  {
    key: "size",
    message: "key < 100",
    limit: (key) => {
      return key < 100;
    },
  },
];
// 3.自定义model类
class CustomLoading extends BaseModel<CustomOptionsType> {
  constructor(w: number, h: number, canvas: HTMLCanvasElement, options: Required<CustomOptionsType>, element: ElementType) {
   super(w, h, canvas, options, element, modelDefOptions, limits, function modelDefCall(model) {
      // BaseModel初始化成功回调(可以自己做一些格外的初始化操作)
      // model 是CustomLoading本身,这里初始化默认画笔fill为红色
      model.ctx.fillStyle = "red";
    });
    // 根据周期调用
    this.run(this.draw);
  }
  draw() {
    // 清空画布
    this.clearRect();
    let op = this.options;
    // 绘制(这里获取配置的自定义options参数)
    this.ctx.fillRect(-op.size / 2, -op.size / 2, op.size, op.size);
  }
}

这里简单自定义绘制了一个矩形

  • BaseModel是自定义继承类,如果是全局引入情况下,window中挂载BaseModel属性的。
  • 注意:modelDefOptionslimitsmodelDefCall不是必填参数
  • 这里如果自定义的model无需options参数,可以省略1、2步骤。
  • loading
import type { LoadingType, CustomOptionsType } from "web-loading";
import { initLoading, BaseModel } from 'web-loading'
let dom = document.querySelector("xxx");
// 配置参数
let options: CustomOptionsType = {
    custom: CustomLoading as typeof BaseModel,
    size: 20,
};
let webLoading: LoadingType = initLoading(options);
webLoading.loading(dom);

原生html项目例子

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>web-loading</title>
  </head>
  <script src="https://cdn.jsdelivr.net/npm/web-loading"></script>
  <body>
    <div id="app">
      <div class="item">
        <div>
          id:
          <span class="value">001</span>
        </div>
        <div>
          user:
          <span class="value">use1</span>
        </div>
      </div>
    </div>
    <script>
      window.onload = () => {
        // encapsulation
        let modelDefOptions = {
          size: 10
        }
        let limits = [
          {
            key: 'size',
            message: 'key < 100',
            limit: (key) => {
              return key < 100
            }
          }
        ]
        class CustomLoading extends BaseModel {
          constructor(w, h, canvas, options, store) {
            super(w, h, canvas, options, store, modelDefOptions, function modelDefCall(model) {
              model.ctx.fillStyle = 'red'
            })
            this.run(this.draw)
          }
          draw() {
            this.clearRect()
            let op = this.options
            this.ctx.fillRect(-op.size / 2, -op.size / 2, op.size, op.size)
          }
        }
        // loading
        let docApp = document.querySelector('#app')
        const webLoading = initLoading({
          custom: CustomLoading,
          size: 20
        })
        window.addEventListener('resize', webLoading.resize)
        webLoading.loading(docApp)
        setTimeout(() => {
          webLoading.close()
        }, 1500)
      }
    </script>
  </body>
  <style>
    #app {
      margin: 12px;
      padding: 12px;
      height: 200px;
      border: 1px solid gray;
      overflow: auto;
      border-radius: 5px;
    }
    #app .item {
      display: flex;
      flex-direction: column;
      border: 1px solid gray;
      border-radius: 5px;
      padding: 10px;
      line-height: 30px;
      margin-bottom: 6px;
      height: 60px;
    }
    #app .item .value {
      display: inline-block;
      min-width: 31px;
      min-height: 16px;
      font-weight: bold;
      color: rgb(64, 158, 255);
    }
  </style>
</html>

1、BaseModel参数

WebLoading调用custom的时候会自动注入相关参数。

参数类型备注
wnumber画布宽度
hnumber画布高度
canvasHTMLCanvasElement画布元素,BaseModel默认以及获取了2d的上下文,但您还可以根据画布元素获取其他上下文
optionsRequired<CustomOptionsType>options是调节model参数,分为有公共参数与model参数最终会合并,Required标注你的参数不为空(已经初始值)
elementElementType容器元素
modelDefOptions?:T自定义model的默认参数(可选)
limits?:Array<LimitType>自定义modeloptions值限制函数(可选)
modelDefCall?:(model: BaseModel<T>) => voidBaseModel初始化完成回调(可选)

ElementType

继承了HTMLElement

属性类型备注
loadingIdstring或null记录loading元素id
$storeElementStoreTypeloding缓存内容
HTMLElement属性.........

ElementType.$store:ElementStoreType

绘制model时需要用到WebLoading的一些状态

属性类型备注
optionsOptionsType储存最终合并的options参数
animationIdnumber或undefined记录animation状态
loadingIdstring或null记录loading元素id
hookCallHooksCallTypeloading的钩子函数
modelBaseModel或null正在使用的model

ElementType.$store.hookCall:HooksCallType

WebLoading关闭时触发的钩子函数。

HOOKSCALL_KEY枚举。

属性枚举值类型备注
BEFORE_COLSEbeforeColseFunction关闭前
COLSEDcolsedFunction关闭后(删除元素后)

以自定义custom为例

// 其余code省略
class CustomLoading extends BaseModel<CustomOptionsType> {
    constructor(w: number, h: number, canvas: HTMLCanvasElement, options: Required<CustomOptionsType>, element: ElementType) {
        super(w, h, canvas, options, element);
        this.initOptions(defOptions);
        this.run(this.draw);
        this.store.hookCall.beforeColse(() => {
            console.log("关闭前");
        });
        this.store.hookCall.colsed(() => {
            console.log("关闭后");
        });
    }
    draw() {
        let op = this.options;
        this.ctx.fillRect(0, 0, op.size, op.size);
    }
}

LimitType

限制options参数值的范围。

属性类型备注
keystring需要限制的options属性
messagestring超出限制的提示
limit(key: any) => boolean限制操作

2、BaseModel函数

BaseModel自带的函数主要是用户扩展model绘制

函数返回备注
initContextCallvoidinitContextCall
runvoidrun
clearRectvoidclearRect
drowRadiusRectvoiddrowRadiusRect
drawTextvoiddrawText
clearAnimationFramevoidclearAnimationFrame

BaseModel:initContextCall

BaseModel初始化自定义画布属性(继承时已经触发)。

参数类型备注
modelDefOptions?:T自定义model的默认options值。
limits?:Array<LimitType>自定义modeloptions值的限制范围。
modelDefCall?:BaseModel<T>BaseModel初始化完成回调。

BaseModel:run

根据options.delay延迟触发requestAnimationFrame

参数类型备注
funFunction调用之前如果正处于加载,会清空上次的状态。
this.run(()=>{
    // 根据options.delay触发
})

BaseModel:clearRect

清空画布。

参数类型备注
x?:number清空起点X
y?:number清空的起点Y
w_r?:number清空终点X(宽度),圆形清空情况下w_r半径
h?:number清空终点Y(高度)
  • 清空全部
this.clearRect()

考虑到绘制区域可能会超出默认宽高,全部清空会清空两倍的宽高。

  • 自定义清空
this.clearRect(0,0,100,100)

清空从x=0,y=0的坐标开始,到x=100,y=100终止。

  • 圆形区域清空
this.clearRect(0,0,10)

清空x=0,y=0并且半径为10的区域。

BaseModel:drowRadiusRect

绘制含有圆角的矩形。

参数类型备注
xnumber起点X
ynumber起点Y
wnumber终点X(宽度)
hnumber终点Y(高度)
this.drowRadiusRect(0, 0, 100, 100, 10)
// 需要自己绘制
this.ctx.fill()

绘制x=0,y=0宽高为100并圆角为10的矩形。

BaseModel:drawText

绘制默认文本。

参数类型备注
params?:DrawTextParamsType绘制文本参数

BaseModel:drawText.DrawTextParamsType

参数类型默认值备注
esGapnumber0格外的文本空隙(本身textGap+fontSize)
xnumber0x轴
textstring加载中...文本
textColorstringrgba(64,158,255,1)文本颜色
this.drawText()

绘制x=0,y=0宽高为100并圆角为10的矩形。

BaseModel:clearAnimationFrame

清空(停止)requestAnimationFrame

参数类型备注
idnumberanimationId
this.clearAnimationFrame(element.$store.animationId)

传入的id是requestAnimationFrame返回的idWebLoading在store中已经保存。

3、BaseModel 技巧

动态的options

无论是初始化还是在run函数中,修改options都是实时动态的,以此可以控制requestAnimationFrame触发的延迟时间不那么规律。

this.run(()=>{
    // 动态修改delay会影响run函数的触发
    this.options.delay = 10
})

html配置方式

options 中添加html配置即可,它的优先级大于modelcustom

初始化

import { initLoading } from 'web-loading'
let webLoading = initLoading({
    html:`<div class="spinner">
    <svg viewBox="25 25 50 50" class="circular">
        <circle stroke-miterlimit="10" stroke-width="3" fill="none" r="20" cy="50" cx="50" class="path"></circle>
    </svg>
</div>`
})

html优先级大于custom

css动画

.spinner {
  --red: #d62d20;
  --blue: #0057e7;
  --green: #008744;
  --yellow: #ffa700;
  position: relative;
  width: 60px;
}

.spinner:before {
  content: "";
  display: block;
  padding-top: 100%;
}

.circular {
  animation: rotate73451 2s linear infinite;
  height: 100%;
  transform-origin: center center;
  width: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}

.path {
  stroke-dasharray: 1, 200;
  stroke-dashoffset: 0;
  animation: dash0175 1.5s ease-in-out infinite, color7123 6s ease-in-out infinite;
  stroke-linecap: round;
}

@keyframes rotate73451 {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes dash0175 {
  0% {
    stroke-dasharray: 1, 200;
    stroke-dashoffset: 0;
  }

  50% {
    stroke-dasharray: 89, 200;
    stroke-dashoffset: -35px;
  }

  100% {
    stroke-dasharray: 89, 200;
    stroke-dashoffset: -124px;
  }
}

@keyframes color7123 {
  100%, 0% {
    stroke: var(--red);
  }

  40% {
    stroke: var(--blue);
  }

  66% {
    stroke: var(--green);
  }

  80%, 90% {
    stroke: var(--yellow);
  }
}

class命名尽量隔绝外部元素。

上次更新:
贡献者: tommyrunner