blacksmithgu / obsidian-dataview

A data index and query language over Markdown files, for https://obsidian.md/.
https://blacksmithgu.github.io/obsidian-dataview/
MIT License
7.13k stars 419 forks source link

Local image in render cause flickering in live preview #2450

Open Graywaren opened 2 months ago

Graywaren commented 2 months ago

What happened?

So I'm not entirely sure if this is a bug with dataview or an issue with obsidian and how they have it handle images and code blocks, so apologies if this isn't a bug with dataview or if my lack of extensive experience with it means I did something wrong.

So the behavior is that when putting an image in the vault into a dataviewjs code block, using dv.span or dv.el("div", ``) it causes the codeblock to flicker as seen here: flicker

It happens with just the internal image link, an internal image link that's sized, an internal image link within a span, with class or without, svg or png etc. I've tested a bunch of different options, though not exhaustive. It happened in both dv.span and dv.el("div", ``).

I've had inconsistent results with dv.paragraph. It doesn't happen in my test vault/code, but it does happen in my use case vault/code. I will update if I can figure out what's going on there.

It also doesn't happen using ![img](folder/file) or <img> and a link to an image on the web, however it does flicker when using <img> with a local file as a source. Unfortunately ![img](folder/file) does not play nicely with the dom, as it literally gets taken out of it's place in the code I wrote, and then gets added as it's own div after the element I added it into for some reason and screws up my entire flex layout. I'm currently working around it by linking to the image in my public dropbox folder, but that's giving me console warnings about cross site cookies >.>

It also doesn't happen if I turn the auto refresh off, so it definitely has to do with that, but that's not a viable alternative for me as I have a number of things that rely on the refresh.

I have tested it in a vault with no theme and with only dataview enabled with the same behavior except for the paragraph thing noted above. I included two snippets of code examples below. I'm using windows 10. Let me know if there's anything you'd like me to test etc. etc.

Update... i have now had it happen with regular internal wiki linked images and the markdown image links, the only thing it hasn't happened with so far has been the img to external web links that are throwing cookie errors. The external web linked images also drastically slow down the rendering of the some things in datablocks, like heatmaps.

DQL

No response

JS

dv.span(`![[gn_trex.png|35]]`);

dv.span(`<span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span><span class=test><span>![[QuestionSearch1.svg|35]]</span></span>`, {cls: "test"});

Dataview Version

0.5.67

Obsidian Version

1.6.7

OS

Windows

Rubinum commented 1 month ago

Can you provide a raw code of your obsidian file, which you mentioned in your description? Guessing from your gif and your description is a bit hard. Besides that: What is your usecase, having a picture linked in a dataview code block? I am asking because I can not think about a case, where you need a link of a picture inside of a dataview query block.

Graywaren commented 1 month ago

Hi So my use cases are making legends for graphs and a daily trackers section for my daily notes that add values to properties. For the daily tracker section, there's a number of them, so I wanted them in two columns. I'm using meta bind inputs for this and want to have an icon that is a link to a heading in a note before each one to indicate which tracker it is and provide a hover over definition. I mainly use emojis for this, and the emojis have no display issues, but windows 10 is especially limited in emojis and there's a few I've ended up making some custom icons for, which is where the linked images come in.

The way I was able to achieve this setup was to render it through dataviewjs code block because every other method of attempting to have columns, icon links, and meta bind input doesn't work because either it's not compatible with one of those things or it opens the source code on click, therefore making the ability to input anything extremely tedious. Rendering it through the dataviewjs codeblock has let me create a very nice looking and easily clicked on and styled to be precise via css (yay flex and grid!) log section. I've been using it for at least a fortnight and it works well and the image jumping and image flashing is the only issue I've run into with it. Here's a partial screen shot of my actual use case. Log

I also use javascript to render certain trackers or not based on the value chosen in a separate tracker.

In the case of the legends, i'm using the Heatmap and Habit Calendar plug ins, which use dataviewjs to render graphs/calendar views with colors/icons on certain days to represent the thing being tracked. Neither came with legends, so I wrote one into the codeblock to render a legend of the icons. An interesting thing I noticed there is that I can assign an internal image as the value of a constant that is being put into the heatmap on a day if the condition is matched and it doesn't flicker/jump, but it does flicker/jump when rendered in the dv.span below the graph.

Some further observations:

Unfortunately I'm not sure how to get a better video of it than the gif, since the jumps are split seconds. Going frame by frame on a screen recording of it shows the entire note contents moving down one line and then back up in the next frame. Here's two still images of the frame before and the frame of the jumping. The red arrow shows the scroll position on the image is cutting off the top of the dinosaur image, then in the second image, which is the frame during the flash/flicker/jump, you can see the dino image is no longer cut off an is further below the navigation arrows. So during that brief moment, everything is being pushed downwards. If there's something else you'd like me to try to better capture it, let me know and I'll give it a shot. NotJumped Jumped

