123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- <template>
- <view
- class="u-loading-icon"
- :style="[$u.addStyle(customStyle)]"
- :class="[vertical && 'u-loading-icon--vertical']"
- v-if="show"
- >
- <view
- v-if="!webviewHide"
- class="u-loading-icon__spinner"
- :class="[`u-loading-icon__spinner--${mode}`]"
- ref="ani"
- :style="{
- color: color,
- width: $u.addUnit(size),
- height: $u.addUnit(size),
- borderTopColor: color,
- borderBottomColor: otherBorderColor,
- borderLeftColor: otherBorderColor,
- borderRightColor: otherBorderColor,
- 'animation-duration': `${duration}ms`,
- 'animation-timing-function': mode === 'semicircle' || mode === 'circle' ? timingFunction : ''
- }"
- >
- <block v-if="mode === 'spinner'">
- <!-- #ifndef APP-NVUE -->
- <view
- v-for="(item, index) in array12"
- :key="index"
- class="u-loading-icon__dot"
- >
- </view>
- <!-- #endif -->
- <!-- #ifdef APP-NVUE -->
- <!-- 此组件内部图标部分无法设置宽高,即使通过width和height配置了也无效 -->
- <loading-indicator
- v-if="!webviewHide"
- class="u-loading-indicator"
- :animating="true"
- :style="{
- color: color,
- width: $u.addUnit(size),
- height: $u.addUnit(size)
- }"
- />
- <!-- #endif -->
- </block>
- </view>
- <text
- v-if="text"
- class="u-loading-icon__text"
- :style="{
- fontSize: $u.addUnit(textSize),
- color: textColor,
- }"
- >{{text}}</text>
- </view>
- </template>
- <script>
- import props from './props.js';
-
- const animation = weex.requireModule('animation');
-
-
- export default {
- name: 'u-loading-icon',
- mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
- data() {
- return {
-
-
- array12: Array.from({
- length: 12
- }),
-
-
- aniAngel: 360,
- webviewHide: false,
- loading: false,
- }
- },
- computed: {
-
-
-
- otherBorderColor() {
- const lightColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[80]
- if (this.mode === 'circle') {
- return this.inactiveColor ? this.inactiveColor : lightColor
- } else {
- return 'transparent'
- }
-
- }
- },
- watch: {
- show(n) {
-
-
- if (n && !this.loading) {
- setTimeout(() => {
- this.startAnimate()
- }, 30)
- }
-
- }
- },
- mounted() {
- this.init()
- },
- methods: {
- init() {
- setTimeout(() => {
-
- this.show && this.nvueAnimate()
-
-
- this.show && this.addEventListenerToWebview()
-
- }, 20)
- },
-
- addEventListenerToWebview() {
-
- const pages = getCurrentPages()
-
- const page = pages[pages.length - 1]
-
- const currentWebview = page.$getAppWebview()
-
- currentWebview.addEventListener('hide', () => {
- this.webviewHide = true
- })
- currentWebview.addEventListener('show', () => {
- this.webviewHide = false
- })
- },
-
- nvueAnimate() {
-
-
- this.mode !== 'spinner' && this.startAnimate()
- },
-
- startAnimate() {
- this.loading = true
- const ani = this.$refs.ani
- if (!ani) return
- animation.transition(ani, {
-
- styles: {
- transform: `rotate(${this.aniAngel}deg)`,
- transformOrigin: 'center center'
- },
- duration: this.duration,
- timingFunction: this.timingFunction,
-
- }, () => {
-
- this.aniAngel += 360
-
-
- this.show && !this.webviewHide ? this.startAnimate() : this.loading = false
- })
- }
-
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "../../libs/css/components.scss";
- $u-loading-icon-color: #c8c9cc !default;
- $u-loading-icon-text-margin-left:4px !default;
- $u-loading-icon-text-color:$u-content-color !default;
- $u-loading-icon-text-font-size:14px !default;
- $u-loading-icon-text-line-height:20px !default;
- $u-loading-width:30px !default;
- $u-loading-height:30px !default;
- $u-loading-max-width:100% !default;
- $u-loading-max-height:100% !default;
- $u-loading-semicircle-border-width: 2px !default;
- $u-loading-semicircle-border-color:transparent !default;
- $u-loading-semicircle-border-top-right-radius: 100px !default;
- $u-loading-semicircle-border-top-left-radius: 100px !default;
- $u-loading-semicircle-border-bottom-left-radius: 100px !default;
- $u-loading-semicircle-border-bottom-right-radiu: 100px !default;
- $u-loading-semicircle-border-style: solid !default;
- $u-loading-circle-border-top-right-radius: 100px !default;
- $u-loading-circle-border-top-left-radius: 100px !default;
- $u-loading-circle-border-bottom-left-radius: 100px !default;
- $u-loading-circle-border-bottom-right-radiu: 100px !default;
- $u-loading-circle-border-width:2px !default;
- $u-loading-circle-border-top-color:#e5e5e5 !default;
- $u-loading-circle-border-right-color:$u-loading-circle-border-top-color !default;
- $u-loading-circle-border-bottom-color:$u-loading-circle-border-top-color !default;
- $u-loading-circle-border-left-color:$u-loading-circle-border-top-color !default;
- $u-loading-circle-border-style:solid !default;
- $u-loading-icon-host-font-size:0px !default;
- $u-loading-icon-host-line-height:1 !default;
- $u-loading-icon-vertical-margin:6px 0 0 !default;
- $u-loading-icon-dot-top:0 !default;
- $u-loading-icon-dot-left:0 !default;
- $u-loading-icon-dot-width:100% !default;
- $u-loading-icon-dot-height:100% !default;
- $u-loading-icon-dot-before-width:2px !default;
- $u-loading-icon-dot-before-height:25% !default;
- $u-loading-icon-dot-before-margin:0 auto !default;
- $u-loading-icon-dot-before-background-color:currentColor !default;
- $u-loading-icon-dot-before-border-radius:40% !default;
- .u-loading-icon {
-
-
-
- flex-direction: row;
- align-items: center;
- justify-content: center;
- color: $u-loading-icon-color;
- &__text {
- margin-left: $u-loading-icon-text-margin-left;
- color: $u-loading-icon-text-color;
- font-size: $u-loading-icon-text-font-size;
- line-height: $u-loading-icon-text-line-height;
- }
- &__spinner {
- width: $u-loading-width;
- height: $u-loading-height;
- position: relative;
-
- box-sizing: border-box;
- max-width: $u-loading-max-width;
- max-height: $u-loading-max-height;
- animation: u-rotate 1s linear infinite;
-
- }
- &__spinner--semicircle {
- border-width: $u-loading-semicircle-border-width;
- border-color: $u-loading-semicircle-border-color;
- border-top-right-radius: $u-loading-semicircle-border-top-right-radius;
- border-top-left-radius: $u-loading-semicircle-border-top-left-radius;
- border-bottom-left-radius: $u-loading-semicircle-border-bottom-left-radius;
- border-bottom-right-radius: $u-loading-semicircle-border-bottom-right-radiu;
- border-style: $u-loading-semicircle-border-style;
- }
- &__spinner--circle {
- border-top-right-radius: $u-loading-circle-border-top-right-radius;
- border-top-left-radius: $u-loading-circle-border-top-left-radius;
- border-bottom-left-radius: $u-loading-circle-border-bottom-left-radius;
- border-bottom-right-radius: $u-loading-circle-border-bottom-right-radiu;
- border-width: $u-loading-circle-border-width;
- border-top-color: $u-loading-circle-border-top-color;
- border-right-color: $u-loading-circle-border-right-color;
- border-bottom-color: $u-loading-circle-border-bottom-color;
- border-left-color: $u-loading-circle-border-left-color;
- border-style: $u-loading-circle-border-style;
- }
- &--vertical {
- flex-direction: column
- }
- }
-
- :host {
- font-size: $u-loading-icon-host-font-size;
- line-height: $u-loading-icon-host-line-height;
- }
- .u-loading-icon {
- &__spinner--spinner {
- animation-timing-function: steps(12)
- }
- &__text:empty {
- display: none
- }
- &--vertical &__text {
- margin: $u-loading-icon-vertical-margin;
- color: $u-content-color;
- }
- &__dot {
- position: absolute;
- top: $u-loading-icon-dot-top;
- left: $u-loading-icon-dot-left;
- width: $u-loading-icon-dot-width;
- height: $u-loading-icon-dot-height;
- &:before {
- display: block;
- width: $u-loading-icon-dot-before-width;
- height: $u-loading-icon-dot-before-height;
- margin: $u-loading-icon-dot-before-margin;
- background-color: $u-loading-icon-dot-before-background-color;
- border-radius: $u-loading-icon-dot-before-border-radius;
- content: " "
- }
- }
- }
- @for $i from 1 through 12 {
- .u-loading-icon__dot:nth-of-type(#{$i}) {
- transform: rotate($i * 30deg);
- opacity: 1 - 0.0625 * ($i - 1);
- }
- }
- @keyframes u-rotate {
- 0% {
- transform: rotate(0deg)
- }
- to {
- transform: rotate(1turn)
- }
- }
-
- </style>
|