Advanced viewport configuration
advancedslide loader
Console
PMA.UI version: 2.43.3
An example showing advanced configuration options for the viewport
advanced_viewport.html
1<!doctype >
2<html lang="en">
3
4<head>
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=10">
7 <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
8
9 <!-- Include PMA.UI required libraries downloaded or from CDN -->
10 <script src="./pma.ui/jquery-3.1.0.js"></script>
11 <link href="./pma.ui/font-awesome.min.css" type="text/css" rel="stylesheet">
12
13 <!-- Include optional libraries downloaded or from CDN -->
14 <link rel="stylesheet" href="./pma.ui/bootstrap.min.css">
15 <script src="./pma.ui/bootstrap.bundle.min.js"></script>
16
17 <!-- Include PMA.UI script & css -->
18 <script src="./pma.ui/pma.ui.js"></script>
19 <link href="./pma.ui/pma.ui.css" type="text/css" rel="stylesheet">
20
21 <!-- Include custom script & css -->
22 <script src="./js/advanced_viewport.js"></script>
23 <link href="./css/advanced_viewport.css" type="text/css" rel="stylesheet">
24
25 <title>Advanced viewport configuration</title>
26</head>
27
28<body>
29 <div class="container-fluid">
30 <div class="row">
31 <div class="col-4 py-1 border-right">
32 <form>
33 <fieldset id="controls" disabled>
34 <div class="form-group row">
35 <label class="col-5 col-form-label col-form-label-sm">Overview</label>
36 <div class="custom-control custom-switch col-3 pt-2">
37 <input type="checkbox" class="custom-control-input" id="overview-visible">
38 <label class="custom-control-label" for="overview-visible">Visible</label>
39 </div>
40 <div class="custom-control custom-switch col-3 pt-2">
41 <input type="checkbox" class="custom-control-input" id="overview-collapsed">
42 <label class="custom-control-label" for="overview-collapsed">Collapse</label>
43 </div>
44 </div>
45 <div class="form-group row">
46 <label class="col-5 col-form-label col-form-label-sm">Dimensions control</label>
47 <div class="custom-control custom-switch col-3 pt-2">
48 <input type="checkbox" class="custom-control-input" id="dimensionselector-visible">
49 <label class="custom-control-label" for="dimensionselector-visible">Visible</label>
50 </div>
51 <div class="custom-control custom-switch col-3 pt-2">
52 <input type="checkbox" class="custom-control-input" id="dimensionselector-collapsed">
53 <label class="custom-control-label" for="dimensionselector-collapsed">Collapse</label>
54 </div>
55 </div>
56 <div class="form-group row">
57 <label class="col-5 col-form-label col-form-label-sm">Barcode</label>
58 <div class="custom-control custom-switch col-3 pt-2">
59 <input type="checkbox" class="custom-control-input" id="barcode-visible">
60 <label class="custom-control-label" for="barcode-visible">Visible</label>
61 </div>
62 <div class="custom-control custom-switch col-3 pt-2">
63 <input type="checkbox" class="custom-control-input" id="barcode-collapsed">
64 <label class="custom-control-label" for="barcode-collapsed">Collapse</label>
65 </div>
66 </div>
67 <div class="form-group row">
68 <label class="col-5 col-form-label col-form-label-sm">Rotation</label>
69 <div class="custom-control custom-switch col-3 pt-2">
70 <input type="checkbox" class="custom-control-input" id="rotation-visible">
71 <label class="custom-control-label" for="rotation-visible">Visible</label>
72 </div>
73 <div class="custom-control custom-switch col-3 pt-2">
74 <input type="checkbox" class="custom-control-input" id="rotation-collapsed">
75 <label class="custom-control-label" for="rotation-collapsed">Collapse</label>
76 </div>
77 </div>
78 <div class="form-group row">
79 <label class="col-5 col-form-label col-form-label-sm">File path</label>
80 <div class="custom-control custom-switch col-3 pt-2">
81 <input type="checkbox" class="custom-control-input" id="filename-visible">
82 <label class="custom-control-label" for="filename-visible">Visible</label>
83 </div>
84 <div class="custom-control custom-switch col-3 pt-2">
85 <input type="checkbox" class="custom-control-input" id="filename-collapsed">
86 <label class="custom-control-label" for="filename-collapsed">Collapse</label>
87 </div>
88 </div>
89 <div class="form-group row">
90 <label class="col-5 col-form-label col-form-label-sm">Scale line</label>
91 <div class="custom-control custom-switch col-3 pt-2">
92 <input type="checkbox" class="custom-control-input" id="scaleline-visible">
93 <label class="custom-control-label" for="scaleline-visible">Visible</label>
94 </div>
95 <div class="custom-control custom-switch col-3 pt-2">
96 <input type="checkbox" class="custom-control-input" id="scaleline-collapsed">
97 <label class="custom-control-label" for="scaleline-collapsed">Collapse</label>
98 </div>
99 </div>
100 <div class="form-group row">
101 <label class="col-5 col-form-label col-form-label-sm">Snapshot button</label>
102 <div class="custom-control custom-switch col-3 pt-2">
103 <input type="checkbox" class="custom-control-input" id="shapshot-visible">
104 <label class="custom-control-label" for="shapshot-visible">Visible</label>
105 </div>
106 </div>
107 <div class="form-group row">
108 <label class="col-5 col-form-label col-form-label-sm">Color adjustments</label>
109 <div class="custom-control custom-switch col-3 pt-2">
110 <input type="checkbox" class="custom-control-input" id="coloradjustments-visible">
111 <label class="custom-control-label" for="coloradjustments-visible">Visible</label>
112 </div>
113 </div>
114 <div class="form-group row">
115 <label class="col-5 col-form-label col-form-label-sm">Zoom slider</label>
116 <div class="custom-control custom-switch col-3 pt-2">
117 <input type="checkbox" class="custom-control-input" id="zoomslider-visible">
118 <label class="custom-control-label" for="zoomslider-visible">Visible</label>
119 </div>
120 </div>
121 <div class="form-group row">
122 <label class="col-5 col-form-label col-form-label-sm">Theme</label>
123 <select class="custom-select theme-select col-6 pt-2">
124 <option selected value="default">Default</option>
125 <option value="classic">Classic</option>
126 <option value="modern">Modern</option>
127 </select>
128 </div>
129 <div class="form-group row">
130 <label class="col-5 col-form-label col-form-label-sm">Μouse wheel mode</label>
131 <div class="custom-control custom-switch col-3 pt-2">
132 <input type="checkbox" class="custom-control-input" id="mouse-wheel-mode">
133 <label class="custom-control-label" for="mouse-wheel-mode">Normal/Objectives</label>
134 </div>
135 </div>
136 <div class="form-group row">
137 <label class="col-5 col-form-label col-form-label-sm">Μouse wheel delta</label>
138 <input type="number" class="form-control col-6 pt-2" min="1" max="10000" id="mouse-wheel-delta">
139 </div>
140 <div class="form-group row">
141 <label class="col-5 col-form-label col-form-label-sm">Digital zoom levels</label>
142 <input type="number" class="form-control col-6 pt-2" min="0" max="5" id="digital-zoom-levels">
143 </div>
144 <div class="form-group row">
145 <label class="col-5 col-form-label col-form-label-sm">Keyboard pan factor</label>
146 <input type="number" class="form-control col-6 pt-2" min="0" max="3" step="0.01" id="keyboard-pan-factor">
147 </div>
148 <div class="form-group row">
149 <label class="col-5 col-form-label col-form-label-sm">Keyboard zoom delta</label>
150 <input type="number" class="form-control col-6 pt-2" min="0" max="3" step="0.01" id="keyboard-zoom-delta">
151 </div>
152 <div class="form-group row">
153 <label class="col-5 col-form-label col-form-label-sm">Flip</label>
154 <div class="form-check form-check-inline">
155 <input class="form-check-input" type="checkbox" id="input-flip-hor">
156 <label class="form-check-label">Horizontally</label>
157 </div>
158 <div class="form-check form-check-inline">
159 <input class="form-check-input" type="checkbox" id="input-flip-ver">
160 <label class="form-check-label">Vertically</label>
161 </div>
162 </div>
163 <hr />
164 <div class="form-group row">
165 <div class="col">
166 <button id="reset-btn" type="button" class="btn btn-light btn-sm"><i class="fas fa-history"></i>
167 Reset values</button>
168 </div>
169 </div>
170 </fieldset>
171 </form>
172 </div>
173 <div class="col-8 p-0">
174 <!-- The element that will host the viewport -->
175 <div id="viewer"></div>
176 </div>
177 </div>
178 </div>
179</body>
180
181</html>
advanced_viewport.css
1html,
2body
3{
4 height: 100%;
5 padding: 0px;
6 margin: 0px;
7}
8
9#viewer
10{
11 height: 100vh;
12}
advanced_viewport.js
1// Initial declarations
2var serverUrl = "https://host.pathomation.com/pma.core.3/";
3var serverUsername = "PMA_UI_demo";
4var serverPassword = "PMA_UI_demo";
5var caller = "DemoPortal";
6var slideLoaderElementSelector = "#viewer";
7var imagePath = "wsiformats/fluo/Olympus/Image_2018-005-KB 20x VZ.vsi";
8var slideLoader = null;
9var currentConfiguration;
10const initialConfiguration = {
11 controls: [
12 {
13 "control": "zoomslider",
14 "visible": false
15 },
16 {
17 "control": "scaleline",
18 "visible": false,
19 "collapsed": false
20 },
21 {
22 "control": "overview",
23 "visible": false,
24 "collapsed": false
25 },
26 {
27 "control": "barcode",
28 "visible": false,
29 "collapsed": false,
30 "rotation": 0
31 },
32 {
33 "control": "magnifier",
34 "visible": true
35 },
36 {
37 "control": "coloradjustments",
38 "visible": false
39 },
40 {
41 "control": "layerswitch",
42 "visible": false,
43 "collapsed": false
44 },
45 {
46 "control": "dimensionselector",
47 "visible": false,
48 "collapsed": false
49 },
50 {
51 "control": "filename",
52 "visible": false,
53 "collapsed": false,
54 "filename": null
55 },
56 {
57 "control": "shapshot",
58 "visible": false
59 },
60 {
61 "control": "rotation",
62 "visible": false,
63 "collapsed": false
64 },
65 {
66 "control": "attribution",
67 "visible": false,
68 "options": null
69 },
70 {
71 "control": "mouseWheel",
72 "mode": "normal",
73 "delta": 100,
74 "levels": 2
75 }
76 ],
77 mouseWheelZoomDelta: 100,
78 mouseWheelZoomMode: PMA.UI.Types.MouseWheelZoomMode.normal,
79 theme: PMA.UI.View.Themes.Default,
80 digitalZoomLevels: 2,
81 keyboardPanFactor: 0.5,
82 keyboardZoomDelta: 1,
83 flipHor: false,
84 flipVer: false,
85};
86
87function setControlsFromConfiguration(conf) {
88 if (!conf) {
89 return;
90 }
91
92 if (conf.controls) {
93 for (let i = 0; i < conf.controls.length; i++) {
94 let c = conf.controls[i];
95 if (c.hasOwnProperty("visible")) {
96 $(`#${c.control}-visible`).prop("checked", c.visible === true);
97 }
98 if (c.hasOwnProperty("collapse")) {
99 $(`#${c.control}-collapse`).prop("checked", c.collapse === true);
100 }
101 }
102 }
103
104 if (conf.mouseWheelZoomMode) {
105 $("#mouse-wheel-mode").prop("checked", conf.mouseWheelZoomMode === PMA.UI.Types.MouseWheelZoomMode.objectives);
106 }
107
108 if (conf.mouseWheelZoomDelta) {
109 $("#mouse-wheel-delta").val(conf.mouseWheelZoomDelta);
110 }
111
112 if (conf.theme) {
113 $(".theme-select").val(conf.theme);
114 }
115
116 if (conf.digitalZoomLevels) {
117 $("#digital-zoom-levels").val(conf.digitalZoomLevels);
118 }
119
120 if (conf.keyboardPanFactor) {
121 $("#keyboard-pan-factor").val(conf.keyboardPanFactor);
122 }
123
124 if (conf.keyboardZoomDelta) {
125 $("#keyboard-zoom-delta").val(conf.keyboardZoomDelta);
126 }
127
128 $("#input-flip-hor").prop('checked', conf.flipHor);
129
130 $("#input-flip-ver").prop('checked', conf.flipVer);
131}
132
133function initConfiguration(reset = false) {
134 if (reset || !currentConfiguration) {
135 currentConfiguration = Object.assign({}, initialConfiguration);
136 }
137 setControlsFromConfiguration(currentConfiguration);
138 slideLoader.mainViewport.setControlsConfiguration(currentConfiguration.controls);
139 slideLoader.mainViewport.setMouseWheelZoomMode(currentConfiguration.mouseWheelZoomMode);
140 slideLoader.mainViewport.setMouseWheelZoomDelta(currentConfiguration.mouseWheelZoomDelta);
141 slideLoader.setOption("theme", currentConfiguration.theme);
142 slideLoader.setOption("digitalZoomLevels", currentConfiguration.digitalZoomLevels);
143 slideLoader.setOption("keyboardPanFactor", currentConfiguration.keyboardPanFactor);
144 slideLoader.setOption("keyboardZoomDelta", currentConfiguration.keyboardZoomDelta);
145 slideLoader.mainViewport.setFlip($("#input-flip-hor").is(':checked'), $("#input-flip-ver").is(':checked'));
146
147 if (reset) {
148 slideLoader.load(serverUrl, imagePath);
149 }
150 console.log(currentConfiguration);
151}
152
153jQuery(function () {
154 console.log(`PMA.UI version: ${PMA.UI.getVersion()}`);
155
156 // Create a context
157 var context = new PMA.UI.Components.Context({ caller: caller });
158
159 // Add an autologin authentication provider
160 new PMA.UI.Authentication.AutoLogin(context, [{ serverUrl: serverUrl, username: serverUsername, password: serverPassword }]);
161
162 // Create an image loader that will allow us to load images easily
163 slideLoader = new PMA.UI.Components.SlideLoader(context, {
164 element: slideLoaderElementSelector,
165 theme: initialConfiguration.theme,
166 digitalZoomLevels: initialConfiguration.digitalZoomLevels,
167 });
168
169 // Listen for the slide loaded event by the slide loader
170 slideLoader.listen(PMA.UI.Components.Events.SlideLoaded, function (args) {
171 console.log("Slide loaded");
172 console.log(args);
173
174 $("#reset-btn").attr("disabled", false);
175 $("#controls").attr("disabled", false);
176
177 initConfiguration();
178 });
179
180 // Listen for the slide info error event by slide loader
181 slideLoader.listen(PMA.UI.Components.Events.SlideInfoError, function (args) {
182 console.log("Slide info error");
183 console.log(args);
184 });
185
186 // Load the image with the context
187 slideLoader.load(serverUrl, imagePath);
188
189 $("#controls").on("change", ".custom-switch", function (e) {
190 let id = e.target.id;
191
192 if (id == "mouse-wheel-mode") {
193 if (e.target.checked) {
194 currentConfiguration.mouseWheelZoomMode = PMA.UI.Types.MouseWheelZoomMode.objectives;
195 slideLoader.mainViewport.setMouseWheelZoomMode(PMA.UI.Types.MouseWheelZoomMode.objectives);
196 return;
197 }
198
199 currentConfiguration.mouseWheelZoomMode = PMA.UI.Types.MouseWheelZoomMode.normal;
200 slideLoader.mainViewport.setMouseWheelZoomMode(PMA.UI.Types.MouseWheelZoomMode.normal);
201 return;
202 }
203
204 let parts = id.split("-");
205 let c = currentConfiguration.controls.find(c => c.control == parts[0]);
206 if (!c) {
207 console.log("configuration not found");
208 return;
209 }
210
211 c[parts[1]] = e.target.checked;
212 slideLoader.mainViewport.setControlsConfiguration(currentConfiguration.controls);
213 });
214
215 $("#controls").on("change", ".theme-select", function (e) {
216 currentConfiguration.theme = e.target.value;
217 slideLoader.setOption("theme", e.target.value);
218 slideLoader.load(serverUrl, imagePath);
219 });
220
221 $("#controls").on("change", "#mouse-wheel-delta", function (e) {
222 currentConfiguration.mouseWheelZoomDelta = e.target.value;
223 slideLoader.mainViewport.setMouseWheelZoomDelta(e.target.value);
224 console.log("Mouse wheel delta:", e.target.value);
225 });
226
227 $("#controls").on("change", "#digital-zoom-levels", function (e) {
228 currentConfiguration.digitalZoomLevels = e.target.value;
229 slideLoader.setOption("digitalZoomLevels", e.target.value);
230 slideLoader.load(serverUrl, imagePath);
231 console.log("Digital zoom levels:", e.target.value);
232 });
233
234 $("#keyboard-pan-factor").on("change", function (e) {
235 currentConfiguration.keyboardPanFactor = e.target.value;
236 slideLoader.setOption("keyboardPanFactor", Number(e.target.value));
237 slideLoader.load(serverUrl, imagePath);
238 console.log("Keyboard pan factor:", slideLoader.getOption("keyboardPanFactor"));
239 });
240
241 $("#keyboard-zoom-delta").on("change", function (e) {
242 currentConfiguration.keyboardZoomDelta = e.target.value;
243 slideLoader.setOption("keyboardZoomDelta", Number(e.target.value));
244 slideLoader.load(serverUrl, imagePath);
245 console.log("Keyboard zoom delta:", slideLoader.getOption("keyboardZoomDelta"));
246 });
247
248 $("#input-flip-hor").on("change", function () {
249 currentConfiguration.flipHor = $("#input-flip-hor").is(':checked');
250 slideLoader.mainViewport.setFlip($("#input-flip-hor").is(':checked'), $("#input-flip-ver").is(':checked'));
251 console.log("Flipped horizontally:", slideLoader.mainViewport.getFlip().horizontally);
252 });
253
254 $("#input-flip-ver").on("change", function () {
255 currentConfiguration.flipVer = $("#input-flip-ver").is(':checked');
256 slideLoader.mainViewport.setFlip($("#input-flip-hor").is(':checked'), $("#input-flip-ver").is(':checked'));
257 console.log("Flipped vertically:", slideLoader.mainViewport.getFlip().vertically);
258 });
259
260 $("#reset-btn").on("click", function () {
261 initConfiguration(true);
262 console.log("Values reverted to initial");
263 });
264});