vault backup: 2025-03-11 23:28:57

This commit is contained in:
BlueRose 2025-03-11 23:28:57 +08:00
parent 50ffee2257
commit 4a5a8657be
13 changed files with 271 additions and 15 deletions

View File

@ -15,7 +15,8 @@
"【自定义】mytools 样式",
"【图标】iconfont",
"【日记】Time",
"custom-admonitions.c9c6cb"
"custom-admonitions.c9c6cb",
"image-captions-figure"
],
"baseFontSizeAction": false,
"accentColor": "#0068f0"

View File

@ -35,5 +35,6 @@
"obsidian-view-mode-by-frontmatter",
"Enhanced-editing",
"table-editor-obsidian",
"obsidian-excalidraw-plugin"
"obsidian-excalidraw-plugin",
"image-captions"
]

175
.obsidian/plugins/image-captions/main.js vendored Normal file
View File

@ -0,0 +1,175 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => ImageCaptions,
renderMarkdown: () => renderMarkdown
});
module.exports = __toCommonJS(main_exports);
var import_obsidian2 = require("obsidian");
// src/settings.ts
var import_obsidian = require("obsidian");
var DEFAULT_SETTINGS = {
captionRegex: ""
};
var CaptionSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian.Setting(containerEl).setName("Advanced settings").setHeading();
new import_obsidian.Setting(containerEl).setName("Caption regex").setDesc("For advanced caption parsing, you can add a regex here. The first capturing group will be used as the image caption. This is useful in situations where you might have another plugin or theme adding text to the caption area which you want to strip out. The placeholder example would be used to exclude everything following a pipe character (if one exists).").addText((text) => text.setPlaceholder("^([^|]+)").setValue(this.plugin.settings.captionRegex).onChange(async (value) => {
this.plugin.settings.captionRegex = value;
await this.plugin.saveSettings();
}));
}
};
// src/main.ts
var filenamePlaceholder = "%";
var filenameExtensionPlaceholder = "%.%";
var ImageCaptions = class extends import_obsidian2.Plugin {
async onload() {
this.registerMarkdownPostProcessor(this.externalImageProcessor());
await this.loadSettings();
this.addSettingTab(new CaptionSettingTab(this.app, this));
this.observer = new MutationObserver((mutations) => {
mutations.forEach((rec) => {
if (rec.type === "childList") {
rec.target.querySelectorAll(".image-embed, .video-embed").forEach(async (imageEmbedContainer) => {
var _a, _b;
const img = imageEmbedContainer.querySelector("img, video");
const width = imageEmbedContainer.getAttribute("width") || "";
const captionText = this.getCaptionText(imageEmbedContainer);
if (!img)
return;
const figure = imageEmbedContainer.querySelector("figure");
const figCaption = imageEmbedContainer.querySelector("figcaption");
if (figure || ((_a = img.parentElement) == null ? void 0 : _a.nodeName) === "FIGURE") {
if (figCaption && captionText) {
const children = (_b = await renderMarkdown(captionText, "", this)) != null ? _b : [captionText];
figCaption.replaceChildren(...children);
} else if (!captionText) {
imageEmbedContainer.appendChild(img);
figure == null ? void 0 : figure.remove();
}
} else {
if (captionText && captionText !== imageEmbedContainer.getAttribute("src")) {
await this.insertFigureWithCaption(img, imageEmbedContainer, captionText, "");
}
}
if (width) {
img.setAttribute("width", width);
} else {
img.removeAttribute("width");
}
});
}
});
});
this.observer.observe(document.body, {
subtree: true,
childList: true
});
}
getCaptionText(img) {
let captionText = img.getAttribute("alt") || "";
const src = img.getAttribute("src") || "";
const edge = captionText.replace(/ > /, "#");
if (captionText === src || edge === src) {
return "";
}
if (this.settings.captionRegex) {
try {
const match = captionText.match(new RegExp(this.settings.captionRegex));
if (match && match[1])
captionText = match[1];
} catch (e) {
}
}
if (captionText === filenamePlaceholder) {
const match = src.match(/[^\\/]+(?=\.\w+$)|[^\\/]+$/);
if (match == null ? void 0 : match[0]) {
captionText = match[0];
}
} else if (captionText === filenameExtensionPlaceholder) {
const match = src.match(/[^\\/]+$/);
if (match == null ? void 0 : match[0]) {
captionText = match[0];
}
} else if (captionText === "\\" + filenamePlaceholder) {
captionText = filenamePlaceholder;
}
captionText = captionText.replace(/<<(.*?)>>/g, (_, linktext) => {
return "[[" + linktext + "]]";
});
return captionText;
}
externalImageProcessor() {
return (el, ctx) => {
el.findAll("img:not(.emoji), video").forEach(async (img) => {
const captionText = this.getCaptionText(img);
const parent = img.parentElement;
if (parent && (parent == null ? void 0 : parent.nodeName) !== "FIGURE" && captionText && captionText !== img.getAttribute("src")) {
await this.insertFigureWithCaption(img, parent, captionText, ctx.sourcePath);
}
});
};
}
async insertFigureWithCaption(imageEl, outerEl, captionText, sourcePath) {
var _a;
const figure = outerEl.createEl("figure");
figure.addClass("image-captions-figure");
figure.appendChild(imageEl);
const children = (_a = await renderMarkdown(captionText, sourcePath, this)) != null ? _a : [captionText];
figure.createEl("figcaption", {
cls: "image-captions-caption"
}).replaceChildren(...children);
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
onunload() {
this.observer.disconnect();
}
};
async function renderMarkdown(markdown, sourcePath, component) {
const el = createDiv();
await import_obsidian2.MarkdownRenderer.renderMarkdown(markdown, el, sourcePath, component);
for (const child of el.children) {
if (child.tagName.toLowerCase() === "p") {
return child.childNodes;
}
}
}
/* nosourcemap */

View File

@ -0,0 +1,11 @@
{
"id": "image-captions",
"name": "Image Captions",
"version": "1.1.5",
"minAppVersion": "0.15.0",
"description": "Adds captions to images when there is alt-text specified",
"author": "Alan Grainger",
"authorUrl": "https://github.com/alangrainger",
"fundingUrl": "https://ko-fi.com/alan_",
"isDesktopOnly": false
}

View File

@ -0,0 +1,24 @@
.image-captions-figure {
margin: 0;
padding: 2px;
display: table; /* To allow for correct caption text wrapping */
border-radius: 2px;
}
.image-captions-caption {
margin: -5px 0 0 0;
padding: 3px 5px;
text-align: center;
display: table-caption; /* To allow for correct caption text wrapping */
caption-side: bottom;
}
.theme-dark .image-captions-figure,
.theme-dark .image-captions-caption {
background: #303030;
}
.theme-light .image-captions-figure,
.theme-light .image-captions-caption {
background: #ebebeb;
}

View File

@ -0,0 +1,4 @@
.image-captions-figure {
margin-left: auto;
margin-right: auto;
}

View File

@ -6,7 +6,7 @@ tags:
rating: ⭐
---
# 项目需求
- [ ] [🍄《百菌志》🍄2024纯享合集](https://www.bilibili.com/video/BV11x6DYbE2g/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e)
- [x] [🍄《百菌志》🍄2024纯享合集](https://www.bilibili.com/video/BV11x6DYbE2g/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e)
- [ ] [【IGN】《大神》续作先导预告 | TGA 2024](https://www.bilibili.com/video/BV1JbqqYuEVB/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e)
## 百菌志
- 背景(场景)为吉普力风格
@ -20,7 +20,7 @@ rating: ⭐
- 只能手绘的要素
- 细小植物
- 需要实现的效果
- [ ] 吉普力风格的水面高光
- [ ] 吉普力风格的水面高光 [🍄《百菌志》🍄2024纯享合集 【精准空降到 00:27】](https://www.bilibili.com/video/BV11x6DYbE2g/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=27)
- [ ] 水滴留下来的动态效果 [🍄《百菌志》🍄2024纯享合集【精准空降到 00:45】](https://www.bilibili.com/video/BV11x6DYbE2g/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=45)
- 角色(会动的物体)使用赛璐璐风格
- 不受GI影响
@ -28,21 +28,43 @@ rating: ⭐
- [x] 阴影亮度控制
- [ ] ***描边(需要制作透明物体)***
![[百菌志_1.png |1200]]
![[百菌志_1.png | 树干 泥地 树叶 细小植被 |1200]]
![[百菌志_2.png|1200]]
![[百菌志_2.png|树木 泥土 青苔|1200]]
![[百菌志_3.png|岩石 青苔|1200]]
![[百菌志_3.png]]
![[百菌志_4.png| 吉普力水面高光效果 泥地 青苔 细小植物 |1200]]
![[百菌志_5.png|青苔 草地 岩石|1200]]
![[百菌志_4.png]]
![[百菌志_6.png|云 山 草地 泥土|1200 ]]
![[百菌志_5.png]]
![[百菌志_6.png]]
![[百菌志_7.png]]
![[百菌志_7.png| 土地 岩石 青苔|1200]]
## 大神
***水墨配色的吉普力式绘制方法***
1. 水墨
1. [ ] 水墨晕染效果3s~9s序列帧+UV扩张。
2. [ ] 水墨植物10s~12s)
1. Kuawahara各项异性实现水墨晕染效果
3. [ ] 滤镜比重较大(22s~25s):镜头不断变亮,但色块量变少、细节(叶子)变多。
2. 油画
1. [ ] 草地25s~28s:Kuawahara滤镜、刮痕+黑点叠加滤镜。
2. [ ] Kuawahara涂抹油画效果28s~30s确定是后处理实现因为阳光与山的交界处出现了多重采样的效果
3. [ ] 各项异性Kuawahara涂抹油画效果36~39s 可以参考 https://zhuanlan.zhihu.com/p/368352199
![[大神_1.png | 1200]]
![[大神_2.png | 看不出滤镜与贴图比重 猜测贴图吉普力化 滤镜各占一半 |1200]]
![[大神_3.png | 远景刮痕与黑点叠加 | 1200]]
![[大神_4.png | 带有笔触的优化滤镜效果 |1200]]
![[大神_5.png | 1200]]
![[大神_6.png | 1200]]
《Oil Painting Style Rendering Based on Kuwahara Filter》论文效果
![Oil Painting Style Rendering Based on Kuwahara Filter](https://pic4.zhimg.com/v2-eb4d7b07529dd442934fab088f6798b1_r.jpg)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.