2025-04-22 21:05:08 +08:00

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>