diff options
Diffstat (limited to 'src/site/components/loading')
| -rw-r--r-- | src/site/components/loading/CubeShadow.vue | 48 | ||||
| -rw-r--r-- | src/site/components/loading/Origami.vue | 121 | ||||
| -rw-r--r-- | src/site/components/loading/PingPong.vue | 98 | ||||
| -rw-r--r-- | src/site/components/loading/RotateSquare.vue | 87 |
4 files changed, 354 insertions, 0 deletions
diff --git a/src/site/components/loading/CubeShadow.vue b/src/site/components/loading/CubeShadow.vue new file mode 100644 index 0000000..af31dac --- /dev/null +++ b/src/site/components/loading/CubeShadow.vue @@ -0,0 +1,48 @@ +<template> + <div :style="styles" + class="spinner spinner--cube-shadow" /> +</template> + +<script> +export default { + props: { + size: { + type: String, + default: '60px' + }, + background: { + type: String, + default: '#9C27B0' + }, + duration: { + type: String, + default: '1.8s' + } + }, + computed: { + styles() { + return { + width: this.size, + height: this.size, + backgroundColor: this.background, + animationDuration: this.duration + }; + } + } +}; +</script> + +<style lang="scss" scoped> + .spinner{ + animation: cube-shadow-spinner 1.8s cubic-bezier(0.75, 0, 0.5, 1) infinite; + } + @keyframes cube-shadow-spinner { + 50% { + border-radius: 50%; + transform: scale(0.5) rotate(360deg); + } + 100% { + transform: scale(1) rotate(720deg); + } + } +</style> diff --git a/src/site/components/loading/Origami.vue b/src/site/components/loading/Origami.vue new file mode 100644 index 0000000..d1b523d --- /dev/null +++ b/src/site/components/loading/Origami.vue @@ -0,0 +1,121 @@ +<template> + <div :style="styles" + class="spinner spinner-origami"> + <div :style="innerStyles" + class="spinner-inner loading"> + <span class="slice" /> + <span class="slice" /> + <span class="slice" /> + <span class="slice" /> + <span class="slice" /> + <span class="slice" /> + </div> + </div> +</template> + +<script> +export default { + props: { + size: { + type: String, + default: '40px' + } + }, + computed: { + innerStyles() { + let size = parseInt(this.size); + return { transform: `scale(${(size / 60)})` }; + }, + styles() { + return { + width: this.size, + height: this.size + }; + } + } +}; +</script> + +<style lang="scss" scoped> +@import '../../styles/colors.scss'; + +@for $i from 1 through 6 { + @keyframes origami-show-#{$i}{ + from{ + transform: rotateZ(60* $i + deg) rotateY(-90deg) rotateX(0deg); + border-left-color: #31855e; + } + } + @keyframes origami-hide-#{$i}{ + to{ + transform: rotateZ(60* $i + deg) rotateY(-90deg) rotateX(0deg); + border-left-color: #31855e; + } + } + + @keyframes origami-cycle-#{$i} { + + $startIndex: $i*5; + $reverseIndex: (80 - $i*5); + + #{$startIndex * 1%} { + transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0deg); + border-left-color: #31855e; + } + #{$startIndex + 5%}, + #{$reverseIndex * 1%} { + transform: rotateZ(60* $i + deg) rotateY(0) rotateX(0deg); + border-left-color: #41b883; + } + + #{$reverseIndex + 5%}, + 100%{ + transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0deg); + border-left-color: #31855e; + } + } +} + +.spinner{ + display: flex; + justify-content: center; + align-items: center; + * { + line-height: 0; + box-sizing: border-box; + } +} +.spinner-inner{ + display: block; + width: 60px; + height: 68px; + .slice { + border-top: 18px solid transparent; + border-right: none; + border-bottom: 16px solid transparent; + border-left: 30px solid #f7484e; + position: absolute; + top: 0px; + left: 50%; + transform-origin: left bottom; + border-radius: 3px 3px 0 0; + } + + @for $i from 1 through 6 { + .slice:nth-child(#{$i}) { + transform: rotateZ(60* $i + deg) rotateY(0deg) rotateX(0); + animation: .15s linear .9 - $i*.08s origami-hide-#{$i} both 1; + } + } + + &.loading{ + @for $i from 1 through 6 { + .slice:nth-child(#{$i}) { + transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0); + animation: 2s origami-cycle-#{$i} linear infinite both; + } + } + } + +} +</style> diff --git a/src/site/components/loading/PingPong.vue b/src/site/components/loading/PingPong.vue new file mode 100644 index 0000000..ac33e28 --- /dev/null +++ b/src/site/components/loading/PingPong.vue @@ -0,0 +1,98 @@ +<template> + <div :style="styles" + class="spinner spinner--ping-pong"> + <div :style="innerStyles" + class="spinner-inner"> + <div class="board"> + <div class="left"/> + <div class="right"/> + <div class="ball"/> + </div> + </div> + </div> +</template> + +<script> +export default { + props: { + size: { + type: String, + default: '60px' + } + }, + computed: { + innerStyles() { + let size = parseInt(this.size); + return { transform: `scale(${size / 250})` }; + }, + styles() { + return { + width: this.size, + height: this.size + }; + } + } +} +</script> + +<style lang="scss" scoped> + .spinner{ + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + * { + line-height: 0; + box-sizing: border-box; + } + } + .board { + width:250px; + position: relative; + } + .left, + .right { + height:50px; + width:15px; + background:#41b883; + display: inline-block; + position:absolute; + } + .left { + left:0; + animation: pingpong-position1 2s linear infinite; + } + .right { + right:0; + animation: pingpong-position2 2s linear infinite; + } + .ball{ + width:15px; + height:15px; + border-radius:50%; + background:#f7484e; + position:absolute; + animation: pingpong-bounce 2s linear infinite; + } + @keyframes pingpong-position1 { + 0% {top:-60px;} + 25% {top:0;} + 50% {top:60px;} + 75% {top:-60px;} + 100% {top:-60px;} + } + @keyframes pingpong-position2 { + 0% {top:60px;} + 25% {top:0;} + 50% {top:-60px;} + 75% {top:-60px;} + 100% {top:60px;} + } + @keyframes pingpong-bounce { + 0% {top:-35px;left:10px;} + 25% {top:25px;left:225px;} + 50% {top:75px;left:10px;} + 75% {top:-35px;left:225px;} + 100% {top:-35px;left:10px;} + } +</style> diff --git a/src/site/components/loading/RotateSquare.vue b/src/site/components/loading/RotateSquare.vue new file mode 100644 index 0000000..4da8300 --- /dev/null +++ b/src/site/components/loading/RotateSquare.vue @@ -0,0 +1,87 @@ +<template> + <div :style="styles" + class="spinner spinner--rotate-square-2" /> +</template> + +<script> +export default { + props: { + size: { + type: String, + default: '40px' + } + }, + computed: { + styles() { + return { + width: this.size, + height: this.size, + display: 'inline-block' + }; + } + } +}; +</script> + +<style lang="scss" scoped> +@import '../../styles/colors.scss'; + +.spinner { + position: relative; + * { + line-height: 0; + box-sizing: border-box; + } + &:before { + content: ''; + width: 100%; + height: 20%; + min-width: 5px; + background: #000; + opacity: 0.1; + position: absolute; + bottom: 0%; + left: 0; + border-radius: 50%; + animation: rotate-square-2-shadow .5s linear infinite; + } + &:after { + content: ''; + width: 100%; + height: 100%; + background: $basePink; + animation: rotate-square-2-animate .5s linear infinite; + position: absolute; + bottom:40%; + left: 0; + border-radius: 3px; + } +} + +@keyframes rotate-square-2-animate { + 17% { + border-bottom-right-radius: 3px; + } + 25% { + transform: translateY(20%) rotate(22.5deg); + } + 50% { + transform: translateY(40%) scale(1, .9) rotate(45deg); + border-bottom-right-radius: 50%; + } + 75% { + transform: translateY(20%) rotate(67.5deg); + } + 100% { + transform: translateY(0) rotate(90deg); + } +} +@keyframes rotate-square-2-shadow { + 0%, 100% { + transform: scale(1, 1); + } + 50% { + transform: scale(1.2, 1); + } +} +</style> |