PageSourceSearch

https://maritiemdigitaal.nl/_content/DDigit.CollectionComponents/js/crop-box.hkje6vnovq.js

js maritiemdigitaal.nl collected 2026-09-24 20:39:58 UTC 6,420 bytes, 204 lines download raw bytes

1{
2  class CropBox {
3    constructor(id, netObjectReference) {
4      this.id = id;
5      this.netObject = netObjectReference;
6      const container = document.getElementById(id);
7      this.container = container; // OpenSeadragon container
8
9      this.startX = 0;
10      this.startY = 0;
11
12      this.initialize_overlay();
13    }
14
15    initialize_overlay() {
16      const overlay = document.createElement('canvas');
17      overlay.classList.add('cropbox-overlay');
18      overlay.style.position = 'absolute';
19      overlay.style.top = '0';
20      overlay.style.left = '0';
21      overlay.style.width = '100%';
22      overlay.style.height = '100%';
23      overlay.style.cursor = 'crosshair';
24      overlay.style.pointerEvents = 'auto';
25
26      overlay.addEventListener('pointerdown', pointer_down);
27      overlay.addEventListener('pointermove', pointer_move);
28      overlay.addEventListener('pointerup', pointer_up);
29      overlay.addEventListener('pointercancel', cancel_cropbox);
30
31      this.container.appendChild(overlay);
32      requestAnimationFrame(() => {
33        overlay.classList.add('visible');
34      });
35
36      const rect = this.container.getBoundingClientRect();
37      overlay.width = rect.width;
38      overlay.height = rect.height;
39
40      this.overlay = overlay;
41      this.context = overlay.getContext('2d');
42
43      // Draw styling
44      this.context.fillStyle = 'rgba(0, 0, 0, 0.4)';
45      this.context.strokeStyle = 'rgba(215, 215, 215, 0.5)';
46
47      // Fill overlay
48      this.context.fillRect(0, 0, overlay.width, overlay.height);
49    }
50
51    remove_overlay() {
52      if (this.overlay) {
53        this.overlay.removeEventListener('pointerdown', pointer_down);
54        this.overlay.removeEventListener('pointermove', pointer_move);
55        this.overlay.removeEventListener('pointerup', pointer_up);
56        this.overlay.removeEventListener('pointercancel', cancel_cropbox);
57
58        this.overlay.classList.remove('visible');
59
60        setTimeout(() => {
61          this.container.removeChild(this.overlay);
62          this.overlay = null;
63          this.isDragging = false;
64        }, 250);
65      }
66    }
67
68
69    pointer_down(x, y) {
70      if (this.overlay) {
71        const rect = this.container.getBoundingClientRect();
72        this.startX = x - rect.left;
73        this.startY = y - rect.top;
74
75        this.isDragging = true;
76      }
77    }
78
79    pointer_move(x, y) {
80      if (this.isDragging) {
81        const rect = this.overlay.getBoundingClientRect();
82        const currentX = x - rect.left;
83        const currentY = y - rect.top;
84
85        this.boxX = Math.min(this.startX, currentX);
86        this.boxY = Math.min(this.startY, currentY);
87        this.boxWidth = Math.abs(currentX - this.startX);
88        this.boxHeight = Math.abs(currentY - this.startY);
89
90        this.context.clearRect(0, 0, rect.width, rect.height);
91        this.context.fillRect(0, 0, rect.width, rect.height);
92
93        this.context.clearRect(this.boxX, this.boxY, this.boxWidth, this.boxHeight);
94        this.context.strokeRect(this.boxX, this.boxY, this.boxWidth, this.boxHeight);
95      }
96    }
97
98    pointer_up() {
99      if (this.isDragging) {
100        this.isDragging = false;
101
102        const viewer = OpenSeadragon.getViewer(this.id);
103        if (viewer) {
104          const endX = this.boxX + this.boxWidth;
105          const endY = this.boxY + this.boxHeight;
106
107          // Directly use client coordinates and convert via OSD
108          const start = viewer.viewport.pointFromPixel(new OpenSeadragon.Point(this.boxX, this.boxY));
109          const end = viewer.viewport.pointFromPixel(new OpenSeadragon.Point(endX, endY));
110
111          const imageStart = viewer.viewport.viewportToImageCoordinates(start);
112          const imageEnd = viewer.viewport.viewportToImageCoordinates(end);
113
114          const imageX = Math.min(imageStart.x, imageEnd.x);
115          const imageY = Math.min(imageStart.y, imageEnd.y);
116          const imageW = Math.abs(imageEnd.x - imageStart.x);
117          const imageH = Math.abs(imageEnd.y - imageStart.y);
118
119          const tiledImage = viewer.world.getItemAt(0);
120          const imageSize = tiledImage.getContentSize();
121
122          const clamp = (v) => Math.max(0, Math.min(100, v));
123
124          const leftPercent = clamp(Math.round((imageX / imageSize.x) * 100));
125          const topPercent = clamp(Math.round((imageY / imageSize.y) * 100));
126          const widthPercent = clamp(Math.round((imageW / imageSize.x) * 100));
127          const heightPercent = clamp(Math.round((imageH / imageSize.y) * 100));
128
129          this.remove_overlay();
130
131          if (this.netObject && widthPercent > 0 && heightPercent > 0) {
132            this.netObject.invokeMethodAsync(
133              'FinishCrop',
134              leftPercent,
135              topPercent,
136              widthPercent,
137              heightPercent
138            );
139          }
140        }
141      }
142    }
143  }
144
145  window.InitializeCropBox = function (obj_ref, id) {
146    cancel_cropbox();
147
148    cropbox = new CropBox(id, obj_ref);
149    cropbox.container.addEventListener('keydown', key_down);
150    window.addEventListener('pointerdown', cancel_cropbox);
151  }
152
153  function cancel_cropbox() {
154    if (cropbox) {
155      cropbox.remove_overlay();
156      cropbox.container.removeEventListener('keydown', key_down);
157
158      window.removeEventListener('pointerdown', cancel_cropbox);
159      cropbox = null;
160    }
161  }
162
163  function pointer_down(event) {
164    event.stopPropagation();
165
166    if (event.pointerType === 'touch' || event.pointerType === 'mouse' || event.pointerType === 'pen') {
167      cropbox.overlay.setPointerCapture(event.pointerId);
168      cropbox.pointer_down(event.clientX, event.clientY);
169    }
170  }
171
172  function pointer_move(event) {
173    if (!cropbox || !cropbox.isDragging) {
174      return;
175    }
176
177    event.stopPropagation();
178    cropbox.pointer_move(event.clientX, event.clientY);
179  }
180
181  function pointer_up(event) {
182    if (!cropbox) {
183      return;
184    }
185
186    event.stopPropagation();
187
188    if (cropbox.overlay) {
189      try {
190        cropbox.overlay.releasePointerCapture(event.pointerId);
191      }
192      catch { /* ignore if not captured */ }
193    }
194    cropbox.pointer_up();
195  }
196
197  function key_down(event) {
198    if (event.key === "Escape") {
199      cancel_cropbox();
200    }
201  }
202
203  var cropbox;
204}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.