四零语境前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

218 lines
4.5 KiB

<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>