213 lines
4.7 KiB
XML
213 lines
4.7 KiB
XML
<template>
|
|
<div class="watchface-container">
|
|
<!-- 背景层 -->
|
|
<image-animator
|
|
class="background-image {{imageAnimationClass}}"
|
|
id="animator"
|
|
duration="{{ duration }}"
|
|
images="{{ frames }}"
|
|
predecode="2"
|
|
poster="last"
|
|
iteration="{{isLoop}}"
|
|
style="opacity: {{imageOpacity}}; display: {{imageDisplay}};"
|
|
/>
|
|
|
|
<!-- 时间显示 -->
|
|
<div class="time-container">
|
|
<text class="time-text" onclick="onClickHandler"
|
|
>{{ currentTime.hours }}:{{ currentTime.minutes }}</text
|
|
>
|
|
</div>
|
|
|
|
<!-- 新增:日期显示 -->
|
|
<div class="date-container">
|
|
<text class="date-text" onclick="onClickHandler2"
|
|
>{{ currentDate.month }}/{{ currentDate.day }}</text
|
|
>
|
|
</div>
|
|
<!-- 前景层(带透明度的图片) -->
|
|
<!--image class="foreground-image" src="/images/foreground.png"></image-->
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="less">
|
|
// 新增日期样式
|
|
.date-container {
|
|
position: absolute;
|
|
left: 23px; // 左侧间距
|
|
bottom: 10px; // 底部间距
|
|
justify-content: flex-start; // 左对齐
|
|
align-items: flex-end; // 底部对齐
|
|
}
|
|
|
|
.date-text {
|
|
font-size: 40px; // 比时间稍小的字号
|
|
font-weight: bold;
|
|
color: #8cc4c2; // 保持与时间一致的配色
|
|
}
|
|
|
|
.watchface-container {
|
|
flex-direction: column;
|
|
width: 390px;
|
|
height: 450px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.background-image {
|
|
position: absolute;
|
|
width: 390px;
|
|
height: 450px;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.time-container {
|
|
position: absolute;
|
|
right: 0px; /* 右侧间距 */
|
|
bottom: 0px; /* 底部间距 */
|
|
justify-content: flex-end; /* 右对齐 */
|
|
align-items: flex-end; /* 底部对齐 */
|
|
|
|
}
|
|
|
|
.time-text {
|
|
font-size: 80px;
|
|
font-weight: bold;
|
|
color: #8cc4c2;
|
|
margin-right: 10px; /* 文字右侧留白 */
|
|
margin-bottom: 10px; /* 文字底部留白 */
|
|
}
|
|
|
|
.foreground-image {
|
|
position: absolute;
|
|
width: 390px;
|
|
height: 450px;
|
|
object-fit: cover;
|
|
}
|
|
@keyframes fadeOut {
|
|
from {
|
|
opacity: 1;
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
/* 新增动画样式 */
|
|
.fade-out-image {
|
|
animation-name: fadeOut;
|
|
animation-duration: 500ms;
|
|
animation-fill-mode: forwards;
|
|
}
|
|
.fade-in-image {
|
|
animation-name: fadeIn;
|
|
animation-duration: 500ms;
|
|
animation-fill-mode: forwards;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
export default {
|
|
data: {
|
|
currentTime: {
|
|
hours: '07',
|
|
minutes: '21'
|
|
},
|
|
currentDate: {
|
|
month: '12',
|
|
day: '34'
|
|
},
|
|
timer: null,
|
|
frames: Array.from(
|
|
{ length: 52 },
|
|
(_, k) => ({
|
|
src: `./assets/frames/image_${k.toString().padStart(2, '0')}.png`
|
|
})
|
|
)
|
|
,
|
|
duration: '50ms',
|
|
imageAnimationClass: '',
|
|
|
|
change: null,
|
|
isLoop: "1",
|
|
},
|
|
|
|
updateTime() {
|
|
const now = new Date();
|
|
const hours = now.getHours().toString().padStart(2, '0');
|
|
const minutes = now.getMinutes().toString().padStart(2, '0');
|
|
const month = (now.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始需要+1
|
|
const day = now.getDate().toString().padStart(2, '0');
|
|
|
|
this.currentTime = { hours, minutes };
|
|
this.currentDate = { month, day }; // 更新日期数据
|
|
},
|
|
|
|
onInit() {
|
|
this.updateTime();
|
|
this.timer = setInterval(() => {
|
|
this.updateTime();
|
|
}, 1000);
|
|
},
|
|
onReady() {
|
|
this.$element('animator').start();
|
|
},
|
|
onShow() {
|
|
this.$element('animator').start()
|
|
},
|
|
|
|
onClickHandler() {
|
|
let state = this.$element('animator').getState();
|
|
switch (state) {
|
|
case 'playing':
|
|
//实现具体的业务逻辑
|
|
this.$element('animator').pause();
|
|
break
|
|
case 'paused':
|
|
//实现具体的业务逻辑
|
|
this.$element('animator').resume();
|
|
break
|
|
case 'stopped':
|
|
this.$element('animator').start();
|
|
break
|
|
}
|
|
},
|
|
onClickHandler2() {
|
|
this.isLoop = this.isLoop === "1" ? "infinite" : "1";
|
|
this.isLoop === "infinite" ? this.$element('animator').start() : "";
|
|
},
|
|
onDestroy() {
|
|
// 清除定时器
|
|
if (this.timer) {
|
|
clearInterval(this.timer);
|
|
}
|
|
if (this.change) {
|
|
clearTimeout(this.change);
|
|
}
|
|
this.$element('animator').stop();
|
|
},
|
|
animate(prop, targetValue, duration, callback) {
|
|
const startTime = Date.now()
|
|
const startValue = this[prop]
|
|
const frame = () => {
|
|
const elapsed = Date.now() - startTime
|
|
const progress = Math.min(elapsed / duration, 1)
|
|
this[prop] = startValue + (targetValue - startValue) * progress
|
|
if (progress < 1) {
|
|
setTimeout(frame, 16) // 模拟requestAnimationFrame
|
|
} else if (callback) {
|
|
callback()
|
|
}
|
|
}
|
|
frame()
|
|
}
|
|
}
|
|
</script>
|