PMA.UI Examples 2.43.3by Pathomation

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 html>
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});