- 项目初始化
- 添加滚动字幕
- 添加CSS内容和样式
- 优化代码
- 增加暂停、快速、慢速等按钮
- 代码重构
- 完整代码
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
项目初始化
复制上次的皮卡丘 |
---|

那个熟悉的pikachu项目,然后使用parcel运行起来
代码语言:javascript复制MacBook-pro:pikachu-2 driverzeng$ parcel src/index.html
打开浏览器访问

添加一个html页面 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<script src="pikachu.js"></script>
</body>
</html>
引入js,然后创建出来js文件

然后用parcel启动pikachu.html
代码语言:javascript复制MacBook-pro:pikachu-2 driverzeng$ parcel src/pikachu.html
添加滚动字幕
接下来我们一步一步的实现功能,首先在html中创建一个div
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo"></div>
<script src="pikachu.js"></script>
</body>
</html>
然后我们使用JS往这个div中,插入字...插它
代码语言:javascript复制let n = 1
demo.innerHTML = n

网页上就会出来一个 1
接下来,我们实现让这个数字,自增
代码语言:javascript复制let n = 1
demo.innerHTML = n
setInterval(()=>{
n =1
demo.innerHTML = n
},1000)

它在自己长大...1秒钟,长大一次
既然n可以变,那我们就来个字符串。
代码语言:javascript复制const string = '大家好,我是曾老湿,我们来测试一下页面打字的效果。'
let n = 1
demo.innerHTML = string.substring(0,n)
setInterval(()=>{
n =1
demo.innerHTML = string.substring(0,n)
},1000)


速度有点慢,可以自己调整
但是这样是有bug的,现在我们看不到,后台的控制台可以看到
代码语言:javascript复制const string = '大家好,我是曾老湿,我们来测试一下页面打字的效果。'
let n = 1
demo.innerHTML = string.substring(0,n)
setInterval(()=>{
console.log(`${n}:${string.substring(0,n)}`)
n =1
demo.innerHTML = string.substring(0,n)
},1000)

这个n一直在输出内容...即便是页面的字打完了,后台的n还在变化。我们需要它打完字就停住,否则以后日志没法看。
计时器,每次都会返回一个id,所以我们判断一下字符串的长度,然后把计时器取消即可。
代码语言:javascript复制const string = '大家好,我是曾老湿,我们来测试一下页面打字的效果。'
let n = 1
demo.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
console.log(`${n}:${string.substring(0,n)}`)
n =1
demo.innerHTML = string.substring(0,n)
if(n>string.length){
window.clearInterval(id)
return
}
},300)

可以看的到,根据字符串长度就能判断出来,然后让它停止。
添加CSS内容和样式
接下来,我们把皮卡丘的html嵌入这个html的div中
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo"></div>
<div id="demo2">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>
页面上什么都 看不出来,接下来我们就是偷偷摸摸的插入CSS,但是这个css在js中插入到html里面,把刚才的那一句话
代码语言:javascript复制const string = `
body{
background: red;
}
`
let n = 1
demo.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
console.log(`${n}:${string.substring(0,n)}`)
n =1
demo.innerHTML = string.substring(0,n)
if(n>string.length){
window.clearInterval(id)
return
}
},200)

字出来了,但是我们想要的css样式改变没有出来。
那我们就加一个style标签
代码语言:javascript复制const string = `
<style>
body{
background: red;
}
</style>
`
let n = 1
demo.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
console.log(`${n}:${string.substring(0,n)}`)
n =1
demo.innerHTML = string.substring(0,n)
if(n>string.length){
window.clearInterval(id)
return
}
},200)

这就太刺激了,我们居然可以偷偷摸摸的加入css的样式
接下来我想同时写入css内容并且样式一起跟着改变,我们需要再来个div
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo"></div>
<div id="demo2"></div>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>
代码语言:javascript复制const string = `
<style>
body{
background: red;
}
</style>
`
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
if(n>string.length){
window.clearInterval(id)
return
}
},50)

