上 codepen 找了一圈灵感.....
<template>
<div>
<div class="container">
<div class="text">Merry Christmas, Friends!</div>
<div class="presents">
<div class="present orange">
<div class="lid"></div>
<div class="box"></div>
<div class="bow"></div>
<div class="ribbon"></div>
</div>
<div class="present blue">
<div class="lid"></div>
<div class="box"></div>
<div class="bow"></div>
<div class="ribbon"></div>
</div>
<div class="present green">
<div class="lid"></div>
<div class="box"></div>
<div class="bow"></div>
<div class="ribbon"></div>
</div>
</div>
</div>
</div>
</template>
<script>
// 记得引入 mojs
export default {
data() {
return {
timer: null,
}
},
mounted() {
this.timer = setInterval(() => this.randomizedConfetti(), 500)
},
methods: {
randomizedConfetti() {
let randomX = Math.floor(Math.random() * (document.body.clientWidth - 300) + 0)
let randomY = Math.floor(Math.random() * (window.innerHeight - 300) + 0)
// eslint-disable-next-line no-undef
const burst = new mojs.Burst({
left: 0,
top: 0,
radius: { 0: 200 },
count: 20,
degree: 360,
children: {
fill: { white: '#f67280' },
duration: 2000,
},
}).tune({
x: randomX,
y: randomY,
})
burst.replay()
},
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
}
</script>
<style lang="scss" scoped>
@import url('https://fonts.googleapis.com/css2?family=Fredoka+One&display=swap');
$border-color: #2c3a49;
$border: 4px solid $border-color;
$border-radius: 5px;
html,
body {
overflow-x: hidden;
}
.container {
position: fixed;
top: 50%;
left: 50%;
z-index: 1000;
transform: translate(-50%, -50%);
}
.text {
min-width: 100%;
text-align: center;
color: #fda639;
// color: #ffe211;
font-family: 'Fredoka One', cursive;
text-shadow: 1px 1px $border-color;
font-size: 3em;
-webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 80%);
clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 80%);
transform: translateY(-50px);
opacity: 0;
animation-name: titleAnimation;
animation-timing-function: ease;
animation-duration: 3s;
animation-delay: 0.6s;
animation-fill-mode: forwards;
}
.presents {
opacity: 0;
animation-name: titleAnimation;
animation-timing-function: ease;
animation-duration: 3s;
animation-delay: 1.1s;
animation-fill-mode: forwards;
display: flex;
justify-content: center;
align-items: flex-end;
height: 200px;
}
@keyframes titleAnimation {
0% {
transform: translateY(-50px);
opacity: 0;
-webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 80%);
clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 80%);
}
20% {
transform: translateY(0);
opacity: 1;
-webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 15%);
clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 15%);
}
100% {
transform: translateY(0);
opacity: 1;
-webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 15%);
clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 15%);
}
}
.text .char {
animation: slide-in 1s cubic-bezier(0.5, 0, 0.5, 1) both;
animation-delay: calc(60ms * var(--char-index));
}
@keyframes slide-in {
from {
transform: translateY(-1em) rotate(-0.5turn) scale(0.5);
opacity: 0;
}
}
@mixin present($name, $positionx, $box-color, $bow-color, $dot-color, $width, $height, $z-index) {
position: relative;
left: $positionx;
width: $width;
height: $height;
z-index: $z-index;
&:hover {
animation: 0.5s #{$name};
}
.lid {
background: $box-color;
}
.box {
background-image: radial-gradient($dot-color 20%, transparent 20%),
radial-gradient($dot-color 20%, transparent 20%);
background-color: $box-color;
}
.ribbon {
background: $bow-color;
&::before {
top: 21%;
}
}
.bow {
background: $bow-color;
&::before,
&::after {
background: $bow-color;
}
}
@keyframes #{$name} {
0% {
width: $width;
height: $height;
}
30% {
width: calc(#{$width} + 10px);
height: calc(#{$height} - 10px);
}
60% {
width: calc(#{$width} - 10px);
height: calc(#{$height} + 10px);
}
100% {
width: $width;
height: $height;
}
}
}
.green {
@include present('green', -20px, #3ddc81, #f75d4c, #fff, 100px, 100px, 1);
}
.orange {
@include present('orange', 20px, #ffa726, #f75d4c, $border-color, 130px, 120px, 10);
}
.blue {
@include present('blue', 0, #1bb5fe, #3ddc81, transparent, 120px, 160px, 0);
}
.present {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
.lid {
height: 20%;
width: calc(100% + 10px);
border: $border;
border-radius: $border-radius;
box-shadow: inset 2px 2px rgba(255, 255, 255, 0.5), 5px 0 rgba(0, 0, 0, 0.15);
}
.box {
width: 100%;
height: 100%;
background-position: 0 0, 20px 20px;
background-size: 40px 40px;
border: $border;
border-top: 0;
border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
box-shadow: inset -10px 5px rgba(0, 0, 0, 0.3), 5px 0 rgba(0, 0, 0, 0.15);
}
.ribbon {
position: absolute;
top: -3px;
width: 30px;
height: calc(100% - 5px);
border: $border;
border-radius: $border-radius;
box-shadow: inset 2px 2px rgba(255, 255, 255, 0.5);
&::before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 5px;
background: rgba(0, 0, 0, 0.3);
}
}
.bow {
position: absolute;
top: -20px;
width: 20px;
height: 20px;
border: $border;
border-radius: 50%;
box-shadow: inset 2px 2px rgba(255, 255, 255, 0.5), inset -2px -5px rgba(0, 0, 0, 0.3);
&::before,
&::after {
display: block;
content: '';
position: absolute;
top: -10px;
width: 30px;
height: 30px;
border: $border;
border-radius: 50%;
box-shadow: inset 2px 2px rgba(255, 255, 255, 0.5), inset -2px -5px rgba(0, 0, 0, 0.3);
z-index: -1;
}
&::before {
left: 15px;
}
&::after {
right: 15px;
}
}
}
</style>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于