Obsidian 时间进度条实现方法
3 min read

Obsidian 时间进度条实现方法

介绍一种通过 css + templater 脚本的方法为 Obsidian 实现一种自动更新的年度进度条(Year Progress Bar)。
Obsidian 时间进度条实现方法
year progress from https://twitter.com/year_progress

如下图所示,受到 @filiphracek 的 Year Progress 启发,我打算在 Obsidian 的 Kanban 中也实现一套可以自动更新的 Year Progress Bar。

year progress from filiphracek

实现 Obsidian Progress Bar 主要是大致分为三个步骤:

  1. 编写 Porgress Bar 的样式表,添加到 Obsidian CSS snippets
  2. 编写 Templater 自动更新模版代码
  3. 为 Templater 模版增加快捷键

Progress Bar 样式表

通过 CSS 样式表来定义 progress bar 的渲染效果,将如下的 CSS 代码添加到 Obsidian CSS snippets:

.meter {
  box-sizing: content-box;
  height: 18px; /* Can be anything */
  position: relative;
  margin: 1px 0 1px 0; /* Just for demo spacing */
  background: rgb(122, 122, 122);
  border-radius: 9px;
  padding: 1px;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.3);
  text-align: left;
  font-family: "Comic Mono";
  font-size: 16px;
  font-style: italic;
  color: brown;
}
.meter > span {
  display: block;
  height: 100%;
  border-top-right-radius: 8px;
  border-bottom-right-radius: 8px;
  border-top-left-radius: 20px;
  border-bottom-left-radius: 20px;
  background-color: rgb(43, 194, 83);
  background-image: linear-gradient(
    center bottom,
    rgb(43, 194, 83) 37%,
    rgb(84, 240, 84) 69%
  );
  box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3),
    inset 0 -2px 6px rgba(0, 0, 0, 0.4);
  position: relative;
  overflow: hidden;
}
.meter > span:after,
.animate > span > span {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-image: linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.2) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.2) 75%,
    transparent 75%,
    transparent
  );
  z-index: 1;
  background-size: 50px 50px;
  animation: move 2s linear infinite;
  border-top-right-radius: 8px;
  border-bottom-right-radius: 8px;
  border-top-left-radius: 20px;
  border-bottom-left-radius: 20px;
  overflow: hidden;
}
.animate > span:after {
  display: none;
}
@keyframes move {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 50px 50px;
  }
}
.orange > span {
  background-image: linear-gradient(#f1a165, #f36d0a);
}
.red > span {
  background-image: linear-gradient(#f0a3a3, #f42323);
}
.nostripes > span > span,
.nostripes > span::after {
  background-image: none;
}
* {
  box-sizing: border-box;
}

Obsidian 如何添加 CSS snippets 的方法参考:CSS snippets - Obsidian Help

Year Progress Bar Templater

根据 templater docs 编写针对年度时间进度的 templater 模版代码:

// according to templater syntax, you need to put the following code into `<%%>`
let startDate = new Date(2023,0,1)
let nowDate = new Date()
let days = (nowDate.getTime()-startDate.getTime())/(1000*60*60*24)
let percent = 100*days/365
let dayPercent = percent.toPrecision(3)
let content = "Year Progress:<div class='meter'><span style='width:" + dayPercent + "%'>" + dayPercent + "%</span></div>"
if (tp.file.content.includes("Year Progress:<div class='meter'><span style='width:")) {
	new Notice("updating year progress bar!");
	let newContent = tp.file.content.replace(/(Year Progress:)([\s,\d, %,<,>,.]+)(.*)/, content)
	let file = this.app.workspace.activeLeaf.view.file
	this.app.vault.modify(file, newContent)
} else {
	new Notice("the file has no year progress bar, insert new one!");
	let newContent = tp.file.content + content;
	let file = this.app.workspace.activeLeaf.view.file
	this.app.vault.modify(file, newContent)
}

在 Obsidian Templater 配置的模版目录下增加 year progress bar templater 模版文件。

templater location to add template files

Obsidian Progress Bar 配置

在 Obsidian 中为 year progress bar templater 增加快捷键配置,主要的配置方法参考:Obsidian 自动添加元数据。Kanban 中自动年度进度条的最终效果如下图所示:

Year Progress Bar in Obsidian Kanban

References

  1. Templater: A template plugin for obsidian
  2. Introduction Templater
  3. Obsidian 自动添加元数据

Public discussion