@hajimism/dek 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/cli/serve.ts +1 -1
- package/src/core/chrome.ts +3 -1
- package/src/core/document.ts +17 -2
- package/src/core/html.ts +99 -14
- package/src/core/page.ts +1 -0
- package/src/runtime/annotate-notes.ts +207 -0
- package/src/runtime/annotate-pick.ts +148 -0
- package/src/runtime/annotate-place.ts +46 -0
- package/src/runtime/annotate-view.ts +738 -0
- package/src/runtime/annotate.ts +15 -0
- package/src/runtime/player.ts +15 -7
- package/src/server/dev.ts +2 -1
- package/src/server/pages.ts +2 -1
- package/src/server/routes.ts +9 -3
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Where annotate mode's popup goes: beside what was picked, never over it, inside the window.
|
|
2
|
+
|
|
3
|
+
type Rect = { left: number; top: number; right: number; bottom: number };
|
|
4
|
+
type Size = { width: number; height: number };
|
|
5
|
+
|
|
6
|
+
/** How far the popup keeps from what was picked and from the window's edges. */
|
|
7
|
+
const GAP = 8;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The popup's top left corner for a note on `picked`, the box around every element picked:
|
|
11
|
+
* under it, else above it, else to its right, else to its left, on the first side it fits on
|
|
12
|
+
* whole. Covering what the note is about would hide what the human is pointing at. When no side
|
|
13
|
+
* fits, it goes under, held inside the window.
|
|
14
|
+
*/
|
|
15
|
+
export function placePopup(
|
|
16
|
+
picked: Rect,
|
|
17
|
+
size: Size,
|
|
18
|
+
viewport: Size,
|
|
19
|
+
): { left: number; top: number } {
|
|
20
|
+
const clampLeft = (left: number): number =>
|
|
21
|
+
Math.max(GAP, Math.min(left, viewport.width - size.width - GAP));
|
|
22
|
+
const clampTop = (top: number): number =>
|
|
23
|
+
Math.max(GAP, Math.min(top, viewport.height - size.height - GAP));
|
|
24
|
+
const fitsTop = (top: number): boolean =>
|
|
25
|
+
top >= GAP && top + size.height <= viewport.height - GAP;
|
|
26
|
+
const fitsLeft = (left: number): boolean =>
|
|
27
|
+
left >= GAP && left + size.width <= viewport.width - GAP;
|
|
28
|
+
|
|
29
|
+
const below = picked.bottom + GAP;
|
|
30
|
+
if (fitsTop(below)) {
|
|
31
|
+
return { left: clampLeft(picked.left), top: below };
|
|
32
|
+
}
|
|
33
|
+
const above = picked.top - GAP - size.height;
|
|
34
|
+
if (fitsTop(above)) {
|
|
35
|
+
return { left: clampLeft(picked.left), top: above };
|
|
36
|
+
}
|
|
37
|
+
const right = picked.right + GAP;
|
|
38
|
+
if (fitsLeft(right)) {
|
|
39
|
+
return { left: right, top: clampTop(picked.top) };
|
|
40
|
+
}
|
|
41
|
+
const left = picked.left - GAP - size.width;
|
|
42
|
+
if (fitsLeft(left)) {
|
|
43
|
+
return { left, top: clampTop(picked.top) };
|
|
44
|
+
}
|
|
45
|
+
return { left: clampLeft(picked.left), top: clampTop(below) };
|
|
46
|
+
}
|