那我们 把皮卡丘的CSS代码直接复制过来
代码语言:javascript复制const string = `
<style>
*{box-sizing: border-box;margin: 0;padding: 0;}
*::before,*::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 100vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
</style>
`
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
if(n>string.length){
window.clearInterval(id)
return
}
},0)
卧槽,居然阔以,那就很开熏了

但是皮卡丘在下面,字体在上面,一上一下,也不知道他俩想干嘛~~~ 想。
优化代码
绝对定位 |
---|
首先我们需要把皮卡丘绝对定位
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo2"></div>
<div id="demo"></div>
<style>
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

不会往下压了,但是代码不滚动了,我们看不到,所以我们需要一个滚动条,我们先把demo2隐藏
添加滚动条 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo2"></div>
<div id="demo"></div>
<style>
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

保证代码在框内 |
---|
隐藏后,我们给代码部分价格border,发现,代码超出了边框部分。所以我们需要overflow一下
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo2"></div>
<div id="demo"></div>
<style>
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow: scroll;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

有了滚动条,但是滚动条好丑啊,并且代码也不会动,所以我们 要把滚动条拉下去
下拉滚动条 |
---|
const string = `
<style>
*{box-sizing: border-box;margin: 0;padding: 0;}
*::before,*::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 100vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
</style>
`
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = 999999
},0)
先简单粗暴设置一个 999999

这样代码就一直在滚动了,滚动条一直自动往下拉,但是999999太粗暴了,一看就不是专业前端写的,所以我们要 保证,滚动条和内容的高度保持一致即可。

我们发现,使用 demo.scrollHeight
可以获取到内容的高度,那就加到代码里
demo.scrollTop = demo.scrollHeight
这样即可,但是其实也是错的,因为滚动条的高度也是有的,但是至少这样能拉到底,而且不那么low
隐藏滚动条 |
---|
我们 把overflow改成hidden,给他隐藏起来
代码语言:javascript复制#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow: hidden;
}

代码依然可以滚动 ,由此可见,对于JS来说,有没有滚动条都可以滚动,但是用户现在是没有办法,上下滚动代码了。
隐藏滚动条,但是让用户可以滚动 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<div id="demo2"></div>
<div id="demo"></div>
<style>
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>
代码不显示style,要不太丑 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<style id="demo2"></style>
<div id="demo"></div>
<style>
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>
代码语言:javascript复制const string = `
*{box-sizing: border-box;margin: 0;padding: 0;}
*::before,*::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 100vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
`
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},0)
增加暂停、快速、慢速等按钮
先添加按钮 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<style id="demo2"></style>
<div id="demo"></div>
<div id="buttons">
<button id="btnPause">暂停</button>
<button id="btnPlay">播放</button>
<button id="btnSlow">慢速</button>
<button id="btnNormal">中速</button>
<button id="btnFast">快速</button>
</div>
<style>
#buttons{
position: fixed;
right: 0;
top: 0;
z-index: 10;
display: flex;
flex-direction: column;
margin-top: 10px;
margin-right: 10px;
}
#buttons>button{
margin-bottom: 10px;
}
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

修改按钮bug |
---|
添加完按钮会发现 ,刷新页面,先变大再变小,为啥呢?因为之前皮卡丘的style.css里面css的reset,都是*,所以我们需要修改一下 。
代码语言:javascript复制const string = `
.sink *{box-sizing: border-box;margin: 0;padding: 0;}
.sink *::before,.skin *::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 50vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
`
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},0)
做html中css的reset |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<style id="demo2"></style>
<div id="demo"></div>
<div id="buttons">
<button id="btnPause">暂停</button>
<button id="btnPlay">播放</button>
<button id="btnSlow">慢速</button>
<button id="btnNormal">中速</button>
<button id="btnFast">快速</button>
</div>
<style>
* {box-sizing: border-box;}
*::before,*::after {box-sizing: border-box;}
#buttons{
position: fixed;
right: 0;
top: 0;
z-index: 10;
display: flex;
flex-direction: column;
margin-top: 10px;
margin-right: 10px;
}
#buttons>button{
margin-bottom: 10px;
}
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

