mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-07 21:15:03 +00:00
fix: bidirectional jump in slide mode (#1873)
Some checks are pending
tinymist::ci / Duplicate Actions Detection (push) Waiting to run
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Waiting to run
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Waiting to run
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-2022) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Blocked by required conditions
tinymist::ci / prepare-build (push) Waiting to run
tinymist::ci / build-binary (push) Blocked by required conditions
tinymist::ci / build-vsc-assets (push) Blocked by required conditions
tinymist::ci / build-vscode (push) Blocked by required conditions
tinymist::ci / build-vscode-others (push) Blocked by required conditions
tinymist::ci / publish-vscode (push) Blocked by required conditions
tinymist::gh_pages / build-gh-pages (push) Waiting to run
Some checks are pending
tinymist::ci / Duplicate Actions Detection (push) Waiting to run
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Waiting to run
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Waiting to run
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-2022) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Blocked by required conditions
tinymist::ci / prepare-build (push) Waiting to run
tinymist::ci / build-binary (push) Blocked by required conditions
tinymist::ci / build-vsc-assets (push) Blocked by required conditions
tinymist::ci / build-vscode (push) Blocked by required conditions
tinymist::ci / build-vscode-others (push) Blocked by required conditions
tinymist::ci / publish-vscode (push) Blocked by required conditions
tinymist::gh_pages / build-gh-pages (push) Waiting to run
This commit is contained in:
parent
32bd813be6
commit
2b7482b263
9 changed files with 157 additions and 99 deletions
|
@ -96,7 +96,7 @@ export function previewActivate(context: vscode.ExtensionContext, isCompat: bool
|
||||||
);
|
);
|
||||||
|
|
||||||
const launchBrowsingPreview = launch("webview", "doc", { isBrowsing: true });
|
const launchBrowsingPreview = launch("webview", "doc", { isBrowsing: true });
|
||||||
const launchDevPreview = launch("webview", "doc", { isDev: true });
|
const launchDevPreview = (mode: "doc" | "slide") => launch("webview", mode, { isDev: true });
|
||||||
// Registers preview commands, check `package.json` for descriptions.
|
// Registers preview commands, check `package.json` for descriptions.
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
vscode.commands.registerCommand("tinymist.browsingPreview", launchBrowsingPreview),
|
vscode.commands.registerCommand("tinymist.browsingPreview", launchBrowsingPreview),
|
||||||
|
@ -104,16 +104,19 @@ export function previewActivate(context: vscode.ExtensionContext, isCompat: bool
|
||||||
vscode.commands.registerCommand("typst-preview.browser", launch("browser", "doc")),
|
vscode.commands.registerCommand("typst-preview.browser", launch("browser", "doc")),
|
||||||
vscode.commands.registerCommand("typst-preview.preview-slide", launch("webview", "slide")),
|
vscode.commands.registerCommand("typst-preview.preview-slide", launch("webview", "slide")),
|
||||||
vscode.commands.registerCommand("typst-preview.browser-slide", launch("browser", "slide")),
|
vscode.commands.registerCommand("typst-preview.browser-slide", launch("browser", "slide")),
|
||||||
vscode.commands.registerCommand("typst-preview.eject", isCompat ? ejectPreviewPanelCompat : ejectPreviewPanelLsp),
|
vscode.commands.registerCommand("tinymist.previewDev", launchDevPreview("doc")),
|
||||||
vscode.commands.registerCommand("tinymist.previewDev", launchDevPreview),
|
vscode.commands.registerCommand("tinymist.previewDevSlide", launchDevPreview("slide")),
|
||||||
vscode.commands.registerCommand(
|
...(isCompat
|
||||||
"typst-preview.revealDocument",
|
? [
|
||||||
isCompat ? revealDocumentCompat : revealDocumentLsp,
|
vscode.commands.registerCommand("typst-preview.eject", ejectPreviewPanelCompat),
|
||||||
),
|
vscode.commands.registerCommand("typst-preview.revealDocument", revealDocumentCompat),
|
||||||
vscode.commands.registerCommand(
|
vscode.commands.registerCommand("typst-preview.sync", panelSyncScrollCompat),
|
||||||
"typst-preview.sync",
|
]
|
||||||
isCompat ? panelSyncScrollCompat : panelSyncScrollLsp,
|
: [
|
||||||
),
|
vscode.commands.registerCommand("typst-preview.eject", ejectPreviewPanelLsp),
|
||||||
|
vscode.commands.registerCommand("typst-preview.revealDocument", revealDocumentLsp),
|
||||||
|
vscode.commands.registerCommand("typst-preview.sync", panelSyncScrollLsp),
|
||||||
|
]),
|
||||||
vscode.commands.registerCommand("tinymist.doInspectPreviewState", () => {
|
vscode.commands.registerCommand("tinymist.doInspectPreviewState", () => {
|
||||||
const tasks = Array.from(activeTask.values()).map((t) => {
|
const tasks = Array.from(activeTask.values()).map((t) => {
|
||||||
return {
|
return {
|
||||||
|
@ -186,18 +189,23 @@ export function previewActivate(context: vscode.ExtensionContext, isCompat: bool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function launchForURI(uri: vscode.Uri, kind: "browser" | "webview", mode: "doc" | "slide", opts?: LaunchOpts) {
|
async function launchForURI(
|
||||||
|
uri: vscode.Uri,
|
||||||
|
kind: "browser" | "webview",
|
||||||
|
mode: "doc" | "slide",
|
||||||
|
opts?: LaunchOpts,
|
||||||
|
) {
|
||||||
const doc =
|
const doc =
|
||||||
vscode.workspace.textDocuments.find((doc) => {
|
vscode.workspace.textDocuments.find((doc) => {
|
||||||
return doc.uri.toString() === uri.toString();
|
return doc.uri.toString() === uri.toString();
|
||||||
}) || (await vscode.workspace.openTextDocument(uri));
|
}) || (await vscode.workspace.openTextDocument(uri));
|
||||||
const editor = await vscode.window.showTextDocument(doc, getSensibleTextEditorColumn(), true);
|
const editor = await vscode.window.showTextDocument(doc, getSensibleTextEditorColumn(), true);
|
||||||
|
|
||||||
const bindDocument = editor.document;
|
const bindDocument = editor.document;
|
||||||
const isBrowsing = opts?.isBrowsing;
|
const isBrowsing = opts?.isBrowsing;
|
||||||
const isDev = opts?.isDev;
|
const isDev = opts?.isDev;
|
||||||
const isNotPrimary = opts?.isNotPrimary;
|
const isNotPrimary = opts?.isNotPrimary;
|
||||||
|
|
||||||
await launchImpl({
|
await launchImpl({
|
||||||
kind,
|
kind,
|
||||||
context,
|
context,
|
||||||
|
@ -209,7 +217,7 @@ export function previewActivate(context: vscode.ExtensionContext, isCompat: bool
|
||||||
isNotPrimary,
|
isNotPrimary,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ejects the preview panel to the external browser.
|
* Ejects the preview panel to the external browser.
|
||||||
*/
|
*/
|
||||||
|
@ -220,10 +228,10 @@ export function previewActivate(context: vscode.ExtensionContext, isCompat: bool
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { panel, state } = focusingContext;
|
const { panel, state } = focusingContext;
|
||||||
|
|
||||||
// Close the preview panel, basically kill the previous preview task.
|
// Close the preview panel, basically kill the previous preview task.
|
||||||
panel.dispose();
|
panel.dispose();
|
||||||
|
|
||||||
await launchForURI(vscode.Uri.parse(state.uri), "browser", state.mode, {
|
await launchForURI(vscode.Uri.parse(state.uri), "browser", state.mode, {
|
||||||
isBrowsing: state.isBrowsing,
|
isBrowsing: state.isBrowsing,
|
||||||
isDev: state.isDev,
|
isDev: state.isDev,
|
||||||
|
@ -318,7 +326,7 @@ export async function openPreviewInWebView({
|
||||||
uri: activeEditor.document.uri.toString(),
|
uri: activeEditor.document.uri.toString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateActivePanel =() => {
|
const updateActivePanel = () => {
|
||||||
if (panel.active) {
|
if (panel.active) {
|
||||||
extensionState.mut.focusingPreviewPanelContext = {
|
extensionState.mut.focusingPreviewPanelContext = {
|
||||||
panel,
|
panel,
|
||||||
|
|
20
tests/workspaces/slides/touying.typ
Normal file
20
tests/workspaces/slides/touying.typ
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#import "@preview/touying:0.6.1": *
|
||||||
|
#import themes.dewdrop: *
|
||||||
|
|
||||||
|
#show: dewdrop-theme.with(aspect-ratio: "16-9")
|
||||||
|
|
||||||
|
= Section 1
|
||||||
|
|
||||||
|
== Subsection 1
|
||||||
|
|
||||||
|
=== Title
|
||||||
|
|
||||||
|
Hello, Touying!
|
||||||
|
|
||||||
|
= Section 2
|
||||||
|
|
||||||
|
== Subsection 2
|
||||||
|
|
||||||
|
=== Title
|
||||||
|
|
||||||
|
Hello, Touying!
|
|
@ -1,5 +1,5 @@
|
||||||
import { triggerRipple } from "./typst-animation.mjs";
|
import { triggerRipple } from "./typst-animation.mjs";
|
||||||
import type { GConstructor, TypstDocumentContext } from "./typst-doc.mjs";
|
import { PreviewMode, type GConstructor, type TypstDocumentContext } from "./typst-doc.mjs";
|
||||||
|
|
||||||
const enum SourceMappingType {
|
const enum SourceMappingType {
|
||||||
Text = 0,
|
Text = 0,
|
||||||
|
@ -225,5 +225,83 @@ export function provideDebugJumpDoc<TBase extends GConstructor<TypstDocumentCont
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollTo(pageRect: ScrollRect, pageNo: number, innerLeft: number, innerTop: number) {
|
||||||
|
if (this.previewMode === PreviewMode.Slide) {
|
||||||
|
this.setPartialPageNumber(pageNo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const windowRoot = document.body || document.firstElementChild;
|
||||||
|
const basePos = windowRoot.getBoundingClientRect();
|
||||||
|
|
||||||
|
const left = innerLeft - basePos.left;
|
||||||
|
const top = innerTop - basePos.top;
|
||||||
|
|
||||||
|
// evaluate window viewport 1vw
|
||||||
|
const pw = window.innerWidth * 0.01;
|
||||||
|
const ph = window.innerHeight * 0.01;
|
||||||
|
|
||||||
|
const xOffsetInnerFix = 7 * pw;
|
||||||
|
const yOffsetInnerFix = 38.2 * ph;
|
||||||
|
|
||||||
|
const xOffset = left - xOffsetInnerFix;
|
||||||
|
const yOffset = top - yOffsetInnerFix;
|
||||||
|
|
||||||
|
const widthOccupied = (100 * 100 * pw) / pageRect.width;
|
||||||
|
|
||||||
|
const pageAdjustLeft = pageRect.left - basePos.left - 5 * pw;
|
||||||
|
const pageAdjust = pageRect.left - basePos.left + pageRect.width - 95 * pw;
|
||||||
|
|
||||||
|
// default single-column or multi-column layout
|
||||||
|
if (widthOccupied >= 90 || widthOccupied < 50) {
|
||||||
|
window.scrollTo({ behavior: "smooth", left: xOffset, top: yOffset });
|
||||||
|
} else {
|
||||||
|
// for double-column layout
|
||||||
|
// console.log('occupied adjustment', widthOccupied, page);
|
||||||
|
|
||||||
|
const xOffsetAdjsut = xOffset > pageAdjust ? pageAdjust : pageAdjustLeft;
|
||||||
|
|
||||||
|
window.scrollTo({ behavior: "smooth", left: xOffsetAdjsut, top: yOffset });
|
||||||
|
}
|
||||||
|
|
||||||
|
// grid ripple for debug vw
|
||||||
|
// triggerRipple(
|
||||||
|
// windowRoot,
|
||||||
|
// svgRect.left + 50 * vw,
|
||||||
|
// svgRect.top + 1 * vh,
|
||||||
|
// "typst-jump-ripple",
|
||||||
|
// "typst-jump-ripple-effect .4s linear",
|
||||||
|
// "green",
|
||||||
|
// );
|
||||||
|
|
||||||
|
// triggerRipple(
|
||||||
|
// windowRoot,
|
||||||
|
// pageRect.left - basePos.left + vw,
|
||||||
|
// pageRect.top - basePos.top + vh,
|
||||||
|
// "typst-jump-ripple",
|
||||||
|
// "typst-jump-ripple-effect .4s linear",
|
||||||
|
// "red",
|
||||||
|
// );
|
||||||
|
|
||||||
|
// triggerRipple(
|
||||||
|
// windowRoot,
|
||||||
|
// pageAdjust,
|
||||||
|
// pageRect.top - basePos.top + vh,
|
||||||
|
// "typst-jump-ripple",
|
||||||
|
// "typst-jump-ripple-effect .4s linear",
|
||||||
|
// "red",
|
||||||
|
// );
|
||||||
|
|
||||||
|
triggerRipple(
|
||||||
|
windowRoot,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
"typst-jump-ripple",
|
||||||
|
"typst-jump-ripple-effect .4s linear",
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ScrollRect = Pick<DOMRect, "left" | "top" | "width" | "height">;
|
||||||
|
|
|
@ -463,6 +463,19 @@ export class TypstDocumentContext<O = any> {
|
||||||
addViewportChange() {
|
addViewportChange() {
|
||||||
this.addChangement(["viewport-change", ""]);
|
this.addChangement(["viewport-change", ""]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPartialPageNumber(page: number): boolean {
|
||||||
|
if (page <= 0 || page > this.kModule.retrievePagesInfo().length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.partialRenderPage = page - 1;
|
||||||
|
this.addViewportChange();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPartialPageNumber(): number {
|
||||||
|
return this.partialRenderPage + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TypstDocument<T> {
|
export interface TypstDocument<T> {
|
||||||
|
@ -536,16 +549,11 @@ export function provideDoc<T extends TypstDocumentContext>(
|
||||||
}
|
}
|
||||||
|
|
||||||
setPartialPageNumber(page: number): boolean {
|
setPartialPageNumber(page: number): boolean {
|
||||||
if (page <= 0 || page > this.kModule.retrievePagesInfo().length) {
|
return this.impl.setPartialPageNumber(page);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.impl.partialRenderPage = page - 1;
|
|
||||||
this.addViewportChange();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPartialPageNumber(): number {
|
getPartialPageNumber(): number {
|
||||||
return this.impl.partialRenderPage + 1;
|
return this.impl.getPartialPageNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
setOutineData(outline: any) {
|
setOutineData(outline: any) {
|
||||||
|
|
|
@ -350,7 +350,7 @@ export function provideSvgDoc<
|
||||||
const height = Number.parseFloat(elem.getAttribute("data-page-height")!);
|
const height = Number.parseFloat(elem.getAttribute("data-page-height")!);
|
||||||
maxWidth = Math.max(maxWidth, width);
|
maxWidth = Math.max(maxWidth, width);
|
||||||
return {
|
return {
|
||||||
index,
|
index: mode === PreviewMode.Slide ? this.partialRenderPage : index,
|
||||||
elem,
|
elem,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
|
1
tools/typst-preview-frontend/src/global.d.ts
vendored
1
tools/typst-preview-frontend/src/global.d.ts
vendored
|
@ -8,6 +8,7 @@ interface Window {
|
||||||
initTypstSvg(docRoot: SVGElement): void;
|
initTypstSvg(docRoot: SVGElement): void;
|
||||||
currentPosition(elem: Element): TypstPosition | undefined;
|
currentPosition(elem: Element): TypstPosition | undefined;
|
||||||
handleTypstLocation(elem: Element, page: number, x: number, y: number);
|
handleTypstLocation(elem: Element, page: number, x: number, y: number);
|
||||||
|
documents: any[];
|
||||||
typstWebsocket: WebSocket;
|
typstWebsocket: WebSocket;
|
||||||
}
|
}
|
||||||
const acquireVsCodeApi: any;
|
const acquireVsCodeApi: any;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import "./styles/outline.css";
|
||||||
import { wsMain, PreviewMode } from "./ws";
|
import { wsMain, PreviewMode } from "./ws";
|
||||||
import { setupDrag } from "./drag";
|
import { setupDrag } from "./drag";
|
||||||
|
|
||||||
|
window.documents = [];
|
||||||
|
|
||||||
/// Main entry point of the frontend program.
|
/// Main entry point of the frontend program.
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { triggerRipple } from "typst-dom/typst-animation.mjs";
|
|
||||||
|
|
||||||
// debounce https://stackoverflow.com/questions/23181243/throttling-a-mousemove-event-to-fire-no-more-than-5-times-a-second
|
// debounce https://stackoverflow.com/questions/23181243/throttling-a-mousemove-event-to-fire-no-more-than-5-times-a-second
|
||||||
// ignore fast events, good for capturing double click
|
// ignore fast events, good for capturing double click
|
||||||
// @param (callback): function to be run when done
|
// @param (callback): function to be run when done
|
||||||
|
@ -240,6 +238,7 @@ window.currentPosition = function (elem: Element) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ScrollRect = Pick<DOMRect, "left" | "top" | "width" | "height">;
|
||||||
window.handleTypstLocation = function (elem: Element, pageNo: number, x: number, y: number) {
|
window.handleTypstLocation = function (elem: Element, pageNo: number, x: number, y: number) {
|
||||||
const docRoot = findAncestor(elem, "typst-doc");
|
const docRoot = findAncestor(elem, "typst-doc");
|
||||||
if (!docRoot) {
|
if (!docRoot) {
|
||||||
|
@ -247,76 +246,12 @@ window.handleTypstLocation = function (elem: Element, pageNo: number, x: number,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScrollRect = Pick<DOMRect, "left" | "top" | "width" | "height">;
|
// scrollTo(pageRect: ScrollRect, pageNo: number, innerLeft: number, innerTop: number)
|
||||||
const scrollTo = (pageRect: ScrollRect, innerLeft: number, innerTop: number) => {
|
|
||||||
const windowRoot = document.body || document.firstElementChild;
|
|
||||||
const basePos = windowRoot.getBoundingClientRect();
|
|
||||||
|
|
||||||
const left = innerLeft - basePos.left;
|
const scrollTo = (pageRect: ScrollRect, pageNo: number, innerLeft: number, innerTop: number) => {
|
||||||
const top = innerTop - basePos.top;
|
for (const doc of window.documents) {
|
||||||
|
doc.impl.scrollTo(pageRect, pageNo, innerLeft, innerTop);
|
||||||
// evaluate window viewport 1vw
|
|
||||||
const pw = window.innerWidth * 0.01;
|
|
||||||
const ph = window.innerHeight * 0.01;
|
|
||||||
|
|
||||||
const xOffsetInnerFix = 7 * pw;
|
|
||||||
const yOffsetInnerFix = 38.2 * ph;
|
|
||||||
|
|
||||||
const xOffset = left - xOffsetInnerFix;
|
|
||||||
const yOffset = top - yOffsetInnerFix;
|
|
||||||
|
|
||||||
const widthOccupied = (100 * 100 * pw) / pageRect.width;
|
|
||||||
|
|
||||||
const pageAdjustLeft = pageRect.left - basePos.left - 5 * pw;
|
|
||||||
const pageAdjust = pageRect.left - basePos.left + pageRect.width - 95 * pw;
|
|
||||||
|
|
||||||
// default single-column or multi-column layout
|
|
||||||
if (widthOccupied >= 90 || widthOccupied < 50) {
|
|
||||||
window.scrollTo({ behavior: "smooth", left: xOffset, top: yOffset });
|
|
||||||
} else {
|
|
||||||
// for double-column layout
|
|
||||||
// console.log('occupied adjustment', widthOccupied, page);
|
|
||||||
|
|
||||||
const xOffsetAdjsut = xOffset > pageAdjust ? pageAdjust : pageAdjustLeft;
|
|
||||||
|
|
||||||
window.scrollTo({ behavior: "smooth", left: xOffsetAdjsut, top: yOffset });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// grid ripple for debug vw
|
|
||||||
// triggerRipple(
|
|
||||||
// windowRoot,
|
|
||||||
// svgRect.left + 50 * vw,
|
|
||||||
// svgRect.top + 1 * vh,
|
|
||||||
// "typst-jump-ripple",
|
|
||||||
// "typst-jump-ripple-effect .4s linear",
|
|
||||||
// "green",
|
|
||||||
// );
|
|
||||||
|
|
||||||
// triggerRipple(
|
|
||||||
// windowRoot,
|
|
||||||
// pageRect.left - basePos.left + vw,
|
|
||||||
// pageRect.top - basePos.top + vh,
|
|
||||||
// "typst-jump-ripple",
|
|
||||||
// "typst-jump-ripple-effect .4s linear",
|
|
||||||
// "red",
|
|
||||||
// );
|
|
||||||
|
|
||||||
// triggerRipple(
|
|
||||||
// windowRoot,
|
|
||||||
// pageAdjust,
|
|
||||||
// pageRect.top - basePos.top + vh,
|
|
||||||
// "typst-jump-ripple",
|
|
||||||
// "typst-jump-ripple-effect .4s linear",
|
|
||||||
// "red",
|
|
||||||
// );
|
|
||||||
|
|
||||||
triggerRipple(
|
|
||||||
windowRoot,
|
|
||||||
left,
|
|
||||||
top,
|
|
||||||
"typst-jump-ripple",
|
|
||||||
"typst-jump-ripple-effect .4s linear",
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderMode = docRoot.getAttribute("data-render-mode");
|
const renderMode = docRoot.getAttribute("data-render-mode");
|
||||||
|
@ -359,7 +294,7 @@ window.handleTypstLocation = function (elem: Element, pageNo: number, x: number,
|
||||||
|
|
||||||
console.log("canvas mode jump", left, top, canvasRect, dataWidth, dataHeight, x, y);
|
console.log("canvas mode jump", left, top, canvasRect, dataWidth, dataHeight, x, y);
|
||||||
|
|
||||||
scrollTo(canvasRect, left, top);
|
scrollTo(canvasRect, pageNo, left, top);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +329,7 @@ window.handleTypstLocation = function (elem: Element, pageNo: number, x: number,
|
||||||
const left = svgRect.left + (x / dataWidth) * svgRect.width;
|
const left = svgRect.left + (x / dataWidth) * svgRect.width;
|
||||||
const top = svgRect.top + (y / dataHeight) * svgRect.height;
|
const top = svgRect.top + (y / dataHeight) * svgRect.height;
|
||||||
|
|
||||||
scrollTo(pageRect, left, top);
|
scrollTo(pageRect, pageNo, left, top);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,8 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupSocket(svgDoc: TypstDocument): () => void {
|
function setupSocket(svgDoc: TypstDocument): () => void {
|
||||||
|
window.documents.push(svgDoc);
|
||||||
|
|
||||||
// todo: reconnect setTimeout(() => setupSocket(svgDoc), 1000);
|
// todo: reconnect setTimeout(() => setupSocket(svgDoc), 1000);
|
||||||
$ws = webSocket<ArrayBuffer>({
|
$ws = webSocket<ArrayBuffer>({
|
||||||
url,
|
url,
|
||||||
|
@ -249,6 +251,10 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
|
||||||
const dispose = () => {
|
const dispose = () => {
|
||||||
disposed = true;
|
disposed = true;
|
||||||
svgDoc.dispose();
|
svgDoc.dispose();
|
||||||
|
const index = window.documents.indexOf(svgDoc);
|
||||||
|
if (index >= 0) {
|
||||||
|
window.documents.splice(index, 1);
|
||||||
|
}
|
||||||
for (const sub of subsribes.splice(0, subsribes.length)) {
|
for (const sub of subsribes.splice(0, subsribes.length)) {
|
||||||
sub.unsubscribe();
|
sub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue