开头
下午群里小伙伴发了个链接,我好奇点进去看了下,结果出现了下面这个动画效果,觉得超好玩,刚好七夕了,我们可以模仿下给女朋友/老婆/女神做一个表白用
链接地址:https://buhuibaidu.me/?s=Peter%20%E8%80%81%E5%85%AC
如果没有女朋友的话,就先找一个临时的吧,实在不行就男朋友,总之把这次学会的技术要用起来
拆解需求
提前准备一段感人的话,例如:Peter老公我爱你!!我要给你生孩子!!
输出一个链接
让女朋友/老婆/女神通过这个链接可以看到一个告白过程(打字)的效果
实现
首先准备一个html结构
<div className="main"></div>
初始化样式
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
#root {
width: 100%;
height: 100%;
overflow: hidden;
align-items: center;
justify-content: center;
background-color: black;
}
.main {
width: 100%;
height: 100%;
padding: 10px;
box-sizing: border-box;
line-height: 30px;
color: #ff2400;
font-size: 15px;
p {
text-indent: 30px;
}
}
}
这里要先讲讲,打字机效果的实现原理:
选定特定的dom节点用作展示字符
获取一段需要实现效果的字符串
设置好打字机效果的时间间隔
每隔上述特定的时间间隔就通过substring api截取不同位置的字符串,然后塞入对应dom节点中,例如:
str:'在很久很久以前,你拥有我,我拥有你'
1s -> 在
1s -> 在很
3s -> 在很久
...
这样就实现了打字机效果:
完整代码:
const typeWriter = {
msg: "",
len: function () {
return this.msg.length;
},
seq: 0,
speed: 100, //打字时间(ms)
type: function () {
const _this = this;
document.querySelector(".main").innerHTML = _this.msg.substring(
0,
_this.seq
);
if (_this.seq == _this.len()) {
_this.seq = 0;
clearTimeout(timer);
} else {
_this.seq++;
timer = setTimeout(function () {
_this.type();
}, this.speed);
}
},
};
const msg = "在很久很久以前,你拥有我,我拥有你";
typeWriter.msg = msg;
typeWriter.type();
有了告白,加点纯css效果实现的烟花
先准备好dom节点
<div id="container">
<div className="firework-grp">
<div className="firework pos1 ">
<div className="drops-grp">
<span className="drop drop-1"></span>
<span className="drop drop-2"></span>
<span className="drop drop-3"></span>
<span className="drop drop-4"></span>
</div>
</div>
</div>
</div>
补上css
样式,通过@keyframes去控制关键帧
html,
body {
background-color: #3b3637;
position: relative;
width: 100%;
height: 100%;
}
#container {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
}
.firework-grp {
display: block;
width: 100%;
height: 100%;
position: absolute;
}
.firework {
font-size: 10px;
display: block;
width: 8.5em;
height: 8.5em;
position: absolute;
}
/*位置,颜色,大小都可调*/
.pos1 {
left: 10%;
top: 5%;
color: #f44336;
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
.pos2 {
left: 65%;
top: 10%;
color: #ffc107;
-webkit-transform: scale(0.6);
transform: scale(0.6);
}
.pos3 {
left: 60%;
top: 35%;
color: #f44336;
-webkit-transform: scale(0.8);
transform: scale(0.8);
}
.pos4 {
left: 15%;
top: 30%;
color: #ffc107;
-webkit-transform: scale(1);
transform: scale(1);
}
/*烟花*/
.drops-grp {
display: block;
width: 8.5em;
height: 8.5em;
position: absolute;
}
.drops-grp2 {
display: block;
width: 8.5em;
height: 8.5em;
position: absolute;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.drop {
display: block;
width: 1em;
height: 2em;
overflow: hidden;
position: absolute;
opacity: 0;
}
.drop:before {
content: "";
display: block;
width: 1em;
height: 1em;
background: currentColor;
border-radius: 50%;
}
.drop:after {
content: "";
display: block;
position: relative;
top: -0.4em;
width: 0;
height: 0;
border-top: 1.4em solid currentColor;
border-left: 0.5em solid transparent;
border-right: 0.5em solid transparent;
}
/*烟花绽放的速度,次数,方式也可以调节*/
.drop-1 {
left: 3.75em;
top: 0;
-webkit-animation: drop1anim 1.5s ease-in-out infinite;
animation: drop1anim 1.5s ease-in-out infinite;
}
.drop-2 {
top: 3.25em;
right: 0;
-webkit-animation: drop2anim 1.5s ease-in-out infinite;
animation: drop2anim 1.5s ease-in-out infinite;
}
.drop-3 {
left: 3.75em;
bottom: 0;
-webkit-animation: drop3anim 1.5s ease-in-out infinite;
animation: drop3anim 1.5s ease-in-out infinite;
}
.drop-4 {
top: 3.25em;
left: 0;
-webkit-animation: drop4anim 1.5s ease-in-out infinite;
animation: drop4anim 1.5s ease-in-out infinite;
}
/*延迟时间*/
.delay1 .drop {
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}
.delay2 .drop {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
/*动画*/
@-webkit-keyframes drop1anim {
0% {
top: 3.25em;
opacity: 0;
-webkit-transform: scale(0.3);
transform: scale(0.3);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
top: -0.75em;
opacity: 0;
-webkit-transform: scale(0.3);
transform: scale(0.3);
}
}
@keyframes drop1anim {
0% {
top: 3.25em;
opacity: 0;
-webkit-transform: scale(0.3);
transform: scale(0.3);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
top: -0.75em;
opacity: 0;
-webkit-transform: scale(0.3);
transform: scale(0.3);
}
}
@-webkit-keyframes drop2anim {
0% {
right: 3.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(90deg);
transform: scale(0.3) rotate(90deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(90deg);
transform: scale(1) rotate(90deg);
}
100% {
right: -0.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(90deg);
transform: scale(0.3) rotate(90deg);
}
}
@keyframes drop2anim {
0% {
right: 3.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(90deg);
transform: scale(0.3) rotate(90deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(90deg);
transform: scale(1) rotate(90deg);
}
100% {
right: -0.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(90deg);
transform: scale(0.3) rotate(90deg);
}
}
@-webkit-keyframes drop3anim {
0% {
bottom: 3.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(180deg);
transform: scale(0.3) rotate(180deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(180deg);
transform: scale(1) rotate(180deg);
}
100% {
bottom: -0.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(180deg);
transform: scale(0.3) rotate(180deg);
}
}
@keyframes drop3anim {
0% {
bottom: 3.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(180deg);
transform: scale(0.3) rotate(180deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(180deg);
transform: scale(1) rotate(180deg);
}
100% {
bottom: -0.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(180deg);
transform: scale(0.3) rotate(180deg);
}
}
@-webkit-keyframes drop4anim {
0% {
left: 3.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(-90deg);
transform: scale(0.3) rotate(-90deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(-90deg);
transform: scale(1) rotate(-90deg);
}
100% {
left: -0.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(-90deg);
transform: scale(0.3) rotate(-90deg);
}
}
@keyframes drop4anim {
0% {
left: 3.75em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(-90deg);
transform: scale(0.3) rotate(-90deg);
}
25% {
opacity: 0;
}
50% {
opacity: 1;
-webkit-transform: scale(1) rotate(-90deg);
transform: scale(1) rotate(-90deg);
}
100% {
left: -0.25em;
opacity: 0;
-webkit-transform: scale(0.3) rotate(-90deg);
transform: scale(0.3) rotate(-90deg);
}
}
实现效果: