关于我Blog首页打字机效果
关于我Blog首页打字机效果
如何实现首页打字机效果 我的blog:onecupof.cn
一、 用到的技术
-
JavaScript
-
CSS3=>animation (核心)
-
Vue
二、实现思路
基础实现思想 B 站有小教程我就不赘述了,主要讲讲怎么在博客中应用。
bilibili:【CSS】打字特效(opens new window)
三、在博客系统中应用
你需要知道的是在 VuePress 中,所有在 .vuepress/components 中找到的 *.vue 文件将会自动地被注册为全局的异步组件,如:
.
└─ .vuepress
└─ components
├─ demo-1.vue
├─ OtherComponent.vue
└─ Foo
└─ Bar.vue
Copied!
你可以直接使用这些组件在任意的 Markdown 文件中(组件名是通过文件名提取到的):
<demo-1/>
<OtherComponent/>
<Foo-Bar/>
Copied!
于是我们在 components 目录下新建一个 NewFont.vue
文件,并填入以下代码:
TemplateScriptStyle
<template>
<div></div>
</template>
Copied!
接下来在你的首页文件 README.md 文件中应用即可。
// ...
<NewFont />
Copied!
我的目录结构如下:
四、普通版本(.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
:root {
font-size: 20px;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
h1 {
margin: 0;
padding: 0;
/* 必须是等宽字体 */
font-family: monospace;
/* 由于是等宽字体,1ch 等于 任何数字、英文、符号的宽度 */
/* width: 1ch; */
position: relative;
/* overflow: hidden; */
/* animation: 1s typing forwards steps(13); */
}
h1::after {
content: "";
display: inline;
position: absolute;
width: 5px;
height: 2ch;
background-color: #000;
border-radius: 2px;
right: -0.5ch;
}
h1.ended::after {
animation: 1.1s cursor steps(2, jump-none) infinite;
}
h1 span {
--delay: 10s;
display: inline-block;
overflow: hidden;
width: 0ch;
animation: 0.1s text-in ease-in-out forwards;
/* animation: 0.1s text-out ease-in-out forwards; */
animation-delay: var(--delay);
}
@keyframes text-in {
from {
width: 0ch;
}
to {
width: 2ch;
}
}
@keyframes text-out {
from {
width: 2ch;
}
to {
width: 0ch;
}
}
@keyframes cursor {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body>
<script>
let strs = [
{
title: "没有梦想,和咸鱼有什么区别",
stop: 5,
},
{
title: "没有什么能够顾阻你,前进的步伐",
stop: 10,
// stop: [4, 13]
},
];
// 当前进行到第几行
let currentIndex = 0;
let h1 = null;
let spans = null;
setTimeout(() => {
h1 = document.createElement("h1");
document.body.appendChild(h1);
init();
}, 2000);
function init() {
if (currentIndex == strs.length) {
currentIndex = 0;
}
h1.innerHTML = strs[currentIndex].title;
h1.innerHTML = h1.textContent.replace(/\S/g, "<span>$&</span>");
let delay = 0;
spans = [...document.querySelectorAll("span")];
spans.forEach((span, i) => {
delay += 0.1;
if (strs[currentIndex].stop instanceof Array) {
if (strs[currentIndex].stop.includes(i)) {
delay += 0.3;
}
} else {
if (strs[currentIndex].stop == i) {
delay += 0.3;
}
}
span.style.setProperty("--delay", `${delay}s`);
});
h1.addEventListener("animationend", lastEnd);
}
function lastEnd(e) {
if (e.target == document.querySelector("h1 span:last-child")) {
h1.classList.add("ended");
setTimeout(() => {
h1.removeEventListener("animationend", lastEnd);
let delay = 0;
spans.reverse().forEach((span, i) => {
h1.classList.remove("ended");
span.style.width = "2ch";
span.style.animation = "0.1s text-out ease-in-out forwards";
delay += 0.05;
// 回去停顿功能
// if (strs[currentIndex].stop instanceof Array) {
// if (strs[currentIndex].stop.includes(spans.length - i)) {
// delay += 0.3
// }
// } else {
// if (strs[currentIndex].stop == spans.length - i) {
// delay += 0.3
// }
// }
span.style.animationDelay = `${delay}s`;
});
h1.addEventListener("animationend", firstEnd);
}, 2000);
}
}
function firstEnd(e) {
if (e.target == document.querySelector("h1 span:first-child")) {
spans.forEach((item) => {
item.remove();
});
h1.removeEventListener("animationend", firstEnd);
currentIndex++;
// h1.classList.add('ended')
// h1.classList.remove('ended')
init();
}
}
</script>
</body>
</html>
Copied!
五、效果
转载自:https://juejin.cn/post/7181844397883932729