修改按钮大小 |
---|
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<style id="demo2"></style>
<div id="demo"></div>
<div id="buttons">
<button id="btnPause">暂停</button>
<button id="btnPlay">播放</button>
<button id="btnSlow">慢速</button>
<button id="btnNormal">中速</button>
<button id="btnFast">快速</button>
</div>
<style>
* {box-sizing: border-box;}
*::before,*::after {box-sizing: border-box;}
#buttons{
position: fixed;
right: 0;
top: 0;
z-index: 10;
display: flex;
flex-direction: column;
margin-top: 10px;
margin-right: 10px;
}
#buttons>button{
margin-bottom: 10px;
padding: 4px 8px;
}
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>

导出代码 |
---|
突然发现皮卡丘的CSS好长还不能折叠,我们再优化一下。
我们单独创建一个pikachu_css.js
文件存储css的字符串
const string = `
.sink *{box-sizing: border-box;margin: 0;padding: 0;}
.sink *::before,.skin *::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 50vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
`
export default string
然后再用pikachu.js导入那个文件
代码语言:javascript复制import string from './pikachu_css.js'
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},0)
实现暂停功能 |
---|
暂停其实就是停下当前的计时器。
代码语言:javascript复制import string from './pikachu_css.js'
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let id = setInterval(()=>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},0)
btnPause.onclick = () =>{
window.clearInterval(id)
return
}
实现播放功能 |
---|
思路就是,刚才已经取消了,就跟你今天闹钟响了,巴扎黑~~给它砸了,那么请问,明天还会响么?不会,那么怎么办?买个新的呗。
代码语言:javascript复制import string from './pikachu_css.js'
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
const run = () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
}
let id = setInterval(()=>{
run()
},0)
btnPause.onclick = () =>{
window.clearInterval(id)
}
btnPlay.onclick = () =>{
id = setInterval(()=>{
run()
},0)
}
实现播放速度功能 |
---|
import string from './pikachu_css.js'
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let time = 100
const run = () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
}
let id = setInterval(()=>{
run()
},time)
btnPause.onclick = () =>{
window.clearInterval(id)
}
btnPlay.onclick = () =>{
id = setInterval(()=>{
run()
},time)
}
btnSlow.onclick = () =>{
window.clearInterval(id)
time = 500
id = setInterval(() => {
run()
},time)
}
btnNormal.onclick = () =>{
window.clearInterval(id)
time = 100
id = setInterval(() => {
run()
},time)
}
btnFast.onclick = () =>{
window.clearInterval(id)
time = 0
id = setInterval(() => {
run()
},time)
}
代码重构
代码语言:javascript复制import string from './pikachu_css.js'
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let time = 100
const run = () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
}
const play =() =>{
id = setInterval(run,time)
}
const pause = () =>{
window.clearInterval(id)
}
let id = play()
btnPause.onclick = () =>{
pause()
}
btnPlay.onclick = () =>{
id = play()
}
btnSlow.onclick = () =>{
pause()
time = 500
play()
}
btnNormal.onclick = () =>{
pause()
time = 100
play()
}
btnFast.onclick = () =>{
pause()
time = 0
play()
}
面向对象优化 |
---|
import string from './pikachu_css.js'
const demo = document.querySelector('#demo')
const demo2 = document.querySelector('#demo2')
let n = 1
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
let time = 100
const player = {
run: () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},
play: () =>{
return setInterval(player.run,time)
},
pause: () =>{
window.clearInterval(id)
},
slow: () =>{
player.pause()
time = 500
id = player.play()
},
normal: () =>{
player.pause()
time = 100
id = player.play()
},
fast: () =>{
player.pause()
time = 0
id = player.play()
}
}
let id = player.play()
document.querySelector('#btnPause').onclick = () =>{
player.pause()
}
document.querySelector('#btnPlay').onclick = () =>{
id = player.play()
}
document.querySelector('#btnSlow').onclick = player.slow
document.querySelector('#btnNormal').onclick = player.normal
document.querySelector('#btnFast').onclick = player.fast
添加对象初始化方法 |
---|
import string from './pikachu_css.js'
const demo = document.querySelector('#demo')
const demo2 = document.querySelector('#demo2')
let n = 1
let time = 100
let id
const player = {
init: () =>{
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
player.play()
},
run: () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},
play: () =>{
id = setInterval(player.run,time)
},
pause: () =>{
window.clearInterval(id)
},
slow: () =>{
player.pause()
time = 500
player.play()
},
normal: () =>{
player.pause()
time = 100
player.play()
},
fast: () =>{
player.pause()
time = 0
player.play()
}
}
player.init()
document.querySelector('#btnPause').onclick = player.pause
document.querySelector('#btnPlay').onclick = player.play
document.querySelector('#btnSlow').onclick = player.slow
document.querySelector('#btnNormal').onclick = player.normal
document.querySelector('#btnFast').onclick = player.fast
绑定事件 |
---|
import string from './pikachu_css.js'
const demo = document.querySelector('#demo')
const demo2 = document.querySelector('#demo2')
let n = 1
let time = 100
let id
const player = {
init: () =>{
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
player.play()
player.bindEvents()
},
bindEvents: () =>{
document.querySelector('#btnPause').onclick = player.pause
document.querySelector('#btnPlay').onclick = player.play
document.querySelector('#btnSlow').onclick = player.slow
document.querySelector('#btnNormal').onclick = player.normal
document.querySelector('#btnFast').onclick = player.fast
},
run: () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},
play: () =>{
id = setInterval(player.run,time)
},
pause: () =>{
window.clearInterval(id)
},
slow: () =>{
player.pause()
time = 500
player.play()
},
normal: () =>{
player.pause()
time = 100
player.play()
},
fast: () =>{
player.pause()
time = 0
player.play()
}
}
player.init()
简化id |
---|
import string from './pikachu_css.js'
const demo = document.querySelector('#demo')
const demo2 = document.querySelector('#demo2')
let n = 1
let time = 100
let id
const player = {
init: () =>{
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
player.play()
player.bindEvents()
},
bindEvents: () =>{
const hashTable = {
'#btnPause' : player.pause,
'#btnPlay' : player.play,
'#btnSlow' : player.slow,
'#btnNormal' : player.normal,
'#btnFast' : player.fast
}
for(let key in hashTable){
document.querySelector(key).onclick = hashTable[key]
}
},
run: () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},
play: () =>{
id = setInterval(player.run,time)
},
pause: () =>{
window.clearInterval(id)
},
slow: () =>{
player.pause()
time = 500
player.play()
},
normal: () =>{
player.pause()
time = 100
player.play()
},
fast: () =>{
player.pause()
time = 0
player.play()
}
}
player.init()
遍历事件,并且防止添加原型 |
---|
import string from './pikachu_css.js'
const demo = document.querySelector('#demo')
const demo2 = document.querySelector('#demo2')
let n = 1
let time = 100
let id
const player = {
init: () =>{
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
player.play()
player.bindEvents()
},
events: {
'#btnPause' : 'pause',
'#btnPlay' : 'play',
'#btnSlow' : 'slow',
'#btnNormal' : 'normal',
'#btnFast' : 'fast'
},
bindEvents: () =>{
for(let key in player.events) if(player.events.hasOwnProperty(key)){
const value = player.events[key]
document.querySelector(key).onclick = player[value]
}
},
run: () =>{
n =1
if(n>string.length){
window.clearInterval(id)
return
}
demo.innerText = string.substring(0,n)
demo2.innerHTML = string.substring(0,n)
demo.scrollTop = demo.scrollHeight
},
play: () =>{
id = setInterval(player.run,time)
},
pause: () =>{
window.clearInterval(id)
},
slow: () =>{
player.pause()
time = 500
player.play()
},
normal: () =>{
player.pause()
time = 100
player.play()
},
fast: () =>{
player.pause()
time = 0
player.play()
}
}
player.init()
老手代码 |
---|
import string from './pikachu_css.js'
const player = {
id : undefined,
time : 100,
ui: {
demo : document.querySelector('#demo'),
demo2 : document.querySelector('#demo2')
},
n : 1,
init: () =>{
player.ui.demo.innerText = string.substring(0,player.n)
player.ui.demo2.innerHTML = string.substring(0,player.n)
player.play()
player.bindEvents()
},
events: {
'#btnPause' : 'pause',
'#btnPlay' : 'play',
'#btnSlow' : 'slow',
'#btnNormal' : 'normal',
'#btnFast' : 'fast'
},
bindEvents: () =>{
for(let key in player.events) if(player.events.hasOwnProperty(key)){
const value = player.events[key]
document.querySelector(key).onclick = player[value]
}
},
run: () =>{
player.n =1
if(player.n>string.length){
window.clearInterval(player.id)
return
}
player.ui.demo.innerText = string.substring(0,player.n)
player.ui.demo2.innerHTML = string.substring(0,player.n)
player.ui.demo.scrollTop = player.ui.demo.scrollHeight
},
play: () =>{
player.id = setInterval(player.run,player.time)
},
pause: () =>{
window.clearInterval(player.id)
},
slow: () =>{
player.pause()
player.time = 500
player.play()
},
normal: () =>{
player.pause()
player.time = 100
player.play()
},
fast: () =>{
player.pause()
player.time = 0
player.play()
}
}
player.init()

