diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
| commit | 9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch) | |
| tree | ce5959571a981b9c4047da3c7b3fd080aa44222c /packages/frontend/src/directives/get-size.ts | |
| parent | wip: retention for dashboard (diff) | |
| download | misskey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.gz misskey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.bz2 misskey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.zip | |
rename: client -> frontend
Diffstat (limited to 'packages/frontend/src/directives/get-size.ts')
| -rw-r--r-- | packages/frontend/src/directives/get-size.ts | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/packages/frontend/src/directives/get-size.ts b/packages/frontend/src/directives/get-size.ts new file mode 100644 index 0000000000..ff3bdd78ac --- /dev/null +++ b/packages/frontend/src/directives/get-size.ts @@ -0,0 +1,54 @@ +import { Directive } from 'vue'; + +const mountings = new Map<Element, { + resize: ResizeObserver; + intersection?: IntersectionObserver; + fn: (w: number, h: number) => void; +}>(); + +function calc(src: Element) { + const info = mountings.get(src); + const height = src.clientHeight; + const width = src.clientWidth; + + if (!info) return; + + // アクティベート前などでsrcが描画されていない場合 + if (!height) { + // IntersectionObserverで表示検出する + if (!info.intersection) { + info.intersection = new IntersectionObserver(entries => { + if (entries.some(entry => entry.isIntersecting)) calc(src); + }); + } + info.intersection.observe(src); + return; + } + if (info.intersection) { + info.intersection.disconnect(); + delete info.intersection; + } + + info.fn(width, height); +} + +export default { + mounted(src, binding, vn) { + const resize = new ResizeObserver((entries, observer) => { + calc(src); + }); + resize.observe(src); + + mountings.set(src, { resize, fn: binding.value }); + calc(src); + }, + + unmounted(src, binding, vn) { + binding.value(0, 0); + const info = mountings.get(src); + if (!info) return; + info.resize.disconnect(); + if (info.intersection) info.intersection.disconnect(); + mountings.delete(src); + }, +} as Directive<Element, (w: number, h: number) => void>; |