| <template> | |
| 	<view v-if="visible" class="circle y-flex" ref="loading" :style="{ | |
| 		width: pixelSize + 'px', | |
| 		height: pixelSize + 'px', | |
| 		'border-radius': pixelSize + 'px' | |
| 	}"> | |
| 		<view | |
| 		class="line y-flex" | |
| 		:style="{ | |
| 			'border-top-width': (pixelSize / 4) + 'px', | |
| 			'border-bottom-width': (pixelSize / 4) + 'px', | |
| 			'border-top-color': item.top, | |
| 			'border-bottom-color': item.bottom, | |
| 			width: (pixelSize / 12) + 'px', | |
| 			left: ((pixelSize / 2) - (pixelSize / 24)) + 'px', | |
| 		}" | |
| 		:class="'line_' + index" | |
| 		v-for="(item, index) in rgbs" :key="index"></view> | |
| 	</view> | |
| </template> | |
| 
 | |
| <script> | |
| 	// #ifdef APP-NVUE | |
| 	const Binding = uni.requireNativePlugin('bindingx'); | |
| 	// #endif | |
| 	export default { | |
| 		props: { | |
| 			visible: { | |
| 				type: Boolean, | |
| 				default: true | |
| 			}, | |
| 			size: { | |
| 				type: [Number, String], | |
| 				default: 40 | |
| 			}, | |
| 			color: { | |
| 				type: String, | |
| 				default: '#333333' | |
| 			} | |
| 		}, | |
| 		computed: { | |
| 			rgbs () { | |
| 				const rgb = this.hexToRgb(this.color).replace('rgb(', '').replace(')', '') | |
| 				return [{ | |
| 					top: `rgba(${rgb}, 1)`, | |
| 					bottom: `rgba(${rgb}, .4)` | |
| 				},{ | |
| 					top: `rgba(${rgb}, .4)`, | |
| 					bottom: `rgba(${rgb}, .5)` | |
| 				},{ | |
| 					top: `rgba(${rgb}, .4)`, | |
| 					bottom: `rgba(${rgb}, .6)` | |
| 				},{ | |
| 					top: `rgba(${rgb}, .4)`, | |
| 					bottom: `rgba(${rgb}, .7)` | |
| 				},{ | |
| 					top: `rgba(${rgb}, .4)`, | |
| 					bottom: `rgba(${rgb}, .8)` | |
| 				},{ | |
| 					top: `rgba(${rgb}, .4)`, | |
| 					bottom: `rgba(${rgb}, .9)` | |
| 				}] | |
| 			}, | |
| 			pixelSize () { | |
| 				return this.unitpixel(this.size) | |
| 			} | |
| 		}, | |
| 		data () { | |
| 			return { | |
| 				loading_binding: null | |
| 			} | |
| 		}, | |
| 		mounted() { | |
| 			// #ifdef APP-NVUE | |
| 			this.$nextTick( function () { | |
| 				if ( this.visible ) this.start() | |
| 			}) | |
| 			// #endif | |
| 		}, | |
| 		beforeDestroy() { | |
| 			// #ifdef APP-NVUE | |
| 			if ( this.loading_binding ) { | |
| 				Binding.unbind({ | |
| 					token: this.loading_binding.token, | |
| 					eventType: 'timing' | |
| 				}) | |
| 				this.loading_binding = null | |
| 			} | |
| 			// #endif | |
| 		}, | |
| 		methods: { | |
| 			start () { | |
| 				const loading = this.getEl(this.$refs.loading); | |
| 				this.loading_binding = Binding.bind({ | |
| 				    eventType: 'timing', | |
| 				    props: [{ | |
| 				        element: loading, | |
| 				        property: 'transform.rotateZ', | |
| 				        expression: 'floor(t/100)*30' | |
| 				    }] | |
| 				}); | |
| 			}, | |
| 			unitpixel (size) { | |
| 				const text = size.toString() | |
| 				return text.indexOf('rpx') > -1 ? uni.upx2px(text.replace('rpx', '')) : text.indexOf('px') > -1 ? parseFloat(text.replace('px', '')) : uni.upx2px(text) | |
| 			}, | |
| 			hexToRgb (hex) { | |
| 				hex = hex.length == 7 ? hex : '#' + hex.slice(1, 4) + hex.slice(1, 4) | |
| 				let str="rgb(" | |
| 				const r = parseInt(hex.slice(1,3),16).toString();   //ff  slice不包括end | |
| 				const g = parseInt(hex.slice(3,5),16).toString();   //00 | |
| 				const b = parseInt(hex.slice(5,7),16).toString();   //ff | |
| 				str += r+","+g+","+b+")"; | |
| 				return str | |
| 			}, | |
| 			getEl (el) { | |
| 			    if (typeof el === 'string' || typeof el === 'number') return el; | |
| 				if (WXEnvironment) { | |
| 				    return el.ref; | |
| 				} else { | |
| 				    return el instanceof HTMLElement ? el : el.$el; | |
| 				} | |
| 			} | |
| 		}, | |
| 		watch: { | |
| 			visible (newVal) { | |
| 				// #ifdef APP-NVUE | |
| 				this.$nextTick(() => { | |
| 					if ( newVal ) { | |
| 						this.start() | |
| 					} else { | |
| 						if ( this.loading_binding ) { | |
| 							Binding.unbind({ | |
| 								token: this.loading_binding.token, | |
| 								eventType: 'timing' | |
| 							}) | |
| 							this.loading_binding = null | |
| 						} | |
| 					} | |
| 				}) | |
| 				// #endif | |
| 			} | |
| 		} | |
| 	} | |
| </script> | |
| 
 | |