完整代码
pikachu.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pikachu的制作过程-曾老湿</title>
</head>
<body>
<style id="demo2"></style>
<div id="demo"></div>
<div id="buttons">
<button id="btnPause">暂停</button>
<button id="btnPlay">播放</button>
<button id="btnSlow">慢速</button>
<button id="btnNormal">中速</button>
<button id="btnFast">快速</button>
</div>
<style>
* {box-sizing: border-box;}
*::before,*::after {box-sizing: border-box;}
#buttons{
position: fixed;
right: 0;
top: 0;
z-index: 10;
display: flex;
flex-direction: column;
margin-top: 10px;
margin-right: 10px;
}
#buttons>button{
margin-bottom: 10px;
padding: 4px 8px;
}
#demo2{
display: none;
}
#demo{
position: fixed;
height: 50vh;
top: 0;
left: 0;
width: 100%;
border: 1px solid red;
overflow-y: auto;
}
#demo::-webkit-scrollbar{
display: none;
}
#html{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50vh;
}
</style>
<div id="html">
<div class="skin">
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose">
<div class="yuan"></div>
</div>
<div class="face left"></div>
<div class="face right"></div>
<div class="mouth">
<div class="up">
<div class="lip left"></div>
<div class="lip right"></div>
</div>
<div class="down">
<div class="yuan1">
<div class="yuan2"></div>
</div>
</div>
</div>
</div>
</div>
<script src="pikachu.js"></script>
</body>
</html>
pikachu.js
代码语言:javascript复制import string from './pikachu_css.js'
const player = {
id : undefined,
time : 100,
ui: {
demo : document.querySelector('#demo'),
demo2 : document.querySelector('#demo2')
},
n : 1,
init: () =>{
player.ui.demo.innerText = string.substring(0,player.n)
player.ui.demo2.innerHTML = string.substring(0,player.n)
player.play()
player.bindEvents()
},
events: {
'#btnPause' : 'pause',
'#btnPlay' : 'play',
'#btnSlow' : 'slow',
'#btnNormal' : 'normal',
'#btnFast' : 'fast'
},
bindEvents: () =>{
for(let key in player.events) if(player.events.hasOwnProperty(key)){
const value = player.events[key]
document.querySelector(key).onclick = player[value]
}
},
run: () =>{
player.n =1
if(player.n>string.length){
window.clearInterval(player.id)
return
}
player.ui.demo.innerText = string.substring(0,player.n)
player.ui.demo2.innerHTML = string.substring(0,player.n)
player.ui.demo.scrollTop = player.ui.demo.scrollHeight
},
play: () =>{
player.id = setInterval(player.run,player.time)
},
pause: () =>{
window.clearInterval(player.id)
},
slow: () =>{
player.pause()
player.time = 500
player.play()
},
normal: () =>{
player.pause()
player.time = 100
player.play()
},
fast: () =>{
player.pause()
player.time = 0
player.play()
}
}
player.init()
pikachu_css.js
代码语言:javascript复制const string = `
.sink *{box-sizing: border-box;margin: 0;padding: 0;}
.sink *::before,.skin *::after{box-sizing: border-box;}
.skin{
position: relative;
background: #ffe600;
height: 50vh;
}
.nose{
border: 10px solid #000;
border-color: #000 transparent transparent transparent;
position: absolute;
left: 50%;
top: 145px;
margin-left: -10px;
z-index: 10;
}
@keyframes wave{
0%{
transform: rotate(0deg);
}
33%{
transform: rotate(5deg);
}
66%{
transform: rotate(-5deg);
}
100%{
transform: rotate(0deg);
}
}
.nose:hover{
transform-origin: center bottom;
animation: wave 300ms infinite linear;
}
.yuan{
position: absolute;
width: 20px;
height: 6px;
top: -16px;
left: -10px;
border-radius: 10px 10px 0 0;
background: #000;
}
.eye{
border: 2px solid #000;
width: 64px;
height: 64px;
position: absolute;
left: 50%;
top: 100px;
margin-left: -32px;
background: #2e2e2e;
border-radius: 50%;
}
.eye::before{
content: '';
display: block;
border: 3px solid #000;
width: 30px;
height: 30px;
background:#fff;
border-radius: 50%;
position: relative;
left: 5px;
top: 3px;
}
.eye.left{
transform: translateX(-100px);
}
.eye.right{
transform: translateX(100px);
}
.mouth{
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 170px;
margin-left: -100px;
}
.mouth .up{
position: relative;
top: -20px;
z-index: 1;
}
.mouth .up .lip{
border: 3px solid black;
background: #ffe600;
height: 30px;
width: 100px;
border-top-color: transparent;
border-right-color: transparent;
position: relative;
position: absolute;
left: 50%;
margin-left: -50px;
}
.mouth .up .lip.left{
border-radius: 0 0 0 50px;
transform: rotate(-15deg) translateX(-53px);
}
.mouth .up .lip.right{
border-radius: 0 0 50px 0;
transform: rotate(15deg) translateX(53px);
}
.mouth .up .lip::before{
content: '';
display: block;
width: 7px;
height: 30px;
position: absolute;
bottom: 0;
background:#ffe600;
}
.mouth .up .lip.left::before{
right: -6px;
}
.mouth .up .lip.right::before{
left: -6px;
}
.mouth .down{
height: 180px;
position: absolute;
top: 5px;
width: 100%;
overflow: hidden;
}
.mouth .down .yuan1{
border: 3px solid black;
width: 150px;
height: 1000px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -75px;
border-radius: 75px / 300px;
background: #9b000a;
overflow: hidden;
}
.mouth .down .yuan1 .yuan2{
width: 200px;
height: 300px;
background: #ff485f;
position: absolute;
bottom: -155px;
left: 50%;
margin-left: -100px;
border-radius: 100px;
}
.face{
position: absolute;
left: 50%;
border: 3px solid black;
width: 88px;
height: 88px;
top: 200px;
margin-left: -44px;
z-index: 3;
background: #ff0000;
border-radius: 50%;
}
.face > img{
position: absolute;
top: 50%;
left: 50%;
display: none;
}
.face:hover > img{
display: block;
}
.face.left{
transform: translateX(-180px);
}
.face.left > img{
transform: rotateY(180deg);
transform-origin: 0 0;
}
.face.right{
transform: translateX(180px);
}
`
export default string