79402450

Date: 2025-01-31 10:36:48
Score: 1.5
Natty:
Report link

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>
    );
}

// **********************************************************
Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Rushil
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: magg