| <style scoped> | |
| 	/* #ifndef APP-NVUE */ | |
| 	@keyframes loading{ | |
| 		0% { | |
| 			transform: rotateZ(30deg); | |
| 		} | |
| 		9.33333%{ | |
| 			transform: rotateZ(60deg); | |
| 		} | |
| 		18.66666%{ | |
| 			transform: rotateZ(90deg); | |
| 		} | |
| 		27.99999%{ | |
| 			transform: rotateZ(120deg); | |
| 		} | |
| 		37.33332%{ | |
| 			transform: rotateZ(150deg); | |
| 		} | |
| 		46.66665%{ | |
| 			transform: rotateZ(180deg); | |
| 		} | |
| 		55.99998%{ | |
| 			transform: rotateZ(210deg); | |
| 		} | |
| 		65.33331%{ | |
| 			transform: rotateZ(240deg); | |
| 		} | |
| 		74.66664%{ | |
| 			transform: rotateZ(270deg); | |
| 		} | |
| 		83.99997%{ | |
| 			transform: rotateZ(300deg); | |
| 		} | |
| 		93.33333%{ | |
| 			transform: rotateZ(330deg); | |
| 		} | |
| 		100%{ | |
| 			transform: rotateZ(360deg); | |
| 		} | |
| 	} | |
| 	/* #endif */ | |
| 	.circle { | |
| 		position: relative; | |
| 		/* #ifndef APP-NVUE */ | |
| 		animation: loading 1200ms step-start infinite; | |
| 		/* #endif */ | |
| 	} | |
| 	.circle .line { | |
| 		position: absolute; | |
| 		border-top-style: solid; | |
| 		border-bottom-style: solid; | |
| 		top: 0; | |
| 		bottom: 0; | |
| 	} | |
| 	.circle .line_0 { | |
| 	} | |
| 	.circle .line_1 { | |
| 		transform: rotateZ(30deg); | |
| 	} | |
| 	.circle .line_2 { | |
| 		transform: rotateZ(60deg); | |
| 	} | |
| 	.circle .line_3 { | |
| 		transform: rotateZ(90deg); | |
| 	} | |
| 	.circle .line_4 { | |
| 		transform: rotateZ(120deg); | |
| 	} | |
| 	.circle .line_5 { | |
| 		transform: rotateZ(150deg); | |
| 	} | |
| </style> |