feat:初始提交uni-app项目

This commit is contained in:
2026-01-14 18:19:33 +08:00
commit 0dcbd340e6
515 changed files with 38560 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
## 1.4.22025-04-03
## 增加两个动画
| locating | 定位 (自定义颜色) |
| photo | 照片 (自定义颜色) |
## 1.4.12024-07-02
### 1. 增加动画equal(等边), wobble(摇摆)
### 2. 原来的triangle(三角)改为surround(环绕)
### 3. 新增可自定义颜色项
## 1.4.02024-06-28
## 增加 loading 加载文字提醒配置项,默认 false
## 1.3.22023-10-31
修改遮罩默认透明度为 0.1
## 1.3.12023-10-31
## 新增支持,自定义动画颜色(仅部分动画支持)
## 新增动画-annulus(圆环)
## 1.3.02023-08-11
支持 vue3 使用, 增加动画类型 radar(雷达)
## 1.2.22023-06-12
增加 maskOpacity, maskMini, maskDark 自定义参数, 提供更丰富的自定义遮罩层能力
## 1.2.12022-09-09
增加齿轮动画 type=gear
## 1.2.02022-05-27
1. 增加加载类型-剑气sword原子atom
2. 默认类型改为 atom
3. 遮罩透明度调整
## 1.1.12022-04-02
更新使用说明
## 1.1.02022-02-23
增加 type="love" 的心形加载动画
## 1.0.02022-01-28
首次发布

View File

