Skip to content

Commit d73175a

Browse files
committed
refactor: use single resize observer to observe flake size
1 parent 25c1ba0 commit d73175a

2 files changed

Lines changed: 55 additions & 23 deletions

File tree

src/utils.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useElementSize, type MaybeComputedElementRef } from '@vueuse/core'
21
import { computed, toValue, type Directive, type MaybeRefOrGetter } from 'vue'
32

43
export const px = (x: number) => `${x}px`
@@ -22,10 +21,6 @@ export const useCssWith = <T>(
2221
})
2322
}
2423

25-
export const useElementBorderSize = (target: MaybeComputedElementRef) => {
26-
return useElementSize(target, { width: 0, height: 0 }, { box: 'border-box' })
27-
}
28-
2924
export const noopAsync = async () => await Promise.resolve()
3025

3126
export const vFocus: Directive<HTMLInputElement> = {

src/vue/FlakeView.vue

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { moment, Notice } from 'obsidian'
55
import { ObIcon } from '@/components'
66
import type { Flake } from '@/data'
77
import type { ImageRawSize, PileActions } from '@/view'
8-
import { CausedError, px, useCssIf, useCssWith, useElementBorderSize, vFocus } from '@/utils'
8+
import { CausedError, px, useCssIf, useCssWith, vFocus } from '@/utils'
99
1010
const props = defineProps<{
1111
flake: Flake
@@ -100,40 +100,77 @@ useEventListener(textareaRef, 'input', () => {
100100
syncTextareaWidth()
101101
})
102102
103-
const nameSize = useElementBorderSize(nameRef)
104-
const contentSize = useElementBorderSize(contentRef)
105-
const footerSize = useElementBorderSize(footerRef)
103+
const borderHeight = ref(0)
104+
const nameHeight = ref(0)
105+
const contentHeight = ref(0)
106+
const footerHeight = ref(0)
106107
const scrollBarHeight = ref(0)
107108
108-
useResizeObserver(scrollableRef, (entries) => {
109-
const entry = entries[0]!
110-
const el = entry.target as HTMLElement
111-
scrollBarHeight.value = el.offsetHeight - el.clientHeight
112-
})
109+
const contentAppliedHeight = ref(0)
113110
114-
const contentHeight = ref(0)
111+
const getBorderHeight = (el: HTMLElement) => {
112+
const style = getComputedStyle(el)
113+
const top = parseFloat(style.borderTopWidth)
114+
const bottom = parseFloat(style.borderBottomWidth)
115+
return top + bottom
116+
}
117+
118+
const getScrollbarHeight = (el: HTMLElement) => {
119+
return el.offsetHeight - el.clientHeight
120+
}
121+
122+
useResizeObserver([
123+
flakeRef,
124+
nameRef,
125+
contentRef,
126+
footerRef,
127+
scrollableRef,
128+
], (entries) => {
129+
for (const entry of entries) {
130+
const el = entry.target as HTMLElement
131+
const h = entry.borderBoxSize[0]?.blockSize ?? 0
132+
133+
switch (el) {
134+
case flakeRef.value:
135+
borderHeight.value = getBorderHeight(el)
136+
break
137+
case nameRef.value:
138+
nameHeight.value = h
139+
break
140+
case contentRef.value:
141+
contentHeight.value = h
142+
break
143+
case footerRef.value:
144+
footerHeight.value = h
145+
break
146+
case scrollableRef.value:
147+
scrollBarHeight.value = getScrollbarHeight(el)
148+
break
149+
}
150+
}
151+
})
115152
116153
watchEffect(async () => {
117154
if (isView.value && isImage.value && imageRawSize.value) {
118155
if (props.flake.enableRatio && props.flake.ratio) {
119156
const ratio = Math.clamp(props.flake.ratio, 0.25, 4)
120-
contentHeight.value = props.width * ratio
157+
contentAppliedHeight.value = props.width * ratio
121158
}
122159
else {
123160
const { width: w, height: h } = imageRawSize.value
124-
contentHeight.value = props.width / w * h
161+
contentAppliedHeight.value = props.width / w * h
125162
}
126163
}
127164
else {
128-
contentHeight.value = contentSize.height.value
165+
contentAppliedHeight.value = contentHeight.value
129166
}
130167
})
131168
132169
const height = computed(() => {
133-
return 2 // Slightly larger than the border size
134-
+ nameSize.height.value
135-
+ contentHeight.value
136-
+ footerSize.height.value
170+
return borderHeight.value
171+
+ nameHeight.value
172+
+ contentAppliedHeight.value
173+
+ footerHeight.value
137174
+ scrollBarHeight.value
138175
})
139176
@@ -284,7 +321,7 @@ const cssTypeIsImage = useCssIf(isImage, 'selected')
284321

285322
<template>
286323
<div ref="el-flake"
287-
:class="['flake-view', 'fp-flake-theme', cssTheme, cssIsEdit, cssLight]">
324+
:class="['fp-flake-theme', 'flake-view', cssTheme, cssIsEdit, cssLight]">
288325
<div v-if="!imageOnly" ref="el-name" class="flake-name">
289326
<div v-if="isText" class="noicon"></div>
290327

0 commit comments

Comments
 (0)