PMA.UI Examples 2.43.3by Pathomation

Multiple Image Annotation

basicviewportannotations
Console
Multiple images parallel annotation
multiple_image_annotation.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    <script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous">
13    </script>
14
15    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
16    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
17    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
18
19    <!-- Include PMA.UI script & css -->
20    <script src="./pma.ui/pma.ui.js"></script>
21    <link href="./pma.ui/pma.ui.css" type="text/css" rel="stylesheet">
22
23    <!-- Include custom script & css -->
24    <script src="./js/multiple_image_annotation.js"></script>
25    <link href="./css/multiple_image_annotation.css" type="text/css" rel="stylesheet">
26
27    <title>Multiple Image Annotation</title>
28</head>
29
30<body>
31    <div id="annotations" class="slide">
32        <div class="btn-group btn-group-sm">
33            <button type="button" class="btn btn-default" data-action="draw" data-type="Freehand" title="Freehand">
34                <i class="fa fa-pencil"></i>
35            </button>
36            <button type="button" class="btn btn-default" data-action="draw" data-type="ClosedFreehand" title="Closed freehand">
37                <i class="fa fa-pencil-square"></i>
38            </button>
39        </div>
40        <div class="btn-group btn-group-sm" data-toggle="buttons">
41            <button type="button" class="btn btn-primary" data-action="deleteall" data-type title="Delete all">
42                <i class="fa fa-times-circle"></i>
43            </button>
44            <button type="button" class="btn btn-primary" data-action="save" data-type title="Save">
45                <i class="fa fa-save"></i>
46            </button>
47        </div>
48        <span class="annotation-helper-icon">
49            <i class="fa fa-spinner fa-spin"></i>
50            <span class="label label-success">
51                <i class="fa fa-check"></i> Saved</span>
52            <span class="label label-danger">
53                <i class="fa fa-times"></i> Error</span>
54        </span>
55    </div>
56    <div class="container">
57        <div id="viewer1" tabindex="0" class="column">
58        </div>
59        <div id="viewer2" tabindex="0" class="column">
60        </div>
61    </div>
62    <div class="container-menu">
63        <div id="viewer1Content" class="viewer-content">
64            <form class="dropdown">
65                <select id="pathsViewer1">
66                    <option value="cases2/fuhrmann/Assessment set/07250086C0001S.mrxs">07250086C0001S.mrxs</option>
67                    <option value="cases2/fuhrmann/Assessment set/07250133C0001S.mrxs">07250133C0001S.mrxs</option>
68                    <option value="cases2/fuhrmann/Assessment set/07250166C0001S.mrxs">07250166C0001S.mrxs</option>
69                </select>
70            </form>
71        </div>
72        <div id="viewer2Content" class="viewer-content">
73            <form class="dropdown">
74                <select id="pathsViewer2">
75                    <option value="cases2/fuhrmann/Assessment set/07250169C0001S.mrxs">07250169C0001S.mrxs</option>
76                    <option value="cases2/fuhrmann/Assessment set/07250174C0001S.mrxs">07250174C0001S.mrxs</option>
77                    <option value="cases2/fuhrmann/Assessment set/07250189C0001S.mrxs">07250189C0001S.mrxs</option>
78                </select>
79            </form>
80        </div>
81    </div>
82</body>
multiple_image_annotation.css
1html,
2body {
3    height: 100%;
4    overflow: hidden;
5    display: flex;
6    flex-direction: column;
7}
8
9#annotations {
10    padding: 10px 0 0 0;
11    text-align: center;
12}
13
14.container {
15    flex-grow: 1;
16    display: flex;
17    height: 100%;
18    width: 100%;
19}
20
21.container-menu {
22    flex-grow: 1;
23    display: flex;
24    width: 100%;
25}
26
27.column {
28    flex-grow: 1;
29    background-color: lightgray;
30    border: 1px gray solid;
31    border-radius: 5px;
32    margin: 10px 10px 0 10px;
33    display: flex;
34    flex-direction: column;
35    align-items: center;
36}
37
38.viewer-content {
39    flex-grow: 1;
40    width: 100%;
41}
42
43.dropdown {
44    width: 100%;
45    display: flex;
46    justify-content: center;
47    padding: 10px;
48}
49
50select {
51    width: 30%;
52    height: auto;
53}
54
55.annotation-helper-icon i,
56.annotation-helper-icon span {
57    display: none;
58}
59
60.annotation-helper-icon.loading i {
61    display: initial;
62}
63
64.annotation-helper-icon.loading span {
65    display: none;
66}
67
68.annotation-helper-icon.saved i,
69.annotation-helper-icon.saved span.label-danger {
70    display: none;
71}
72
73.annotation-helper-icon.saved span.label-success {
74    display: initial;
75}
76
77.annotation-helper-icon.error i,
78.annotation-helper-icon.error span.label-success {
79    display: none;
80}
multiple_image_annotation.js
1var serverUrl = "https://host.pathomation.com/pma.core.3/";
2var username = "zuidemo";
3var password = "zuidemo";
4var slideLoader1, slideLoader2;
5var annotationManager1, annotationManager2;
6
7function loadImage(slideLoader, imagePath) {
8    slideLoader.load(serverUrl, imagePath);
9}
10
11function initAnnotationToolbar() {
12    $("button[data-action][data-type], a[data-action][data-type]").on("click", function (e) {
13        const action = $(this).data("action");
14        const type = $(this).data("type");
15        if (annotationManager1) {
16            annotationManager1.finishDrawing(false);
17            annotationManager1.stopTool();
18            if (action === 'draw') {
19                annotationManager1.startDrawing({
20                    type: type,
21                    color: "#00ff00",
22                    lineThickness: 2,
23                });
24            }
25            else if (action === "deleteall") {
26                var allAnnotations = slideLoader1.mainViewport.getAnnotations();
27
28                for (var i = 0; i < allAnnotations.length; i++) {
29                    annotationManager1.deleteAnnotation(allAnnotations[i].getId());
30                }
31            }
32            else if (action === "save") {
33                $(".annotation-helper-icon").addClass("loading");
34                annotationManager1.saveAnnotations();
35                annotationManager1.listen(PMA.UI.Components.Events.AnnotationsSaved, function (e) {
36                    if (e && e.success) {
37                        $(".annotation-helper-icon").removeClass("loading").addClass("saved");
38                    } else {
39                        $(".annotation-helper-icon").removeClass("loading").addClass("error");
40                    }
41
42                    $("button[data-action=save][data-type]").removeClass("active");
43
44                    setTimeout(function () {
45                        $(".annotation-helper-icon").removeClass("loading error saved");
46                    }, 1000);
47                });
48            }
49        }
50
51        if (annotationManager2) {
52            annotationManager2.finishDrawing(false);
53            annotationManager2.stopTool();
54            if (action === 'draw') {
55                annotationManager2.startDrawing({
56                    type: type,
57                    color: "#00ff00",
58                    lineThickness: 2,
59                });
60            }
61            else if (action === "deleteall") {
62                var allAnnotations = slideLoader2.mainViewport.getAnnotations();
63
64                for (var i = 0; i < allAnnotations.length; i++) {
65                    annotationManager2.deleteAnnotation(allAnnotations[i].getId());
66                }
67            }
68            else if (action === "save") {
69                annotationManager2.saveAnnotations();
70                annotationManager2.listen(PMA.UI.Components.Events.AnnotationsSaved, function (e) {
71                    if (e && e.success) {
72                        $(".annotation-helper-icon").removeClass("loading").addClass("saved");
73                    } else {
74                        $(".annotation-helper-icon").removeClass("loading").addClass("error");
75                    }
76
77                    $("button[data-action=save][data-type]").removeClass("active");
78
79                    setTimeout(function () {
80                        $(".annotation-helper-icon").removeClass("loading error saved");
81                    }, 1000);
82                });
83            }
84        }
85    });
86}
87
88$(document).ready(function () {
89    var context = new PMA.UI.Components.Context({
90        caller: "public demo",
91    });
92
93    new PMA.UI.Authentication.AutoLogin(context, [
94        { serverUrl: serverUrl, username: username, password: password },
95    ]);
96
97    var options1 = {
98        element: "#viewer1",
99        annotations: true,
100    };
101
102    slideLoader1 = new PMA.UI.Components.SlideLoader(context, options1);
103    slideLoader1.listen(
104        PMA.UI.Components.Events.SlideLoaded,
105        function (args) {
106            annotationManager1 = new PMA.UI.Components.Annotations({
107                context: context,
108                element: null,
109                viewport: slideLoader1.mainViewport,
110                serverUrl: args.serverUrl,
111                path: args.path,
112                enabled: true,
113            });
114        });
115
116    $("#pathsViewer1").change(function () {
117        loadImage(slideLoader1, $(this).val());
118    });
119
120    loadImage(slideLoader1, $("#pathsViewer1").val());
121
122    var options2 = {
123        element: "#viewer2",
124        annotations: true,
125    };
126
127    slideLoader2 = new PMA.UI.Components.SlideLoader(context, options2);
128    slideLoader2.listen(
129        PMA.UI.Components.Events.SlideLoaded,
130        function (args) {
131            annotationManager2 = new PMA.UI.Components.Annotations({
132                context: context,
133                element: null,
134                viewport: slideLoader2.mainViewport,
135                serverUrl: args.serverUrl,
136                path: args.path,
137                enabled: true,
138            });
139        });
140
141    $("#pathsViewer2").change(function () {
142        loadImage(slideLoader2, $(this).val());
143    });
144
145    loadImage(slideLoader2, $("#pathsViewer2").val());
146    initAnnotationToolbar();
147});