diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 65d3d529dd002b1c3e20072978fc359d22b242de..57d24d82eee747e87c4a959e1b466627eda3bbbc 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -22,6 +22,33 @@ </div> </template> +<script lang="ts"> +/** + * アスペクト比算出ã®ãŸã‚ã«HTMLElement.clientWidthを使ã†ãŒã€ + * 大変é‡ãŸã„ã®ã§ã‚³ãƒ³ãƒ†ãƒŠè¦ç´ ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ãƒªã‚¹ãƒˆå¹…ã®ãƒšã‚¢ã‚’ã‚ャッシュã™ã‚‹ + * (タイムラインã”ã¨ã«ã‚¹ã‚¯ãƒãƒ¼ãƒ«ã‚³ãƒ³ãƒ†ãƒŠãŒå˜åœ¨ã™ã‚‹å‰æã ãŒâ€¦â€¦ï¼‰ + */ +const widthCache = new Map<Element, number>(); + +/** + * コンテナè¦ç´ ãŒãƒªã‚µã‚¤ã‚ºã•ã‚ŒãŸã‚‰ã‚ャッシュを削除ã™ã‚‹ + */ +const ro = new ResizeObserver(entries => { + for (const entry of entries) { + widthCache.delete(entry.target); + } +}); + +function getClientWidthWithCache(targetEl: HTMLElement, containerEl: HTMLElement) { + if (widthCache.has(containerEl)) return widthCache.get(containerEl)!; + + const width = targetEl.clientWidth; + widthCache.set(containerEl, width); + ro.observe(containerEl); + return width; +} +</script> + <script lang="ts" setup> import { onMounted, shallowRef } from 'vue'; import * as misskey from 'misskey-js'; @@ -62,7 +89,8 @@ function calcAspectRatio() { return; } - const width = gallery.value.clientWidth; + if (!container.value) container.value = getScrollContainer(root.value); + const width = container.value ? getClientWidthWithCache(root.value, container.value) : root.value.clientWidth; const heightMin = (ratio: number) => { const imgResizeRatio = width / img.properties.width; @@ -84,7 +112,6 @@ function calcAspectRatio() { gallery.value.style.height = heightMin(3 / 2); break; default: { - if (!container.value) container.value = getScrollContainer(root.value); const maxHeight = Math.max(64, (container.value ? container.value.clientHeight : getBodyScrollHeight()) * 0.5 || 360); if (width === 0 || !maxHeight) return; const imgResizeRatio = width / img.properties.width;