I'm not sure what you mean by raw code exactly or how it differs than the js code I included before or which file I mentioned you're referring to, but I'm included a few things so hopefully at least one of them will be what you're after. If not please forgive my ignorance and if you can let me know a bit more specifically I'll include it.

Here's the entire contents of a note built in a basic test vault,, no theme, only community plug in is dataview. Each method has the image flashing and jumping.

```dataviewjs
dv.span(`[![[gn_trex.png]]](<linked note.md>) This icon is a link to a note`, {cls: "customstyle1"})
dv.span(`![[gn_trex.png]] This icon is just an image`)
dv.el("div", `[![[gn_trex.png]]](<linked note.md>) This icon is a link to a note in a div instead`)

Here's the debug info for the basic test valt
SYSTEM INFO:
    Obsidian version: v1.7.4
    Installer version: v1.6.7
    Operating system: Windows 10 Home 10.0.19045
    Login status: not logged in
    Language: en
    Insider build toggle: off
    Live preview: on
    Base theme: adapt to system
    Community theme: none
    Snippets enabled: 1
    Restricted mode: off
    Plugins installed: 1
    Plugins enabled: 1
        1: Dataview v0.5.67

---------

The thing about the heatmap I mentioned goes like this:

Here is an example of it being used as the value that's added on a day where the property for that habit meets the criteria and is therefore rendered within the heatmap itself, this does not flicker or jump:
const habit= '<span class="habit icon">![[habiticon.jpg]]</span>'

...all heatmap coding where the habit constant is added to calendarData under certain conditions....

renderHeatmapCalendar(this.container, calendarData)

Here's an example of my legend rendered below the heatmap graph in the same code block. In this case, the image jumps and flickers, pushing the screen:
...all heatmap coding...

renderHeatmapCalendar(this.container, calendarData)

dv.span(`<span class="legend-item custom"><span class="icon custom">![[habiticon.jpg]]</span><span class="label">custom habit</span></span><span class="legend-item social"><span class="icon speech">💬</span><span class="label">social</span></span>`, {cls: "hm-legend"})

However, if I change my legend to work this way, assigning the code to a constant, then putting that constant in the span, it still flickers/jumps. Definitely seems like it's specifically rendering it in the dv.span etc.  
renderHeatmapCalendar(this.container, calendarData)

const legend = '<span class="legend-item custom"><span class="icon custom">![[habiticon.jpg]]</span><span class="label">custom habit</span></span><span class="legend-item social"><span class="icon speech">💬</span><span class="label">social</span></span>'

dv.span(legend, {cls: "hm-legend"})

------------

Here's a shortened version of my daily notes template, showing the metabind input, coding structure, and custom emoji icon short code from that plug in "`:ci_brainzap:`". Using this short code occasionally has the icon go invisible for a split second, but doesn't jump the screen. 

{{date:dddd, MMMM Do, YYYY}}

Captain's Log:{.blue-caplog}

dv.span(`<span class="dailies-col"><span class="dailies-item car"><span class="icon"><span class="red-car">[[Dailies Definitions#Car{.blue-icob4-red-car}|🚗]]</span>:</span><span class="dailies-input">\`INPUT[inlineListSuggester(optionQuery("List/Options"),useLinks(partial)):car]\`</span></span><span class="dailies-item speech"><span class="icon"><span class="speech">[[Dailies Definitions#Speech{.blue-icob4-speech}|💬]]</span>:</span><span class="dailies-input">\`INPUT[inlineListSuggester(optionQuery("List/Options"),useLinks(partial)):speech]\`</span></span></span><span class="dailies-col"><span class="dailies-item tent"><span class="icon"><span class="camp">[[Dailies Definitions#Camp{.lime-icob4-camp}|🏕]]</span>:</span><span class="dailies-input">\`INPUT[inlineListSuggester(optionQuery("List/Options"),useLinks(partial)):camp]\`</span></span><span class="dailies-item brain"><span class="icon"><span class="brain">[[Dailies Definitions#Brain{.foxfire-icob4-brain}|:ci_brainzap:]]</span>:</span><span class="dailies-input">\`INPUT[inlineListSuggester(optionQuery("List/Options"),useLinks(partial)):brain]\`</span></span></span>`, {cls: "dailies"});

Ramblings: {.foxfire}



If I were to replace `[[Dailies Definitions#Brain{.foxfire-icob4-brain}|:ci_brainzap:]]` with `[![[brainzap.jpg]]](<Dailies Definitions.md#Brain{.foxfire-icob4-brain}>)` it would flicker and jump the screen. 

Hopefully any of that is helpful!