Obsidian 基于 Viewer.js 实现的高级图片查看功能(支持滚轮缩放/拖拽)

Quartz 详细参考 Quartz v4知识库搭建

“基于 Viewer.js 实现的高级图片查看功能(支持滚轮缩放/拖拽)” 的最佳实践方案完整梳理一遍。

这是一条零报错、最标准的实施路径。


🚀 Quartz v4 高级图片灯箱 (Lightbox) 完整配置指南

第一步:安装依赖与准备样式文件

这一步是为了解决 SCSS 语法报错,通过把 CSS 转为 SCSS 模块来完美集成。

  1. 进入项目根目录

    cd /home/zbc/code_pangu/quartz
  2. 安装 Viewer.js

    npm install viewerjs
  3. 复制并重命名样式文件 (将 CSS 转为 Sass 模块):

    cp node_modules/viewerjs/dist/viewer.css quartz/styles/_viewer.scss

第二步:引入全局样式

修改 quartz/styles/custom.scss,使用 @use 引入刚才复制的样式模块。

@use "./base.scss";
@use "./viewer.scss"; /* ✅ 引入 Viewer.js 样式模块 */

// 下面写你的自定义 CSS

/* 调整背景颜色(深色半透明) */
.viewer-backdrop {
  background-color: rgba(0, 0, 0, 0.85) !important;
}

/* 强制提升层级,防止被侧边栏遮挡 */
.viewer-container {
  z-index: 9999 !important;
}

第三步:编写功能脚本

创建 quartz/components/scripts/lightbox.inline.ts。 这是核心逻辑,负责初始化 Viewer.js 并处理 SPA 页面跳转。

import Viewer from "viewerjs"

let viewer: Viewer | null = null

document.addEventListener("nav", () => {
  // 1. 每次页面跳转前清理旧实例
  if (viewer) {
    viewer.destroy()
    viewer = null
  }

  // 2. 获取文章容器
  const container = document.querySelector("article") || document.querySelector(".prose")
  if (!container) return

  // 3. 初始化 Viewer
  viewer = new Viewer(container as HTMLElement, {
    url: 'src', // 使用图片的 src 作为大图
    // 过滤:只对 img 标签生效,且排除带有 no-zoom 类的图片
    filter(image: HTMLElement) {
      return image.tagName === 'IMG' && 
             !image.classList.contains('no-zoom') && 
             !image.hasAttribute('data-no-zoom')
    },
    // 功能配置
    navbar: false,      // 隐藏底部缩略图导航
    title: false,       // 隐藏文件名标题
    toolbar: {          // 工具栏配置 (1:显示, 0:隐藏)
      zoomIn: 1,
      zoomOut: 1,
      oneToOne: 1,
      reset: 1,
      prev: 0,
      next: 0,
      rotateLeft: 0,
      rotateRight: 0,
      flipHorizontal: 0,
      flipVertical: 0,
    },
    tooltip: true,      // 显示缩放比例
    movable: true,      // 允许拖拽
    zoomable: true,     // ✅ 允许滚轮缩放
    backdrop: true,     // 显示遮罩背景
    transition: true,   // 启用动画
  })

  // 4. 注册页面清理函数
  window.addCleanup(() => {
    if (viewer) {
      viewer.destroy()
      viewer = null
    }
  })
})

第四步:封装组件外壳

创建 quartz/components/Lightbox.tsx

import { QuartzComponent, QuartzComponentConstructor } from "./types"
// @ts-ignore: 忽略 TS 对 .inline 后缀的检查
import script from "./scripts/lightbox.inline"

export default (() => {
  const Lightbox: QuartzComponent = () => <></> // 无 UI 组件
  
  // 将脚本注入到页面加载后执行
  Lightbox.afterDOMLoaded = script
  
  return Lightbox
}) satisfies QuartzComponentConstructor

第五步:注册并启用组件

  1. 导出组件: 修改 quartz/components/index.ts,在文件末尾添加:

    export { default as Lightbox } from "./Lightbox"
    
  2. 加载组件: 修改 quartz.layout.ts,将组件加入全局共享布局的 afterBody 中:

    export const sharedPageComponents: SharedLayout = {
      head: Component.Head(),
      header: [],
      afterBody: [
        Component.Lightbox(), // ✅ 启用组件
      ],
      footer: Component.Footer({ /* ... */ }),
    }
    

第六步:启动验证

npx quartz build --serve

最终效果

  • 点击文章内的任意图片,会弹出全屏查看器。
  • 支持鼠标滚轮缩放
  • 支持鼠标拖拽移动图片。
  • 底部有工具栏,支持还原大小。
  • Esc 或点击背景可关闭。

恭喜你!你现在拥有了一个功能非常强大的知识库图片浏览体验。✨