插件片段:简单悬停预览大图

主要参考了插件 AttachFlowobsidian-highlighter,谢谢你们~

平时只有少量查看大图需求,就写了一个简单的。

20240622_123822

main.js:

const ob = require('obsidian')
, import_mouse = (ob)=> new class {
  restLength = (mouse, screen)=> mouse < screen / 2 ? screen - mouse : mouse
  keyMoveImg = (evt)=> {
    const isKey = evt.altKey
    , { target, view } = evt, targetNotImg = target.tagName != 'IMG'
    if (targetNotImg && this.hoverOn) this.hoverOn = !1
    if (!isKey || targetNotImg || !view || this.hoverOn) return
    const pop = new ob.HoverPopover(view, target, 200), { hoverEl } = pop

    const { naturalWidth, naturalHeight } = target
    , ratio = naturalHeight / naturalWidth
    , restWidth = this.restLength(evt.clientX, view.innerWidth)
    , expectHeight = restWidth * ratio
    , restHeight = this.restLength(evt.clientY, view.innerHeight)
    , expectWidth = restHeight / ratio
    let calcByWidth
    if (expectWidth < restWidth && expectHeight < restHeight)
      calcByWidth = restWidth * expectHeight > restHeight * expectWidth;
    else calcByWidth = expectWidth > restWidth
    let width = calcByWidth ? restWidth : expectWidth
    width = Math.min(800, width)
    Object.assign(hoverEl.style, {
      width: `${width}px`, height: `${width * ratio}px`,
      'background-image': `url(${target.src})`, 'background-size': 'cover',
    })

    hoverEl.onwheel = e=> {
      const scale = e.deltaY > 0 ? 0.8 : 1.2 // 20% 缩放
      , mouseX = e.clientX, mouseY = e.clientY, width = hoverEl.offsetWidth * scale
      Object.assign(hoverEl.style, {
        width: `${width}px`, height: `${width * ratio}px`,
        left: `${mouseX - (mouseX - hoverEl.offsetLeft) * scale}px`,
        top: `${mouseY - (mouseY - hoverEl.offsetTop) * scale}px`,
      })
    }
    this.hoverOn = !0; pop.onunload = ()=> this.hoverOn = !1
  }
}
module.exports = class extends ob.Plugin {
  onload() {
    let Timer; const { keyMoveImg } = import_mouse(ob)
    this.registerEvent(
      this.app.workspace.on('active-leaf-change', (leaf)=> {
        if (Timer) clearTimeout(Timer)
        Timer = setTimeout(()=> {
          const { view } = leaf; if (!view) return
          this.registerDomEvent(view.contentEl, 'mousemove', keyMoveImg)
        })
      }),
    )
  }
  onunload() {}
}
  • keyMoveImg() 第 1 行 isKey 控制按住什么键悬停触发大图,这里设置的是 Alt 键。鼠标移动到大图区域后不用再按住键。
  • 鼠标滚轮放大缩小。
3 个赞

我看着这个实现的效果好像和obsidian-image-toolkit基本一样。是我忽略了哪里的不同吗?

obsidian-image-toolkit 的 Normal Mode 是点击一下图片之后出现一个黑色遮罩,然后在上面展示图片;而 Pin Mode 主要是为了贴图,也就是点完之后还要手动关掉图,不是鼠标移开后图会自动消失。

这是它的 Normal Mode。它还有 Pin Mode。

  • You can click and popped up 1 to 5 images at a time
  • Comparing with normal mode, the image will be popped up without mask layer after clicking the image
  • It’s allowed to edit and look through your notes while images are being popped up and previewed

也就没有黑色遮罩了。如图显示。

1 个赞

原来如此,你的需求是这样的。我明白了。

请问这个js文件应该怎么用呢

啊,这个主要是分享插件片段,为了方便其他人复用到自己插件里的,因为这个特别短。像 AttachFlow 和 image-toolkit 都是社区成熟的插件,使用的话还是直接安装这两个更好。

1 个赞

好的,hh,我去试试