2023-01-13 04:40:33 +00:00
|
|
|
import { Directive } from "vue";
|
|
|
|
|
|
|
|
const mountings = new Map<
|
|
|
|
Element,
|
|
|
|
{
|
|
|
|
resize: ResizeObserver;
|
|
|
|
intersection?: IntersectionObserver;
|
|
|
|
fn: (w: number, h: number) => void;
|
|
|
|
}
|
|
|
|
>();
|
2022-02-06 01:59:36 +00:00
|
|
|
|
|
|
|
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) {
|
2023-01-13 04:40:33 +00:00
|
|
|
info.intersection = new IntersectionObserver((entries) => {
|
|
|
|
if (entries.some((entry) => entry.isIntersecting)) calc(src);
|
2022-02-06 01:59:36 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
info.intersection.observe(src);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (info.intersection) {
|
2022-06-10 05:36:55 +00:00
|
|
|
info.intersection.disconnect();
|
2023-01-13 04:40:33 +00:00
|
|
|
info.intersection = undefined;
|
2022-06-10 05:36:55 +00:00
|
|
|
}
|
2021-10-08 13:03:06 +00:00
|
|
|
|
2022-02-06 01:59:36 +00:00
|
|
|
info.fn(width, height);
|
2022-06-10 05:36:55 +00:00
|
|
|
}
|
2021-10-08 13:03:06 +00:00
|
|
|
|
2022-02-06 01:59:36 +00:00
|
|
|
export default {
|
|
|
|
mounted(src, binding, vn) {
|
|
|
|
const resize = new ResizeObserver((entries, observer) => {
|
|
|
|
calc(src);
|
2021-10-08 13:03:06 +00:00
|
|
|
});
|
2022-02-06 01:59:36 +00:00
|
|
|
resize.observe(src);
|
2021-10-08 13:03:06 +00:00
|
|
|
|
2023-01-13 04:40:33 +00:00
|
|
|
mountings.set(src, { resize, fn: binding.value });
|
2022-02-06 01:59:36 +00:00
|
|
|
calc(src);
|
2021-10-08 13:03:06 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
unmounted(src, binding, vn) {
|
|
|
|
binding.value(0, 0);
|
2022-02-06 01:59:36 +00:00
|
|
|
const info = mountings.get(src);
|
|
|
|
if (!info) return;
|
|
|
|
info.resize.disconnect();
|
|
|
|
if (info.intersection) info.intersection.disconnect();
|
|
|
|
mountings.delete(src);
|
2023-01-13 04:40:33 +00:00
|
|
|
},
|
2022-02-06 01:59:36 +00:00
|
|
|
} as Directive<Element, (w: number, h: number) => void>;
|