|
|
|
@ -1,6 +1,6 @@ |
|
|
|
|
import Taro from "@tarojs/taro"; |
|
|
|
|
import { View, Image } from '@tarojs/components' |
|
|
|
|
import { Component, ReactNode } from "react"; |
|
|
|
|
import {View, Image} from '@tarojs/components' |
|
|
|
|
import {Component, ReactNode} from "react"; |
|
|
|
|
import indicator from './loading.svg' |
|
|
|
|
import './style.scss' |
|
|
|
|
|
|
|
|
@ -12,8 +12,9 @@ type Status = |
|
|
|
|
| 'completed' |
|
|
|
|
|
|
|
|
|
interface Props { |
|
|
|
|
enable?: boolean |
|
|
|
|
overlay?: boolean |
|
|
|
|
enable?: boolean // 控制显现
|
|
|
|
|
overlay?: boolean // 页面覆盖
|
|
|
|
|
block?: boolean // 块级
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface State { |
|
|
|
@ -30,8 +31,8 @@ type Controller = { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function createController(setState: StateSetter): Controller { |
|
|
|
|
const background = Taro.createAnimation({ duration: 600 }) |
|
|
|
|
const rotation = Taro.createAnimation({ duration: 600 }) |
|
|
|
|
const background = Taro.createAnimation({duration: 600}) |
|
|
|
|
const rotation = Taro.createAnimation({duration: 600}) |
|
|
|
|
let rotateTimer: ReturnType<typeof setTimeout> | undefined |
|
|
|
|
let status: Status | undefined |
|
|
|
|
|
|
|
|
@ -49,8 +50,8 @@ function createController(setState: StateSetter): Controller { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 清空动画
|
|
|
|
|
background.export() |
|
|
|
|
rotation.export() |
|
|
|
|
background.step().export() |
|
|
|
|
rotation.step().export() |
|
|
|
|
|
|
|
|
|
// 通知 UI 刷新
|
|
|
|
|
if (notify) { |
|
|
|
@ -66,7 +67,7 @@ function createController(setState: StateSetter): Controller { |
|
|
|
|
|
|
|
|
|
// 旋转动画定时器
|
|
|
|
|
const rotate = () => { |
|
|
|
|
rotation.opacity(opacity).rotate(360).step({ duration: 600 }) |
|
|
|
|
rotation.opacity(opacity).rotate(360).step({duration: 600}) |
|
|
|
|
notifyListener() |
|
|
|
|
rotateTimer = setTimeout(rotate, 600) |
|
|
|
|
} |
|
|
|
@ -80,23 +81,20 @@ function createController(setState: StateSetter): Controller { |
|
|
|
|
|
|
|
|
|
const onFinish = (opacity: number, nextStatus: Status) => { |
|
|
|
|
const lockStatus = status |
|
|
|
|
setTimeout(() => { |
|
|
|
|
if (lockStatus === status) { |
|
|
|
|
background.backgroundColor(`rgba(255,255,255,${opacity})`).step({ duration: 0 }) |
|
|
|
|
background.backgroundColor(`rgba(255,255,255,${opacity})`).step({duration: 0}) |
|
|
|
|
if (nextStatus === 'dismissed') { |
|
|
|
|
clearAnimation() |
|
|
|
|
} |
|
|
|
|
status = nextStatus |
|
|
|
|
notifyListener() |
|
|
|
|
} |
|
|
|
|
}, 600) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const setStatus = (newStatus: Status, opacity: number) => { |
|
|
|
|
if (status !== newStatus) { |
|
|
|
|
status = newStatus |
|
|
|
|
setAnimation(opacity) |
|
|
|
|
|
|
|
|
|
if (status === 'reverse') { |
|
|
|
|
onFinish(0, 'dismissed') |
|
|
|
|
} else if (status === 'forward') { |
|
|
|
@ -140,10 +138,9 @@ export default class Spin extends Component<Props, State> { |
|
|
|
|
this.setState((s) => ({...s, ...state})) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
componentDidMount(): void { |
|
|
|
|
console.log(this.props.enable) |
|
|
|
|
this.controller.setTick(this.props.enable) |
|
|
|
|
} |
|
|
|
|
// componentDidMount(): void {
|
|
|
|
|
// this.controller.setTick(this.props.enable)
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
componentDidUpdate(): void { |
|
|
|
|
this.controller.setTick(this.props.enable) |
|
|
|
@ -161,9 +158,10 @@ export default class Spin extends Component<Props, State> { |
|
|
|
|
|
|
|
|
|
render(): ReactNode { |
|
|
|
|
return ( |
|
|
|
|
<View className={`spinner-wrapper ${this.state.status} ${this.props.overlay ? 'is-fixed' : ''}`}> |
|
|
|
|
<View |
|
|
|
|
className={`spinner-wrapper ${this.state.status} ${this.props.overlay && 'is-fixed'} ${this.props.block && 'is-block'}`}> |
|
|
|
|
<View className={`spinner ${this.state.status}`}> |
|
|
|
|
<Image className="spinner-icon" src={indicator} /> |
|
|
|
|
<Image className="spinner-icon" src={indicator}/> |
|
|
|
|
</View> |
|
|
|
|
</View> |
|
|
|
|
) |
|
|
|
|