Thanks @Rushil Mahadevu, I forgot yesterday to update here that I've found a solution with the following component and I'll share it as well.
similar to your answer and the previous snipped I've shared it comes with the following features:
import { createRef } from "preact";
import { useLayoutEffect, useState } from "preact/hooks";
import type { JSX } from "preact/jsx-runtime";
// **********************************************************
export interface ContainerDocumentProps
{
docWidth: number,
docScale: number,
docPadX?: number,
children?: any,
}
// **********************************************************
export const ContainerDocument = (props: ContainerDocumentProps): JSX.Element =>
{
const clientRef = createRef<HTMLDivElement>();
const [areaWidth, setAreaWidth] = useState<number>(0);
const [docScale, setDocScale] = useState<number>(0.0);
const [userScollWidth, setUserScrollWidth] = useState<number>(0.5);
const onUpdateScale = (el: HTMLElement): void =>
{
const clientWidth = el.clientWidth;
const docPadX = props.docPadX ?? 0;
const docWidth = clientWidth * 0.75;
const docScale = (docWidth * props.docScale) / props.docWidth;
const areaScaled = Math.max(clientWidth, (props.docWidth + docPadX) * docScale);
el.scrollLeft = (areaScaled - clientWidth) * userScollWidth;
setAreaWidth(areaScaled);
setDocScale(docScale);
}
const onUpdateScroll = (ev: Event): void =>
{
const target = ev.target as HTMLDivElement;
setUserScrollWidth(target.scrollLeft / (target.scrollWidth - target.clientWidth));
}
useLayoutEffect(() =>
{
const el = clientRef.current;
if (el)
{
const observer = new ResizeObserver(() => onUpdateScale(el));
onUpdateScale(el);
observer.observe(el);
return () => observer.disconnect();
}
}, [clientRef.current, props.docScale]);
return (
<div class="w-100 h-100 overflow-y-scroll overflow-x-auto d-flex"
style="padding-top: 10vh; padding-bottom: 60vh;" ref={clientRef} onScroll={onUpdateScroll} >
<div class="position-relative d-flex flex-column" style={""
+ `min-width: ${areaWidth.toFixed(0)}px; height: fit-content;`} >
<div class="position-absolute top-0 start-50" style={"transform-origin: top center;"
+ `min-width: ${props.docWidth.toFixed(0)}px;`
+ `transform: translateX(-50%) scale(${docScale.toFixed(2)});`}
children={props.children} />
</div>
</div>
);
}
// **********************************************************