@@ -0,0 +1,45 @@
<template>
<view class="animations">
<view class="loader" :style="{ '--color': color }"></view>
</view>
</template>
<script>
export default {
name: "loading-annulus",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.loader {
width: 60px;
height: 60px;
}
.loader::before {
content: "";
box-sizing: border-box;
position: absolute;
width: 60px;
height: 60px;
border-radius: 50%;
border-top: 2px solid var(--color);
border-right: 2px solid transparent;
animation: spinner 1s linear infinite;
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
</style>

View File

@@ -0,0 +1,108 @@
<template>
<view class="animations">
<view class="box" :style="{ '--color': color }">
<view class="atom"></view>
<view class="atom"></view>
<view class="atom"></view>
<view class="dot"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-atom",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
position: relative;
width: 120rpx;
height: 120rpx;
}
.dot {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--color);
animation: dotbreath 2s linear infinite;
}
.atom {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
border-left-width: 6rpx;
border-top-width: 6rpx;
border-left-color: var(--color);
border-left-style: solid;
border-top-style: solid;
border-top-color: transparent;
}
.atom:nth-of-type(1) {
left: 0%;
top: 0%;
animation: atom1 1s linear infinite;
}
.atom:nth-of-type(2) {
right: 0%;
top: 0%;
animation: atom2 1s linear infinite;
}
.atom:nth-of-type(3) {
right: 0%;
bottom: 0%;
animation: atom3 1s linear infinite;
}
@keyframes dotbreath {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
@keyframes atom1 {
0% {
transform: rotateZ(120deg) rotateX(66deg) rotateZ(0deg);
}
100% {
transform: rotateZ(120deg) rotateX(66deg) rotateZ(360deg);
}
}
@keyframes atom2 {
0% {
transform: rotateZ(240deg) rotateX(66deg) rotateZ(0deg);
}
100% {
transform: rotateZ(240deg) rotateX(66deg) rotateZ(360deg);
}
}
@keyframes atom3 {
0% {
transform: rotateZ(360deg) rotateX(66deg) rotateZ(0deg);
}
100% {
transform: rotateZ(360deg) rotateX(66deg) rotateZ(360deg);
}
}
</style>

View File

@@ -0,0 +1,84 @@
<template>
<view class="animations">
<view class="box">
<view class="dot dot1"></view>
<view class="dot dot2"></view>
<view class="dot dot3"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-bounce",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
width: 100rpx;
height: 50rpx;
position: relative;
}
.dot {
width: 14rpx;
height: 14rpx;
background: #007aff;
border-radius: 50%;
position: absolute;
top: calc(50% - 5rpx);
}
.dot1 {
background: #1fa2ff;
left: 0rpx;
-webkit-animation: bounce 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
infinite;
animation: bounce 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite;
}
.dot2 {
background: #12d8fa;
left: 40rpx;
-webkit-animation: bounce 0.5s 0.2s cubic-bezier(0.77, 0.47, 0.64, 0.28)
alternate infinite;
animation: bounce 0.5s 0.2s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
infinite;
}
.dot3 {
background: #29ffc6;
left: 80rpx;
-webkit-animation: bounce 0.5s 0.4s cubic-bezier(0.77, 0.47, 0.64, 0.28)
alternate infinite;
animation: bounce 0.5s 0.4s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate
infinite;
}
@-webkit-keyframes bounce {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-20rpx);
transform: translateY(-20rpx);
}
}
@keyframes bounce {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-20rpx);
transform: translateY(-20rpx);
}
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<view class="animations">
<view class="loader" :style="{ '--color': color }"></view>
</view>
</template>
<script>
export default {
name: "loading-circle",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
// .container {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// }
.loader {
display: block;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 3rpx solid transparent;
border-top-color: var(--color);
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
position: relative;
}
.loader::before {
content: "";
position: absolute;
top: 8rpx;
left: 8rpx;
right: 8rpx;
bottom: 8rpx;
border-radius: 50%;
border: 3rpx solid transparent;
border-top-color: var(--color);
-webkit-animation: spin 3s linear infinite;
animation: spin 3s linear infinite;
}
.loader::after {
content: "";
position: absolute;
top: 16rpx;
left: 16rpx;
right: 16rpx;
bottom: 16rpx;
border-radius: 50%;
border: 3rpx solid transparent;
border-top-color: var(--color);
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view class="animations">
<view class="loader" :style="{ '--color': color }"></view>
</view>
</template>
<script>
export default {
name: "loading-equal",
props: {
color: {
type: String,
default: "#ff1919",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.loader {
width: 50px;
aspect-ratio: 1.154;
position: relative;
background: conic-gradient(
from 120deg at 50% 64%,
#0000,
var(--color) 1deg 120deg,
#0000 121deg
);
animation: spin 1.5s infinite cubic-bezier(0.3, 1, 0, 1);
}
.loader:before,
.loader:after {
content: "";
position: absolute;
inset: 0;
background: inherit;
transform-origin: 50% 66%;
animation: separate 1.5s infinite;
}
.loader:after {
--s: -1;
}
@keyframes spin {
0%,
30% {
transform: rotate(0);
}
70% {
transform: rotate(120deg);
}
70.01%,
100% {
transform: rotate(360deg);
}
}
@keyframes separate {
0% {
transform: rotate(calc(var(--s, 1) * 120deg)) translate(0);
}
30%,
70% {
transform: rotate(calc(var(--s, 1) * 120deg))
translate(calc(var(--s, 1) * -5px), 10px);
}
100% {
transform: rotate(calc(var(--s, 1) * 120deg)) translate(0);
}
}
</style>

View File

@@ -0,0 +1,78 @@
<template>
<view class="animations">
<view class="box">
<view class="eye"></view>
<view class="eye"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-eyes",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
width: 110rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.eye {
width: 50rpx;
height: 50rpx;
background: linear-gradient(135deg, #1fa2ff, #12d8fa);
border-radius: 50%;
position: relative;
}
.eye:after {
background-color: #ffffff;
width: 18rpx;
height: 18rpx;
border-radius: 50%;
left: 20rpx;
top: 24rpx;
position: absolute;
content: "";
-webkit-animation: eyeball 1s linear infinite alternate;
-moz-animation: eyeball 1s linear infinite alternate;
animation: eyeball 1s linear infinite alternate;
}
@-webkit-keyframes eyeball {
0% {
left: 30rpx;
}
100% {
left: 2rpx;
}
}
@-moz-keyframes eyeball {
0% {
left: 30rpx;
}
100% {
left: 2rpx;
}
}
@keyframes eyeball {
0% {
left: 30rpx;
}
100% {
left: 2rpx;
}
}
</style>

View File

@@ -0,0 +1,118 @@
<template>
<view class="animations">
<view class="box">
<view class="gear1">
<view class="inner inner1"> </view>
<view class="inner inner2"> </view>
<view class="inner inner3"> </view>
</view>
<view class="gear2">
<view class="inner inner1"> </view>
<view class="inner inner2"> </view>
<view class="inner inner3"> </view>
</view>
<view class="gear3">
<view class="inner inner1"> </view>
<view class="inner inner2"> </view>
<view class="inner inner3"> </view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "loading-gear",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
$size: 80rpx;
$bgc: red;
.box {
width: 200rpx;
height: 200rpx;
position: relative;
}
@mixin gear($size: $size, $bgc: $bgc) {
width: $size;
height: $size;
.inner {
position: absolute;
width: $size;
height: $size;
top: 0;
left: 0;
background: $bgc;
border-radius: 6rpx;
mask: radial-gradient(transparent 40%, #fff 60%);
}
.inner2 {
transform: rotate(120deg);
}
.inner3 {
transform: rotate(240deg);
}
// &:after {
// position: absolute;
// content: '';
// background: #fff;
// width: $size / 1.8;
// height: $size / 1.8;
// border-radius: 100%;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// }
}
.gear1 {
@include gear(60rpx, #0396ff);
position: absolute;
top: 35rpx;
left: 35rpx;
animation: rotate 5s infinite linear;
}
.gear2 {
@include gear(50rpx, #dd524d);
position: absolute;
top: 50rpx;
left: 110rpx;
animation: rotateR 5s infinite linear;
}
.gear3 {
@include gear(50rpx, #f0ad4e);
position: absolute;
top: 110rpx;
left: 50rpx;
animation: rotateR 5s infinite linear;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes rotateR {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view class="animations">
<view class="loader" :style="{ '--color': color }"></view>
</view>
</template>
<script>
export default {
name: "loading-locating",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.loader {
width: 96rpx;
height: 96rpx;
display: block;
margin: 40rpx auto;
box-sizing: border-box;
position: relative;
}
.loader::after {
content: '';
width: 96rpx;
height: 96rpx;
left: 0;
bottom: 0;
position: absolute;
border-radius: 50% 50% 0;
border: 30rpx solid var(--color);
transform: rotate(45deg) translate(0, 0);
box-sizing: border-box;
animation: animMarker 0.4s ease-in-out infinite alternate;
}
.loader::before {
content: '';
box-sizing: border-box;
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 150%;
width: 48rpx;
height: 8rpx;
border-radius: 50%;
background: rgba(0, 0, 0, 0.2);
animation: animShadow 0.4s ease-in-out infinite alternate;
}
@keyframes animMarker {
0% {
transform: rotate(45deg) translate(10rpx, 10rpx);
}
100% {
transform: rotate(45deg) translate(-10rpx, -10rpx);
}
}
@keyframes animShadow {
0% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
</style>

View File

@@ -0,0 +1,201 @@
<template>
<view class="animations">
<view class="box">
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
<view class="item"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-love",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
display: flex;
justify-content: center;
align-items: center;
flex-flow: row nowrap;
height: 160rpx;
}
.item {
background: linear-gradient(to bottom, #f00000, #e73827);
width: 16rpx;
height: 16rpx;
border-radius: 20rpx;
margin-right: 10rpx;
}
.item:nth-child(1) {
animation: love1 4s infinite;
}
.item:nth-child(2) {
animation: love2 4s infinite;
animation-delay: 0.15s;
}
.item:nth-child(3) {
animation: love3 4s infinite;
animation-delay: 0.3s;
}
.item:nth-child(4) {
animation: love4 4s infinite;
animation-delay: 0.45s;
}
.item:nth-child(5) {
animation: love5 4s infinite;
animation-delay: 0.6s;
}
.item:nth-child(6) {
animation: love4 4s infinite;
animation-delay: 0.75s;
}
.item:nth-child(7) {
animation: love3 4s infinite;
animation-delay: 0.9s;
}
.item:nth-child(8) {
animation: love2 4s infinite;
animation-delay: 1.05s;
}
.item:nth-child(9) {
animation: love1 4s infinite;
animation-delay: 1.2s;
}
@keyframes love1 {
30%,
50% {
height: 50rpx;
transform: translateY(-20rpx);
}
75%,
100% {
height: 20rpx;
transform: translateY(0);
}
}
@keyframes love2 {
30%,
50% {
height: 90rpx;
transform: translateY(-25rpx);
}
75%,
100% {
height: 20rpx;
transform: translateY(0);
}
}
@keyframes love3 {
30%,
50% {
height: 120rpx;
transform: translateY(-20rpx);
}
75%,
100% {
height: 20rpx;
transform: translateY(0);
}
}
@keyframes love4 {
30%,
50% {
height: 130rpx;
transform: translateY(-10rpx);
}
75%,
100% {
height: 20rpx;
transform: translateY(0);
}
}
@keyframes love5 {
30%,
50% {
height: 130rpx;
transform: translateY(10rpx);
}
75%,
100% {
height: 20rpx;
transform: translateY(0);
}
}
// .item:nth-child(1) {
// height: 50rpx;
// transform: translateY(-20rpx);
// }
// .item:nth-child(2) {
// height: 90rpx;
// transform: translateY(-25rpx);
// }
// .item:nth-child(3) {
// height: 120rpx;
// transform: translateY(-20rpx);
// }
// .item:nth-child(4) {
// height: 130rpx;
// transform: translateY(-10rpx);
// }
// .item:nth-child(5) {
// height: 130rpx;
// transform: translateY(10rpx);
// }
// .item:nth-child(6) {
// height: 130rpx;
// transform: translateY(-10rpx);
// }
// .item:nth-child(7) {
// height: 120rpx;
// transform: translateY(-20rpx);
// }
// .item:nth-child(8) {
// height: 90rpx;
// transform: translateY(-25rpx);
// }
// .item:nth-child(9) {
// height: 50rpx;
// transform: translateY(-20rpx);
// }
</style>

View File

@@ -0,0 +1,87 @@
<template>
<view class="animations">
<view class="loader" :style="{ '--color': color }"></view>
</view>
</template>
<script>
export default {
name: "loading-photo",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.loader {
width: 128rpx;
height: 128rpx;
position: relative;
background: #f4f4f4;
border-radius: 8rpx;
overflow: hidden;
}
.loader:before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 80rpx;
height: 80rpx;
transform: rotate(45deg) translate(30%, 40%);
background: var(--color);
box-shadow: 64rpx -68rpx 0 10rpx var(--color);
animation: slide 2s infinite ease-in-out alternate;
}
.loader:after {
content: "";
position: absolute;
left: 20rpx;
top: 20rpx;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: var(--color);
transform: rotate(0deg);
transform-origin: 70rpx 290rpx;
animation: rotate 2s infinite ease-in-out;
}
@keyframes slide {
0% , 100% {
bottom: -70rpx
}
25% , 75% {
bottom: -4rpx
}
20% , 80% {
bottom: 4rpx
}
}
@keyframes rotate {
0% {
transform: rotate(-15deg)
}
25% , 75% {
transform: rotate(0deg)
}
100% {
transform: rotate(25deg)
}
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<view class="animations">
<view class="box" :style="{ '--color': color }">
<view class="pulse-bubble pulse-bubble-1"></view>
<view class="pulse-bubble pulse-bubble-2"></view>
<view class="pulse-bubble pulse-bubble-3"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-pulse",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
width: 100rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.pulse-bubble {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: var(--color);
}
.pulse-bubble-1 {
// background: #1fa2ff;
animation: pulse 0.4s ease 0s infinite alternate;
}
.pulse-bubble-2 {
// background: #12d8fa;
animation: pulse 0.4s ease 0.2s infinite alternate;
}
.pulse-bubble-3 {
// background: #29ffc6;
animation: pulse 0.4s ease 0.4s infinite alternate;
}
@keyframes pulse {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0.25;
transform: scale(0.75);
}
}
</style>

View File

@@ -0,0 +1,132 @@
<template>
<view class="animations">
<view class="radar">
<view class="dot dot-1"></view>
<view class="dot dot-2"></view>
<view class="dot dot-3"></view>
<view class="cover"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-radar",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
$size: 180rpx;
$dotSize: 4rpx;
$maincolor: #2da3f6;
.radar {
position: relative;
z-index: 1;
height: $size;
width: $size;
background: -webkit-repeating-radial-gradient(
rgba(45, 163, 246, 0) 0%,
rgba(45, 163, 246, 0) 23%,
rgba(45, 163, 246, 0.7) 24%,
rgba(45, 163, 246, 0) 25%
);
margin: 0 auto;
border-radius: 50%;
border: 2rpx solid rgba(45, 163, 246, 0.7);
overflow: hidden;
}
.radar::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: $dotSize;
height: $dotSize;
background: $maincolor;
margin-left: -1rpx;
margin-top: -1rpx;
border-radius: 1rpx;
}
.dot {
position: absolute;
width: $dotSize;
height: $dotSize;
background: $maincolor;
opacity: 0;
border-radius: 50%;
animation: breath 3s linear infinite;
box-shadow: 0 0 2rpx 2rpx rgba(45, 163, 246, 0.5);
}
.dot-1 {
top: 50rpx;
left: 30rpx;
animation-delay: 1s;
}
.dot-2 {
top: 60rpx;
right: 20rpx;
animation-delay: 0.2s;
}
.dot-3 {
top: 140rpx;
right: 100rpx;
animation-delay: 2.3s;
}
.cover {
transform-origin: bottom right;
border-right: 1rpx solid $maincolor;
background: linear-gradient(
45deg,
rgba(255, 255, 255, 0) 45%,
$maincolor 100%
);
width: 50%;
height: 50%;
position: absolute;
top: 0;
left: 0;
animation: rotation 3s linear infinite;
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes breath {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
20% {
opacity: 1;
}
40% {
opacity: 0;
}
100% {
opacity: 0;
}
}
</style>

View File

@@ -0,0 +1,140 @@
<template>
<view class="animations">
<view class="box">
<view class="sun"></view>
<view class="orbit orbit1">
<view class="planetX planet1"></view>
</view>
<view class="orbit orbit2">
<view class="planetX planet2"></view>
</view>
<view class="orbit orbit3">
<view class="planetX planet3"></view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "loading-sun",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
width: 210rpx;
height: 210rpx;
position: relative;
}
.sun {
background: radial-gradient(#ff0, #f90);
height: 50rpx;
width: 50rpx;
border-radius: 50%;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
.planetX {
position: absolute;
z-index: 100;
border-radius: 50%;
}
.planet1 {
left: 20rpx;
height: 13rpx;
width: 13rpx;
background-color: #fed313;
}
.planet2 {
left: 23rpx;
height: 20rpx;
width: 20rpx;
background: linear-gradient(#00ff00, #09f, #09f);
-webkit-animation: rotation 1s infinite linear;
animation: rotation 1s infinite linear;
}
.planet3 {
left: 49rpx;
height: 17rpx;
width: 17rpx;
background: radial-gradient(#ff9900, #ff4400);
}
.orbit {
background: transparent;
border-radius: 50%;
border: 1rpx solid #cccccc;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
.orbit1 {
height: 100rpx;
width: 100rpx;
-webkit-animation: rotation 2s infinite linear;
-moz-animation: rotation 2s infinite linear;
animation: rotation 2s infinite linear;
}
.orbit2 {
height: 150rpx;
width: 150rpx;
-webkit-animation: rotation 3s infinite linear;
-moz-animation: rotation 3s infinite linear;
animation: rotation 3s infinite linear;
}
.orbit3 {
height: 200rpx;
width: 200rpx;
-moz-animation: rotation 6s infinite linear;
-webkit-animation: rotation 6s infinite linear;
animation: rotation 6s infinite linear;
}
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@-moz-keyframes rotation {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(359deg);
}
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<view class="animations">
<view class="box">
<view class="loader">
<view class="loader__ball"></view>
<view class="loader__ball"></view>
<view class="loader__ball"></view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "loading-triangle",
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
$dotColor: linear-gradient(135deg, #1fa2ff, #12d8fa, #29ffc6);
$dotSize: 30rpx;
$duration: 2s;
.animations {
width: 160rpx;
height: 160rpx;
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loader {
animation: rotate $duration linear infinite normal;
position: relative;
transform-origin: 50% 50%;
&__ball {
height: $dotSize;
width: $dotSize;
left: -$dotSize * 0.5;
position: absolute;
top: -$dotSize * 0.5;
transform-origin: 50% 50%;
&:nth-of-type(2) {
transform: rotate(120deg);
}
&:nth-of-type(3) {
transform: rotate(240deg);
}
&::after {
animation: move $duration * 0.5 ease-in-out infinite alternate;
background: $dotColor;
border-radius: 50%;
content: "";
display: inline-block;
height: 100%;
width: 100%;
transform-origin: 50% 50%;
}
}
}
@keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes move {
0%,
15% {
transform: translateY(0);
}
100% {
transform: translateY(-150%);
}
}
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view class="animations">
<view class="box" :style="{ '--color': color }">
<view class="sword"></view>
<view class="sword"></view>
<view class="sword"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-sword",
props: {
color: {
type: String,
default: "#ED213A",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.box {
position: relative;
width: 120rpx;
height: 120rpx;
}
.sword {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
}
.sword:nth-of-type(1) {
left: 0%;
top: 0%;
border-bottom: 8rpx solid var(--color);
animation: sword1 0.8s linear infinite;
}
.sword:nth-of-type(2) {
right: 0%;
top: 0%;
border-right: 8rpx solid var(--color);
animation: sword2 0.8s linear infinite;
}
.sword:nth-of-type(3) {
right: 0%;
bottom: 0%;
border-top: 8rpx solid var(--color);
animation: sword3 0.8s linear infinite;
}
@keyframes sword1 {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes sword2 {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes sword3 {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<view class="animations">
<view class="three-body" :style="{ '--color': color }">
<view class="three-body__dot"></view>
<view class="three-body__dot"></view>
<view class="three-body__dot"></view>
</view>
</view>
</template>
<script>
export default {
name: "loading-wobble",
props: {
color: {
type: String,
default: "#0396FF",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
$size: 100rpx;
$speed: 1s;
.three-body {
position: relative;
display: inline-block;
height: $size;
width: $size;
animation: spin78236 calc($speed * 2.5) infinite linear;
}
.three-body__dot {
position: absolute;
height: 100%;
width: 27%;
}
.three-body__dot:after {
content: "";
position: absolute;
height: 0%;
width: 100%;
padding-bottom: 100%;
background-color: var(--color);
border-radius: 50%;
}
.three-body__dot:nth-child(1) {
bottom: 5%;
left: 0;
transform: rotate(60deg);
transform-origin: 50% 85%;
}
.three-body__dot:nth-child(1)::after {
bottom: 0;
left: 0;
animation: wobble1 $speed infinite ease-in-out;
animation-delay: calc($speed * -0.3);
}
.three-body__dot:nth-child(2) {
bottom: 5%;
right: 0;
transform: rotate(-60deg);
transform-origin: 50% 85%;
}
.three-body__dot:nth-child(2)::after {
bottom: 0;
left: 0;
animation: wobble1 $speed infinite calc($speed * -0.15) ease-in-out;
}
.three-body__dot:nth-child(3) {
bottom: -5%;
left: 0;
transform: translateX(116.666%);
}
.three-body__dot:nth-child(3)::after {
top: 0;
left: 0;
animation: wobble2 $speed infinite ease-in-out;
}
@keyframes spin78236 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes wobble1 {
0%,
100% {
transform: translateY(0%) scale(1);
opacity: 1;
}
50% {
transform: translateY(-66%) scale(0.65);
opacity: 0.8;
}
}
@keyframes wobble2 {
0%,
100% {
transform: translateY(0%) scale(1);
opacity: 1;
}
50% {
transform: translateY(66%) scale(0.65);
opacity: 0.8;
}
}
</style>

View File

@@ -0,0 +1,186 @@
<template>
<!-- -->
<view
:style="{ position: position, 'z-index': zIndex, '--opacity': maskOpacity }"
class="container"
:class="[
mask ? 'mask' : '',
maskMini ? 'mask-mini' : '',
(mask || maskMini) && maskDark ? 'mask-dark' : '',
]"
@click.prevent="handleClick"
>
<view>
<view class="main">
<loading0 v-if="type == 'circle'" :color="color"></loading0>
<loading1 v-if="type == 'pulse'" :color="color"></loading1>
<loading2 v-if="type == 'bounce'"></loading2>
<loading3 v-if="type == 'eyes'"></loading3>
<loading4 v-if="type == 'surround'"></loading4>
<loading5 v-if="type == 'sun'"></loading5>
<loading6 v-if="type == 'love'"></loading6>
<loading7 v-if="type == 'sword'" :color="color"></loading7>
<loading8 v-if="type == 'atom'" :color="color"></loading8>
<loading9 v-if="type == 'gear'"></loading9>
<loading10 v-if="type == 'radar'"></loading10>
<loading11 v-if="type == 'annulus'" :color="color"></loading11>
<loading12 v-if="type == 'wobble'" :color="color"></loading12>
<loading13 v-if="type == 'equal'" :color="color"></loading13>
<loading14 v-if="type == 'photo'" :color="color"></loading14>
<loading15 v-if="type == 'locating'" :color="color"></loading15>
</view>
<view
class="tips"
v-if="showText"
:style="{ color: textColor, fontSize: textSize, marginTop: textGap }"
>{{ text }}</view
>
</view>
</view>
</template>
<script>
import loading0 from "./static/loading-circle.vue";
import loading1 from "./static/loading-pulse.vue";
import loading2 from "./static/loading-bounce.vue";
import loading3 from "./static/loading-eyes.vue";
import loading4 from "./static/loading-surround.vue";
import loading5 from "./static/loading-sun.vue";
import loading6 from "./static/loading-love.vue";
import loading7 from "./static/loading-sword.vue";
import loading8 from "./static/loading-atom.vue";
import loading9 from "./static/loading-gear.vue";
import loading10 from "./static/loading-radar.vue";
import loading11 from "./static/loading-annulus.vue";
import loading12 from "./static/loading-wobble.vue";
import loading13 from "./static/loading-equal.vue";
import loading14 from "./static/loading-photo.vue";
import loading15 from "./static/loading-locating.vue";
export default {
name: "zero-loading",
components: {
loading0,
loading1,
loading2,
loading3,
loading4,
loading5,
loading6,
loading7,
loading8,
loading9,
loading10,
loading11,
loading12,
loading13,
loading14,
loading15,
},
props: {
type: {
type: String,
default: "atom",
},
position: {
type: String,
default: "fixed",
},
zIndex: {
type: Number,
default: 9,
},
mask: {
type: Boolean,
default: false,
},
maskOpacity: {
type: Number,
default: 0.1,
},
maskMini: {
type: Boolean,
default: false,
},
maskDark: {
type: Boolean,
default: true,
},
color: {
type: String,
default: "#0396FF",
},
showText: {
type: Boolean,
default: false,
},
text: {
type: String,
default: "加载中...",
},
textSize: {
type: String,
default: "28rpx",
},
textColor: {
type: String,
default: "#333333",
},
textGap: {
type: String,
default: "40rpx",
},
},
data() {
return {};
},
methods: {
handleClick() {
this.$emit("click");
},
},
};
</script>
<style lang="scss" scoped>
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
}
.tips {
// margin-top: 40rpx;
text-align: center;
}
.mask {
z-index: 999 !important;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 100vh;
width: 100vw;
background: rgba(255, 255, 255, var(--opacity));
transform: translate(0, 0);
}
.mask-mini {
height: 300rpx;
width: 300rpx;
border-radius: 20rpx;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.mask-dark {
background: rgba(7, 17, 27, var(--opacity));
}
</style>

View File

@@ -0,0 +1,83 @@
{
"id": "zero-loading",
"displayName": "zero-loading(加载动画)",
"version": "1.4.2",
"description": "纯css加载动画, 一个标签元素即可实现炫酷的全屏loading效果,支持vue2,vue3",
"keywords": [
"loading",
"加载动画",
"css动画",
"加载"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "u",
"app-nvue": "u",
"app-harmony": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "u",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@@ -0,0 +1,69 @@
# zero-loading
> 仅测试于 vue2, vue3, 微信小程序. 其他平台自行测试
## 使用方法
导入 `uni_modules` 后直接使用即可
提供多种加载动画类型,传入 type 改变 loading 样式,不传默认 circle
### 全屏使用
```html
<zero-loading v-if="loading"></zero-loading>
```
### 局部使用
**父元素的 `position` 记得改为 `relative` 不然可能影响效果**
```html
<zero-loading type="pulse" position="absolute"></zero-loading>
```
## 参数说明
| 参数 | 类型 | 默认值 | 描述 |
| ----------- | -------- | --------- | ---------------------------------------------- |
| type | String | atom | 样式 |
| position | String | fixed | 定位方式 |
| zIndex | Number | 9 | |
| mask | Boolean | false | 是否需要遮罩 (默认为全屏遮罩,背景色默认为黑色) |
| maskOpacity | Number | 0.1 | 遮罩透明度 |
| maskMini | Boolean | false | 传入 true 时,使用小遮罩 |
| maskDark | Boolean | true | 传入 false 时,遮罩背景色为白色 |
| color | String | #0396FF | 自定义颜色,仅部分支持 |
| showText | showText | false | 是否显示文字 |
| text | String | 加载中... | 文本内容 |
| textSize | String | 28rpx | 文字大小 |
| textColor | String | #333333 | 文字颜色 |
| textGap | String | 40rpx | 文字与 loading 动画的间距 |
### type 可选值:
| type 值 | 描述 |
| -------- | ----------------- |
| locating | 定位 (自定义颜色) |
| photo | 照片 (自定义颜色) |
| equal | 等边 (自定义颜色) |
| wobble | 摇摆 (自定义颜色) |
| annulus | 圆环 (自定义颜色) |
| sword | 剑气 (自定义颜色) |
| atom | 原子 (自定义颜色) |
| pulse | 脉冲 (自定义颜色) |
| circle | 圆圈 (自定义颜色) |
| eyes | 眼睛 |
| surround | 环绕 |
| bounce | 弹跳 |
| radar | 雷达 |
| gear | 齿轮 |
| love | 爱心 |
| sun | 太阳 |
插件预览:
![code](https://cdn.zerojs.cn/image/common/code-z_1722414660881_1.jpg?imageMogr2/thumbnail/200x)
> 小程序搜索: 零技术
> 预览的小程序不一定能及时更新当前插件