给侧边栏添加春节倒计时卡片

原文出自 梦爱吃鱼 大佬

效果展示

点击查看

修改步骤

1、新建JS文件

[Blog]\themes\anzhiyu\source\static\ 路径下新建 countdown.js ,没有 \static\ 文件夹就在 [Blog]\themes\anzhiyu\source\ 路径下新建一个。

添加以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
const CountdownTimer = (() => {
const config = {
targetDate: "2025-01-29",
targetName: "春节",
units: {
day: { text: "今日", divider: 1, unit: "小时" },
week: { text: "本周", divider: 24, unit: "天" },
month: { text: "本月", divider: 24, unit: "天" },
year: { text: "本年", divider: 24, unit: "天" }
}
};

function getTimeUnit(unit) {
const now = new Date();
const start = new Date(now.setHours(0, 0, 0, 0));
const end = new Date(now.setHours(23, 59, 59, 999));

if (unit === 'day') {
const currentHour = new Date().getHours();
const remaining = 24 - currentHour;
const percentage = (currentHour / 24) * 100;

return {
name: config.units[unit].text,
remaining: remaining,
percentage: percentage.toFixed(2),
unit: config.units[unit].unit
};
}

const ranges = {
week: () => {
start.setDate(start.getDate() - start.getDay());
end.setDate(end.getDate() - end.getDay() + 6);
},
month: () => {
start.setDate(1);
end.setMonth(end.getMonth() + 1, 0);
},
year: () => {
start.setMonth(0, 1);
end.setMonth(11, 31);
}
};
ranges[unit]?.();

const total = unit === "day" ? 24 : Math.floor((end - start) / 86400000) + 1;
const passed = Math.floor((now - start) / (3600000 * config.units[unit].divider));
const percentage = (passed / total) * 100;

return {
name: config.units[unit].text,
remaining: total - passed,
percentage: percentage.toFixed(2),
unit: config.units[unit].unit
};
}

function updateCountdown() {
const elements = ['eventName', 'eventDate', 'daysUntil', 'countRight']
.map(id => document.getElementById(id));

if (elements.some(el => !el)) return;

const [eventName, eventDate, daysUntil, countRight] = elements;
const timeData = Object.keys(config.units).reduce((acc, unit) => ({...acc, [unit]: getTimeUnit(unit)}), {});
const daysRemaining = Math.round((new Date(config.targetDate) - new Date().setHours(0,0,0,0)) / 86400000);

eventName.textContent = config.targetName;
eventDate.textContent = config.targetDate;
daysUntil.textContent = daysRemaining;
countRight.innerHTML = Object.entries(timeData)
.map(([_, item]) => `
<div class="cd-count-item">
<div class="cd-item-name">${item.name}</div>
<div class="cd-item-progress">
<div class="cd-progress-bar" style="width: ${item.percentage}%; opacity: ${item.percentage/100}"></div>
<span class="cd-percentage ${item.percentage >= 46 ? 'cd-many' : ''}">${item.percentage}%</span>
<span class="cd-remaining ${item.percentage >= 60 ? 'cd-many' : ''}">
<span class="cd-tip">还剩</span>${item.remaining}<span class="cd-tip">${item.unit}</span>
</span>
</div>
</div>
`).join('');
}

function injectStyles() {
const styles = `
.card-countdown .item-content {
display: flex;
}
.cd-count-left {
position: relative;
display: flex;
flex-direction: column;
margin-right: 0.8rem;
line-height: 1.5;
align-items: center;
justify-content: center;
}
.cd-count-left .cd-text {
font-size: 14px;
}
.cd-count-left .cd-name {
font-weight: bold;
font-size: 18px;
}
.cd-count-left .cd-time {
font-size: 30px;
font-weight: bold;
color: var(--anzhiyu-main);
}
.cd-count-left .cd-date {
font-size: 12px;
opacity: 0.6;
}
.cd-count-left::after {
content: "";
position: absolute;
right: -0.8rem;
width: 2px;
height: 80%;
background-color: var(--anzhiyu-main);
opacity: 0.5;
}
.cd-count-right {
flex: 1;
margin-left: .8rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.cd-count-item {
display: flex;
flex-direction: row;
align-items: center;
height: 24px;
}
.cd-item-name {
font-size: 14px;
margin-right: 0.8rem;
white-space: nowrap;
}
.cd-item-progress {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 100%;
width: 100%;
border-radius: 8px;
background-color: var(--anzhiyu-background);
overflow: hidden;
}
.cd-progress-bar {
height: 100%;
border-radius: 8px;
background-color: var(--anzhiyu-main);
}
.cd-percentage,
.cd-remaining {
position: absolute;
font-size: 12px;
margin: 0 6px;
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.cd-many {
color: #fff;
}
.cd-remaining {
opacity: 0;
transform: translateX(10px);
}
.card-countdown .item-content:hover .cd-remaining {
transform: translateX(0);
opacity: 1;
}
.card-countdown .item-content:hover .cd-percentage {
transform: translateX(-10px);
opacity: 0;
}
`;

const styleSheet = document.createElement("style");
styleSheet.textContent = styles;
document.head.appendChild(styleSheet);
}

let timer;
const start = () => {
injectStyles();
updateCountdown();
timer = setInterval(updateCountdown, 600000);
};

['pjax:complete', 'DOMContentLoaded'].forEach(event => document.addEventListener(event, start));
document.addEventListener('pjax:send', () => timer && clearInterval(timer));

return { start, stop: () => timer && clearInterval(timer) };
})();

2、新建widget.yml文件

路径下新建 [Blog]\source\_data\widget.yml 文件,并添加以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
top:
- class_name: card-countdown
id_name:
name:
icon:
html: |
<div class="cd-count-left">
<span class="cd-text">距离</span>
<span class="cd-name" id="eventName"></span>
<span class="cd-time" id="daysUntil"></span>
<span class="cd-date" id="eventDate"></span>
</div>
<div id="countRight" class="cd-count-right"></div>

3、在主题配置文件中引入JS

1
2
3
4
5
inject:
head:

bottom:
+ - <script src="/static/countdown.js"></script>

4、补充

不同年份的春节可以在 countdown.js 文件中修改

1
2
3
const config = {
targetDate: "2025-01-29",
targetName: "春节",

相关文章

给博客添加昼夜转换动画
在侧边栏添加时钟卡片
在侧边栏添加来访者欢迎卡片
右下角添加石蒜模拟器