虽互不曾谋面,但希望能和您成为笔尖下的朋友
以读书,技术,生活为主,偶尔撒点鸡汤
不作,不敷衍,意在真诚吐露,用心分享
点击左上方,可关注本刊
标星公众号(ID:itclanCoder)
非常想念各位itclanCoder的粉友们,一直都没有更新博文,但我一直都是在的,感谢朋友还在
您可以在https://coder.itclan.cn的网站找到最新的内容,我会一直坚持下去的
今天给大家分享一个,翻转时钟的特效,具体Vue版本,React版本,原生javaScript版本如下所示:如有不清晰的,也可以点击文末左下方阅读原文
Vue版本实现
FlipClock
组件
/*
* 翻牌数字
* @author:itclanCoder
*/
<template>
<div class="FlipClock">
<Flipper ref="flipperHour1" />
<Flipper ref="flipperHour2" />
<em>:</em>
<Flipper ref="flipperMinute1" />
<Flipper ref="flipperMinute2" />
<em>:</em>
<Flipper ref="flipperSecond1" />
<Flipper ref="flipperSecond2" />
</div>
</template>
<script>
import Flipper from './flipper'
export default {
name: 'flipClock',
data() {
return {
timer: null,
flipObjs: []
}
},
components: {
Flipper
},
methods: {
// 初始化数字
init() {
let now = new Date()
let nowTimeStr = this.formatDate(new Date(now.getTime()), 'hhiiss')
for (let i = 0; i < this.flipObjs.length; i++) {
this.flipObjs[i].setFront(nowTimeStr[i])
}
},
// 开始计时
run() {
this.timer = setInterval(() => {
// 获取当前时间
let now = new Date()
let nowTimeStr = this.formatDate(new Date(now.getTime() - 1000), 'hhiiss')
let nextTimeStr = this.formatDate(now, 'hhiiss')
for (let i = 0; i < this.flipObjs.length; i++) {
if (nowTimeStr[i] === nextTimeStr[i]) {
continue
}
this.flipObjs[i].flipDown(
nowTimeStr[i],
nextTimeStr[i]
)
}
}, 1000)
},
// 正则格式化日期
formatDate(date, dateFormat) {
/* 单独格式化年份,根据y的字符数量输出年份
* 例如:yyyy => 2019
yy => 19
y => 9
*/
if (/(y+)/.test(dateFormat)) {
dateFormat = dateFormat.replace(
RegExp.$1,
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
)
}
// 格式化月、日、时、分、秒
let o = {
'm+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'i+': date.getMinutes(),
's+': date.getSeconds()
}
for (let k in o) {
if (new RegExp(`(${k})`).test(dateFormat)) {
// 取出对应的值
let str = o[k] + ''
/* 根据设置的格式,输出对应的字符
* 例如: 早上8时,hh => 08,h => 8
* 但是,当数字>=10时,无论格式为一位还是多位,不做截取,这是与年份格式化不一致的地方
* 例如: 下午15时,hh => 15, h => 15
*/
dateFormat = dateFormat.replace(
RegExp.$1,
RegExp.$1.length === 1 ? str : this.padLeftZero(str)
)
}
}
return dateFormat
},
// 日期时间补零
padLeftZero(str) {
return ('00' + str).substr(str.length)
}
},
mounted() {
this.flipObjs = [
this.$refs.flipperHour1,
this.$refs.flipperHour2,
this.$refs.flipperMinute1,
this.$refs.flipperMinute2,
this.$refs.flipperSecond1,
this.$refs.flipperSecond2
]
this.init()
this.run()
}
}
</script>
<style>
.FlipClock {
text-align: center;
}
.FlipClock .M-Flipper {
margin: 0 3px;
}
.FlipClock em {
display: inline-block;
line-height: 102px;
font-size: 66px;
font-style: normal;
vertical-align: top;
}
</style>
flipper
组件组件
/*
* 翻牌数字
* @author:itclanCoder
*/
<template>
<div class="M-Flipper" :class="[flipType, {'go': isFlipping}]">
<div class="digital front" :class="_textClass(frontTextFromData)"></div>
<div class="digital back" :class="_textClass(backTextFromData)"></div>
</div>
</template>
<script>
export default {
name: 'FlipClock',
data() {
return {
isFlipping: false,
flipType: 'down',
frontTextFromData: 0,
backTextFromData: 1
}
},
props: {
// front paper text
// 前牌文字
frontText: {
type: [Number, String],
default: 0
},
// back paper text
// 后牌文字
backText: {
type: [Number, String],
default: 1
},
// flipping duration, please be consistent with the CSS animation-duration value.
// 翻牌动画时间,与CSS中设置的animation-duration保持一致
duration: {
type: Number,
default: 600
}
},
methods: {
_textClass(number) {
return 'number' + number
},
_flip(type, front, back) {
// 如果处于翻转中,则不执行
if (this.isFlipping) {
return false
}
this.frontTextFromData = front
this.backTextFromData = back
// 根据传递过来的type设置翻转方向
this.flipType = type
// 设置翻转状态为true
this.isFlipping = true
setTimeout(() => {
// 设置翻转状态为false
this.isFlipping = false
this.frontTextFromData = back
}, this.duration)
},
// 下翻牌
flipDown(front, back) {
this._flip('down', front, back)
},
// 上翻牌
flipUp(front, back) {
this._flip('up', front, back)
},
// 设置前牌文字
setFront(text) {
this.frontTextFromData = text
},
// 设置后牌文字
setBack(text) {
this.backTextFromData = text
}
},
created() {
this.frontTextFromData = this.frontText
this.backTextFromData = this.backText
}
}
</script>
<style>
.M-Flipper {
display: inline-block;
position: relative;
width: 60px;
height: 100px;
line-height: 100px;
border: solid 1px #000;
border-radius: 10px;
background: #fff;
font-size: 66px;
color: #fff;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
text-align: center;
font-family: 'HYLeMiaoTiW';
}
@media screen and (min-width: 375px) and (max-width: 768px){
.M-Flipper {
width: 35px;
font-size: 40px;
}
}
@media screen and