|
1 | | -const buttons = [ |
| 1 | +const zoomButtons = [ |
2 | 2 | { icon: "fa-plus", title: "Zoom in", action: (v) => v.viewport.zoomBy(1.5) }, |
3 | | - { icon: "fa-minus", title: "Zoom out", action: (v) => v.viewport.zoomBy(0.667) }, |
| 3 | + { |
| 4 | + icon: "fa-minus", |
| 5 | + title: "Zoom out", |
| 6 | + action: (v) => v.viewport.zoomBy(0.667), |
| 7 | + }, |
4 | 8 | { icon: "fa-home", title: "Reset view", action: (v) => v.viewport.goHome() }, |
5 | | - { icon: "fa-expand", title: "Full screen", action: (v) => v.setFullScreen(!v.isFullPage()) }, |
| 9 | + { |
| 10 | + icon: "fa-expand", |
| 11 | + title: "Full screen", |
| 12 | + action: (v) => v.setFullScreen(!v.isFullPage()), |
| 13 | + }, |
6 | 14 | ]; |
7 | 15 |
|
| 16 | +function makeButton({ icon, title, onClick }) { |
| 17 | + const btn = document.createElement("button"); |
| 18 | + btn.type = "button"; |
| 19 | + btn.className = "osd-btn"; |
| 20 | + btn.title = title; |
| 21 | + btn.innerHTML = `<i class="fas ${icon}"></i>`; |
| 22 | + btn.addEventListener("click", onClick); |
| 23 | + return btn; |
| 24 | +} |
| 25 | + |
| 26 | +function setViewerInteractive(viewer, enabled) { |
| 27 | + const settings = { |
| 28 | + scrollToZoom: enabled, |
| 29 | + clickToZoom: enabled, |
| 30 | + dblClickToZoom: enabled, |
| 31 | + pinchToZoom: enabled, |
| 32 | + flickEnabled: enabled, |
| 33 | + }; |
| 34 | + Object.assign(viewer.gestureSettingsMouse, settings); |
| 35 | + Object.assign(viewer.gestureSettingsTouch, settings); |
| 36 | + viewer.panHorizontal = enabled; |
| 37 | + viewer.panVertical = enabled; |
| 38 | +} |
| 39 | + |
8 | 40 | export function addViewerButtons(viewer, container) { |
9 | | - const group = document.createElement("div"); |
10 | | - Object.assign(group.style, { |
11 | | - position: "absolute", |
12 | | - top: "10px", |
13 | | - right: "10px", |
14 | | - zIndex: "10", |
15 | | - borderRadius: "0.375rem", |
16 | | - border: "1px solid rgba(0, 0, 0, 0.125)", |
17 | | - overflow: "hidden", |
18 | | - display: "flex", |
19 | | - flexDirection: "column", |
20 | | - }); |
| 41 | + container.style.position = "relative"; |
21 | 42 |
|
22 | | - for (const { icon, title, action } of buttons) { |
23 | | - const btn = document.createElement("button"); |
24 | | - btn.type = "button"; |
25 | | - btn.title = title; |
26 | | - btn.innerHTML = `<i class="fas ${icon}"></i>`; |
27 | | - Object.assign(btn.style, { |
28 | | - backgroundColor: "#fff", |
29 | | - border: "none", |
30 | | - borderBottom: "1px solid rgba(0, 0, 0, 0.125)", |
31 | | - color: "#495057", |
32 | | - fontSize: "0.875rem", |
33 | | - width: "32px", |
34 | | - height: "32px", |
35 | | - display: "flex", |
36 | | - alignItems: "center", |
37 | | - justifyContent: "center", |
38 | | - cursor: "pointer", |
39 | | - transition: "all 0.15s ease-in-out", |
40 | | - }); |
41 | | - btn.addEventListener("mouseenter", () => { |
42 | | - btn.style.backgroundColor = "#f8f9fa"; |
43 | | - btn.style.color = "#212529"; |
44 | | - }); |
45 | | - btn.addEventListener("mouseleave", () => { |
46 | | - btn.style.backgroundColor = "#fff"; |
47 | | - btn.style.color = "#495057"; |
48 | | - }); |
49 | | - btn.addEventListener("mousedown", () => { |
50 | | - btn.style.backgroundColor = "#e9ecef"; |
51 | | - }); |
52 | | - btn.addEventListener("mouseup", () => { |
53 | | - btn.style.backgroundColor = "#f8f9fa"; |
54 | | - }); |
55 | | - btn.addEventListener("click", () => action(viewer)); |
56 | | - group.appendChild(btn); |
| 43 | + // Start locked |
| 44 | + setViewerInteractive(viewer, false); |
| 45 | + |
| 46 | + // --- Locked state: single unlock button --- |
| 47 | + const lockedGroup = document.createElement("div"); |
| 48 | + lockedGroup.className = "osd-btn-group"; |
| 49 | + lockedGroup.appendChild( |
| 50 | + makeButton({ |
| 51 | + icon: "fa-search-plus", |
| 52 | + title: "Enable zoom", |
| 53 | + onClick: () => { |
| 54 | + setViewerInteractive(viewer, true); |
| 55 | + lockedGroup.style.display = "none"; |
| 56 | + unlockedGroup.style.display = "flex"; |
| 57 | + }, |
| 58 | + }), |
| 59 | + ); |
| 60 | + container.appendChild(lockedGroup); |
| 61 | + |
| 62 | + // --- Unlocked state: zoom controls + lock button --- |
| 63 | + const unlockedGroup = document.createElement("div"); |
| 64 | + unlockedGroup.className = "osd-btn-group"; |
| 65 | + unlockedGroup.style.display = "none"; |
| 66 | + |
| 67 | + for (const { icon, title, action } of zoomButtons) { |
| 68 | + unlockedGroup.appendChild( |
| 69 | + makeButton({ icon, title, onClick: () => action(viewer) }), |
| 70 | + ); |
57 | 71 | } |
58 | 72 |
|
59 | | - // Remove border-bottom from last button |
60 | | - group.lastElementChild.style.borderBottom = "none"; |
| 73 | + unlockedGroup.appendChild( |
| 74 | + makeButton({ |
| 75 | + icon: "fa-lock", |
| 76 | + title: "Lock view", |
| 77 | + onClick: () => { |
| 78 | + viewer.viewport.goHome(); |
| 79 | + setViewerInteractive(viewer, false); |
| 80 | + unlockedGroup.style.display = "none"; |
| 81 | + lockedGroup.style.display = "flex"; |
| 82 | + }, |
| 83 | + }), |
| 84 | + ); |
61 | 85 |
|
62 | | - container.style.position = "relative"; |
63 | | - container.appendChild(group); |
| 86 | + container.appendChild(unlockedGroup); |
64 | 87 | } |
0 commit comments