index.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <template>
  2. <div class="card" :style="styleObj">
  3. <div class="card-borders">
  4. <div class="border-top"></div>
  5. <div class="border-right"></div>
  6. <div class="border-bottom"></div>
  7. <div class="border-left"></div>
  8. </div>
  9. <div class="card-content">
  10. <el-image :src="avatar" class="avatar"></el-image>
  11. <div class="username">{{ username }}</div>
  12. <div class="social-icons">
  13. <a
  14. v-for="(item, index) in iconArray"
  15. :key="index"
  16. class="social-icon"
  17. :href="item.url"
  18. target="_blank"
  19. >
  20. <vab-icon :icon="['fas', item.icon]" />
  21. </a>
  22. </div>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. export default {
  28. name: "VabProfile",
  29. props: {
  30. styleObj: {
  31. type: Object,
  32. default: () => {
  33. return {};
  34. },
  35. },
  36. username: {
  37. type: String,
  38. default: "",
  39. },
  40. avatar: {
  41. type: String,
  42. default: "",
  43. },
  44. iconArray: {
  45. type: Array,
  46. default: () => {
  47. return [
  48. { icon: "bell", url: "" },
  49. { icon: "bookmark", url: "" },
  50. { icon: "cloud-sun", url: "" },
  51. ];
  52. },
  53. },
  54. },
  55. data() {
  56. return {};
  57. },
  58. created() {},
  59. mounted() {},
  60. methods: {},
  61. };
  62. </script>
  63. <style lang="scss" scoped>
  64. .card {
  65. --card-bg-color: hsl(240, 31%, 25%);
  66. --card-bg-color-transparent: hsla(240, 31%, 25%, 0.7);
  67. position: relative;
  68. width: 100%;
  69. height: 100%;
  70. .card-borders {
  71. position: absolute;
  72. top: 0;
  73. left: 0;
  74. width: 100%;
  75. height: 100%;
  76. overflow: hidden;
  77. .border-top {
  78. position: absolute;
  79. top: 0;
  80. width: 100%;
  81. height: 2px;
  82. background: var(--card-bg-color);
  83. transform: translateX(-100%);
  84. animation: slide-in-horizontal 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
  85. forwards;
  86. }
  87. .border-right {
  88. position: absolute;
  89. right: 0;
  90. width: 2px;
  91. height: 100%;
  92. background: var(--card-bg-color);
  93. transform: translateY(100%);
  94. animation: slide-in-vertical 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
  95. forwards;
  96. }
  97. .border-bottom {
  98. position: absolute;
  99. bottom: 0;
  100. width: 100%;
  101. height: 2px;
  102. background: var(--card-bg-color);
  103. transform: translateX(100%);
  104. animation: slide-in-horizontal-reverse 0.8s
  105. cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
  106. }
  107. .border-left {
  108. position: absolute;
  109. top: 0;
  110. width: 2px;
  111. height: 100%;
  112. background: var(--card-bg-color);
  113. transform: translateY(-100%);
  114. animation: slide-in-vertical-reverse 0.8s
  115. cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
  116. }
  117. }
  118. .card-content {
  119. display: flex;
  120. flex-direction: column;
  121. align-items: center;
  122. height: 100%;
  123. padding: 40px 0 40px 0;
  124. background: var(--card-bg-color-transparent);
  125. opacity: 0;
  126. transform: scale(0.6);
  127. animation: bump-in 0.5s 0.8s forwards;
  128. .avatar {
  129. width: 80px;
  130. height: 80px;
  131. border: 1px solid $base-color-white;
  132. border-radius: 50%;
  133. opacity: 0;
  134. transform: scale(0.6);
  135. animation: bump-in 0.5s 1s forwards;
  136. }
  137. .username {
  138. position: relative;
  139. margin-top: 20px;
  140. margin-bottom: 20px;
  141. font-size: 26px;
  142. color: transparent;
  143. letter-spacing: 2px;
  144. animation: fill-text-white 1.2s 2s forwards;
  145. &::before {
  146. position: absolute;
  147. top: 0;
  148. left: 0;
  149. width: 100%;
  150. height: 100%;
  151. color: black;
  152. content: "";
  153. background: #35b9f1;
  154. transform: scaleX(0);
  155. transform-origin: left;
  156. animation: slide-in-out 1.2s 1.2s cubic-bezier(0.75, 0, 0, 1) forwards;
  157. }
  158. }
  159. .social-icons {
  160. display: flex;
  161. .social-icon {
  162. position: relative;
  163. display: flex;
  164. align-items: center;
  165. justify-content: center;
  166. width: 2.5em;
  167. height: 2.5em;
  168. margin: 0 15px;
  169. color: white;
  170. text-decoration: none;
  171. border-radius: 50%;
  172. @for $i from 1 through 3 {
  173. &:nth-child(#{$i}) {
  174. &::before {
  175. animation-delay: 2s + 0.1s * $i;
  176. }
  177. &::after {
  178. animation-delay: 2.1s + 0.1s * $i;
  179. }
  180. svg {
  181. animation-delay: 2.2s + 0.1s * $i;
  182. }
  183. }
  184. }
  185. &::before,
  186. &::after {
  187. position: absolute;
  188. top: 0;
  189. left: 0;
  190. width: 100%;
  191. height: 100%;
  192. content: "";
  193. border-radius: inherit;
  194. transform: scale(0);
  195. }
  196. &::before {
  197. background: #f7f1e3;
  198. animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
  199. }
  200. &::after {
  201. background: #2c3e50;
  202. animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
  203. }
  204. svg {
  205. z-index: 99;
  206. transform: scale(0);
  207. animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
  208. }
  209. }
  210. }
  211. }
  212. }
  213. @keyframes bump-in {
  214. 50% {
  215. transform: scale(1.05);
  216. }
  217. to {
  218. opacity: 1;
  219. transform: scale(1);
  220. }
  221. }
  222. @keyframes slide-in-horizontal {
  223. 50% {
  224. transform: translateX(0);
  225. }
  226. to {
  227. transform: translateX(100%);
  228. }
  229. }
  230. @keyframes slide-in-horizontal-reverse {
  231. 50% {
  232. transform: translateX(0);
  233. }
  234. to {
  235. transform: translateX(-100%);
  236. }
  237. }
  238. @keyframes slide-in-vertical {
  239. 50% {
  240. transform: translateY(0);
  241. }
  242. to {
  243. transform: translateY(-100%);
  244. }
  245. }
  246. @keyframes slide-in-vertical-reverse {
  247. 50% {
  248. transform: translateY(0);
  249. }
  250. to {
  251. transform: translateY(100%);
  252. }
  253. }
  254. @keyframes slide-in-out {
  255. 50% {
  256. transform: scaleX(1);
  257. transform-origin: left;
  258. }
  259. 50.1% {
  260. transform-origin: right;
  261. }
  262. 100% {
  263. transform: scaleX(0);
  264. transform-origin: right;
  265. }
  266. }
  267. @keyframes fill-text-white {
  268. to {
  269. color: white;
  270. }
  271. }
  272. @keyframes scale-in {
  273. to {
  274. transform: scale(1);
  275. }
  276. }
  277. </style>