<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>番茄钟</title>
<link rel="stylesheet" href="./font-awesome.css">
<style type="text/css">
.container{
width: 100%;
height: 500px;
background-color: #0f0f0f;
}
.timer{
width: 50%;
height: 200px;
color: white;
margin: 10px auto;
border: 1px solid white;
}
.timer .minute{
width: 120px;
height: 120px;
line-height: 100px;
font-size: 100px;
}
.timer .sp{
width: 20px;
height: 120px;
line-height: 100px;
font-size: 100px;
}
.timer .seconds{
width: 120px;
height: 120px;
line-height: 100px;
font-size: 100px;
}
.controls{
width: 50%;
height: 150px;
margin: 10px auto;
border: 1px solid white;
color: white;
}
.controls>div{
display: inline-block;
width: 24%;
text-align: center;
}
.controls button{
width: 80px;
height: 22px;
color: white;
}
.input{
width: 50%;
height: 80px;
margin: 10px auto;
border: 1px solid white;
}
</style>
<script type="text/javascript">
class Pomodoro{
constructor(audio){
this.states = [
{
from:'stopped',
to:'timing',
action:'start'
},
{
from:'stopped',
to:'editing',
action:'edit'
},
{
from:'timing',
to:'paused',
action:'pause'
},
{
from:'timing',
to:'stopped',
action:'stop'
},
{
from:'paused',
to:'timing',
action:'start'
},
{
from:'paused',
to:'stopped',
action:'stop'
},
{
from:'paused',
to:'editing',
action:'edit'
},
{
from:'editing',
to:'stopped',
action:'save'
},
{
from:'editing',
to:'',
action:'cancel'
},
];
this.currentState = 'stopped';
this.totalSeconds = 25 * 60;
this.remainSeconds = this.totalSeconds;
this.timer = null;
this.audio = audio;
}
startTimer(){
this.timer = setInterval(()=>this.countdown(),1000);
}
stopTimer(){
clearInterval(this.timer);
this.timer = null;
}
countdown(){
if(this.remainSeconds == 0){
this.stopTimer();
this.audio.play();
return;
}
this.remainSeconds--;
console.log(this.remainSeconds);
}
start(){
this.currentState = 'timing';
this.startTimer();
}
stop(){
this.currentState = 'stopped';
this.remainSeconds = this.totalSeconds;
this.stopTimer();
this.audio.load();
}
pause(){
this.currentState = 'paused';
this.stopTimer();
this.audio.pause();
}
edit(){
this.currentState = 'editing';
}
save(seconds){
this.currentState = 'stopped';
this.totalSeconds = seconds * 60;
this.remainSeconds = seconds * 60;
}
cancel(){
this.currentState = this.totalSeconds === this.remainSeconds ? 'stopped':'paused';
}
get actions(){
return this.states.filter(_=>_.from === this.currentState)
.map((value)=>value.action);
}
}
</script>
</head>
<body>
<div class="container">
<div id="app">
<!-- 显示时间-->
<div class="timer">
<span class="minute">{{minutes}}</span>
<span class="sp">:</span>
<span class="seconds">{{seconds}}</span>
</div>
<!-- 控制器-->
<div class="controls">
<div v-for="item in pomodoro.actions" v-on:click="doAction(item)">
<i v-bind:class="['fa',getActionIcon(item)]"></i>
</div>
</div>
<!-- 修改时间-->
<div class="input" v-if="pomodoro.currentState === 'editing'">
<input type="number" min="1" value="25">
<!-- 倒计时结束后播放音频-->
<audio src="./1.mp3" id="audio" loop>你的浏览器不支持audio标记</audio>
</div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const audio = document.getElementById('audio');
const myPomodoro = new Pomodoro(audio);
let vm = new Vue({
el:'#app',
data:{
pomodoro: myPomodoro
},
methods:{
formatTime(time){
return (time < 10 ? '0':'') + time;
},
doAction(action){
this.pomodoro[action]();
},
getActionIcon(action){
let icons = [
{
action:'start',
icon:'fa-play',
},
{
action:'pause',
icon: 'fa-pause'
},
{
action:'stop',
icon: 'fa-stop'
},
{
action:'edit',
icon: 'fa-edit'
},
{
action:'save',
icon: 'fa-check'
},
{
action:'cancel',
icon: 'fa-close'
},
];
return icons.find(_=>_.action == action).icon;
},
},
computed:{
minutes(){
const minutes = Math.floor(this.pomodoro.remainSeconds / 60);
return this.formatTime(minutes);
},
seconds(){
const seconds = this.pomodoro.remainSeconds % 60;
return this.formatTime(seconds);
}
}
});
</script>
</body>
</html>
vue-前端第8章demoTwo05.html
原创
©著作权归作者所有:来自51CTO博客作者虾米大王的原创作品,请联系作者获取转载授权,否则将追究法律责任

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
vue-前端第8章demoTwo02.html
【代码】vue-前端第8章demoTwo02.html。
css html javascript sed -
vue-前端第8章demoTwo06.html
【代码】vue-前端第8章demoTwo06.html。
vue.js sed html css -
vue-前端第8章demoTwo03.html
【代码】vue-前端第8章demoTwo03.html。
vue.js javascript java sed html -
vue-前端第8章demoTwo01.html
【代码】vue-前端第8章demoTwo01.html。
css html css3 播放音频 -
vue-前端第8章demoTwo04.html
【代码】vue-前端第8章demoTwo04.html。
vue.js sed html css -
vue-前端第3章computed05.html
【代码】vue-前端第3章computed05.html。
vue.js javascript 前端 html Math -
vue-前端第7章v-if05.html
【代码】vue-前端第7章v-if05.html。
vue.js javascript 前端 html Vue -
vue-前端第5章event05.html
【代码】vue-前端第5章event05.html。
vue.js javascript 前端 html Vue -
vue-前端第9章component05.html
【代码】vue-前端第9章component05.html。
vue.js javascript 前端 html Vue -
vue-前端第3章watch05.html
【代码】vue-前端第3章watch05.html。
vue.js javascript 前端 html ci -
vue-前端第2章instance05.html
【代码】vue-前端第2章instance05.html。
vue.js javascript 前端 html ci -
vue-前端第6章form05.html
【代码】vue-前端第6章form05.html。
javascript 前端 dreamweaver python php -
vue-前端第4章class05.html
【代码】vue-前端第4章class05.html。
javascript vue.js 前端 html css -
vue-前端第12章transition05.html
【代码】vue-前端第12章transition05.html。
html javascript 前端 ide 开发技术 -
vue-前端第11章ajax-demo05.html
【代码】vue-前端第11章ajax-demo05.html。
javascript 前端 html ios ajax -
vue-前端第8章demo02.html
【代码】vue-前端第8章demo02.html。
javascript 前端 html vue.js Vue -
vue-前端第8章demo04.html
【代码】vue-前端第8章demo04.html。
javascript html 前端 vue.js Vue -
vue-前端第8章demo03.html
【代码】vue-前端第8章demo03.html。
javascript 前端 html vue.js Vue -
vue-前端第8章demo01.html
【代码】vue-前端第8章demo01.html。
html servlet java vue.js Vue