Skip to content

Commit

Permalink
feat: resolve currentPosition
Browse files Browse the repository at this point in the history
  • Loading branch information
Myriad-Dreamin committed Dec 14, 2024
1 parent 90d6d56 commit bf1da5d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
7 changes: 7 additions & 0 deletions tools/typst-preview-frontend/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
interface TypstPosition {
page: number;
x: number;
y: number;
}

interface Window {
initTypstSvg(docRoot: SVGElement): void;
currentPosition(elem: Element): TypstPosition | undefined;
handleTypstLocation(elem: Element, page: number, x: number, y: number);
typstWebsocket: WebSocket;
}
Expand Down
56 changes: 56 additions & 0 deletions tools/typst-preview-frontend/src/typst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,62 @@ function layoutText(svg: SVGElement) {
console.log(`layoutText used time ${performance.now() - layoutBegin} ms`);
}

window.currentPosition = function (elem: Element) {
const docRoot = findAncestor(elem, "typst-doc");
if (!docRoot) {
console.warn("no typst-doc found", elem);
return;
}

interface TypstPosition {
page: number;
x: number;
y: number;
distance: number;
}

let result: TypstPosition | undefined = undefined;
const windowX = window.innerWidth / 2;
const windowY = window.innerHeight / 2;
type ScrollRect = Pick<DOMRect, "left" | "top" | "width" | "height">;
const handlePage = (pageBBox: ScrollRect, page: number) => {
const x = pageBBox.left;
const y = pageBBox.top + pageBBox.height / 2;

const distance = Math.hypot(x - windowX, y - windowY);
if (result === undefined || distance < result.distance) {
result = { page, x, y, distance };
}
};

const renderMode = docRoot.getAttribute("data-render-mode");
if (renderMode === "canvas") {
const pages = docRoot.querySelectorAll<HTMLDivElement>(".typst-page");

for (const page of pages) {
const pageNumber = Number.parseInt(
page.getAttribute("data-page-number")!
);

const bbox = page.getBoundingClientRect();
handlePage(bbox, pageNumber);
}
return result;
}

const children = docRoot.children;
let nthPage = 0;
for (let i = 0; i < children.length; i++) {
if (children[i].tagName === "g") {
nthPage++;
}
const page = children[i] as SVGGElement;
const bbox = page.getBoundingClientRect();
handlePage(bbox, nthPage);
}
return result;
};

window.handleTypstLocation = function (
elem: Element,
pageNo: number,
Expand Down
14 changes: 10 additions & 4 deletions tools/typst-preview-frontend/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,16 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
}

if (message[0] === "jump" || message[0] === "viewport") {
const rootElem =
document.getElementById("typst-app")?.firstElementChild;

// todo: aware height padding
const current_page_number = svgDoc.getPartialPageNumber();
let currentPageNumber = 1;
if (previewMode === PreviewMode.Slide) {
currentPageNumber = svgDoc.getPartialPageNumber();
} else if (rootElem) {
currentPageNumber = window.currentPosition(rootElem)?.page || 1;
}

let positions = dec
.decode((message[1] as any).buffer)
Expand All @@ -315,7 +323,7 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
// choose the page, x, y closest to the current page
const [page, x, y] = positions.reduce((acc, cur) => {
const [page, x, y] = cur.split(" ").map(Number);
const current_page = current_page_number;
const current_page = currentPageNumber;
if (Math.abs(page - current_page) < Math.abs(acc[0] - current_page)) {
return [page, x, y];
}
Expand All @@ -338,8 +346,6 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
}
}

const rootElem =
document.getElementById("typst-app")?.firstElementChild;
if (rootElem) {
/// Note: when it is really scrolled, it will trigger `svgDoc.addViewportChange`
/// via `window.onscroll` event
Expand Down

0 comments on commit bf1da5d

Please sign in to comment.