1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | import * as go from '../release/go-module.js';
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | export class ZoomSlider {
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | constructor(diagram, options) {
|
60 |
|
61 | this._size = 125;
|
62 | this._buttonSize = 25;
|
63 | this._alignment = go.Spot.BottomRight;
|
64 | this._alignmentFocus = go.Spot.BottomRight;
|
65 | this._orientation = 'vertical';
|
66 | this._opacity = .75;
|
67 | this._diagram = diagram;
|
68 | this._initialScale = diagram.scale;
|
69 | this._diagramDiv = diagram.div;
|
70 | this._sliderDiv = null;
|
71 |
|
72 | if (options !== undefined) {
|
73 | if (options.size !== undefined)
|
74 | this._size = options.size;
|
75 | if (options.buttonSize !== undefined)
|
76 | this._buttonSize = options.buttonSize;
|
77 | if (options.alignment !== undefined)
|
78 | this._alignment = options.alignment;
|
79 | if (options.alignmentFocus !== undefined)
|
80 | this._alignmentFocus = options.alignmentFocus;
|
81 | if (options.orientation !== undefined)
|
82 | this._orientation = options.orientation;
|
83 | if (options.opacity !== undefined)
|
84 | this._opacity = options.opacity;
|
85 | }
|
86 |
|
87 | const self = this;
|
88 | this.updateOnViewportBoundsChanged = (e) => { self.scaleToValue(); };
|
89 | this.init();
|
90 | }
|
91 | |
92 |
|
93 |
|
94 | get diagram() { return this._diagram; }
|
95 | |
96 |
|
97 |
|
98 |
|
99 | get size() { return this._size; }
|
100 | set size(val) {
|
101 | const old = this._size;
|
102 | if (old !== val) {
|
103 | this._size = val;
|
104 | this.resize();
|
105 | }
|
106 | }
|
107 | |
108 |
|
109 |
|
110 |
|
111 | get buttonSize() { return this._buttonSize; }
|
112 | set buttonSize(val) {
|
113 | const old = this._buttonSize;
|
114 | if (old !== val) {
|
115 | this._buttonSize = val;
|
116 | this.resize();
|
117 | }
|
118 | }
|
119 | |
120 |
|
121 |
|
122 |
|
123 | get alignment() { return this._alignment; }
|
124 | set alignment(val) {
|
125 | const old = this._alignment;
|
126 | if (old !== val) {
|
127 | this._alignment = val;
|
128 | this.realign();
|
129 | }
|
130 | }
|
131 | |
132 |
|
133 |
|
134 |
|
135 | get alignmentFocus() { return this._alignmentFocus; }
|
136 | set alignmentFocus(val) {
|
137 | const old = this._alignmentFocus;
|
138 | if (old !== val) {
|
139 | this._alignmentFocus = val;
|
140 | this.realign();
|
141 | }
|
142 | }
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 | get orientation() { return this._orientation; }
|
149 | set orientation(val) {
|
150 | if (val !== 'horizontal' && val !== 'vertical') {
|
151 | throw new Error('Orientation must be "horizontal" or "vertical"');
|
152 | }
|
153 | const old = this._orientation;
|
154 | if (old !== val) {
|
155 | this._orientation = val;
|
156 | this.resize(true);
|
157 | }
|
158 | }
|
159 | |
160 |
|
161 |
|
162 |
|
163 | get opacity() { return this._opacity; }
|
164 | set opacity(val) {
|
165 | const old = this._opacity;
|
166 | if (old !== val) {
|
167 | this._opacity = val;
|
168 | if (this._sliderDiv !== null) {
|
169 | this._sliderDiv.style.opacity = val.toString();
|
170 | }
|
171 | }
|
172 | }
|
173 | |
174 |
|
175 |
|
176 |
|
177 | init() {
|
178 |
|
179 | this.sliderDivSetup();
|
180 | this.resize(true);
|
181 |
|
182 | this.sliderListenerSetup();
|
183 | }
|
184 | |
185 |
|
186 |
|
187 |
|
188 | sliderDivSetup() {
|
189 | this._sliderDiv = document.createElement('div');
|
190 | this._sliderDiv.className = 'zoomSlider';
|
191 |
|
192 | const zoomOutBtn = document.createElement('button');
|
193 | zoomOutBtn.id = 'zoomSliderOut';
|
194 | zoomOutBtn.className = 'zoomButton';
|
195 | zoomOutBtn.innerHTML = '-';
|
196 | this._sliderDiv.appendChild(zoomOutBtn);
|
197 | const zoomRangeContainer = document.createElement('div');
|
198 | zoomRangeContainer.id = 'zoomSliderRangeCtn';
|
199 | zoomRangeContainer.className = 'zoomRangeContainer';
|
200 | this._sliderDiv.appendChild(zoomRangeContainer);
|
201 | const zoomRangeInput = document.createElement('input');
|
202 | zoomRangeInput.id = 'zoomSliderRange';
|
203 | zoomRangeInput.className = 'zoomRangeInput';
|
204 | zoomRangeInput.type = 'range';
|
205 | zoomRangeInput.min = '-50';
|
206 | zoomRangeInput.max = '100';
|
207 | zoomRangeContainer.appendChild(zoomRangeInput);
|
208 | const zoomInBtn = document.createElement('button');
|
209 | zoomInBtn.id = 'zoomSliderIn';
|
210 | zoomInBtn.className = 'zoomButton';
|
211 | zoomInBtn.innerHTML = '+';
|
212 | this._sliderDiv.appendChild(zoomInBtn);
|
213 |
|
214 |
|
215 | if (this._diagramDiv !== null) {
|
216 | const diagramParent = this._diagramDiv.parentElement;
|
217 | if (diagramParent !== null) {
|
218 | diagramParent.appendChild(this._sliderDiv);
|
219 | }
|
220 | }
|
221 | }
|
222 | |
223 |
|
224 |
|
225 |
|
226 |
|
227 | sliderListenerSetup() {
|
228 | const zoomOutBtn = document.getElementById('zoomSliderOut');
|
229 | const zoomInBtn = document.getElementById('zoomSliderIn');
|
230 | const zoomRangeInput = document.getElementById('zoomSliderRange');
|
231 | if (zoomOutBtn === null || zoomInBtn === null || zoomRangeInput === null)
|
232 | return;
|
233 |
|
234 | this.diagram.addDiagramListener('ViewportBoundsChanged', this.updateOnViewportBoundsChanged);
|
235 |
|
236 | const self = this;
|
237 | zoomOutBtn.onclick = function () {
|
238 | zoomRangeInput.stepDown();
|
239 | self.valueToScale();
|
240 | };
|
241 | zoomInBtn.onclick = function () {
|
242 | zoomRangeInput.stepUp();
|
243 | self.valueToScale();
|
244 | };
|
245 | const valChanged = function () {
|
246 | self.valueToScale();
|
247 | };
|
248 | zoomRangeInput.oninput = valChanged;
|
249 | zoomRangeInput.onchange = valChanged;
|
250 | }
|
251 | |
252 |
|
253 |
|
254 |
|
255 |
|
256 | resize(reorient) {
|
257 | let sliderWidth = 0;
|
258 | let sliderHeight = 0;
|
259 | const zoomOutBtn = document.getElementById('zoomSliderOut');
|
260 | const zoomInBtn = document.getElementById('zoomSliderIn');
|
261 | const zoomRangeContainer = document.getElementById('zoomSliderRangeCtn');
|
262 | const zoomRangeInput = document.getElementById('zoomSliderRange');
|
263 | if (this._sliderDiv === null || zoomOutBtn === null || zoomInBtn === null ||
|
264 | zoomRangeContainer === null || zoomRangeInput === null)
|
265 | return;
|
266 | if (this.orientation === 'horizontal') {
|
267 | sliderWidth = this.size;
|
268 | sliderHeight = this.buttonSize;
|
269 | const rangeWidth = sliderWidth - sliderHeight * 2;
|
270 | zoomOutBtn.style.width = sliderHeight + 'px';
|
271 | zoomOutBtn.style.height = sliderHeight + 'px';
|
272 | zoomRangeContainer.style.width = rangeWidth + 'px';
|
273 | zoomRangeContainer.style.height = sliderHeight + 'px';
|
274 | zoomRangeInput.style.width = rangeWidth + 'px';
|
275 | zoomRangeInput.style.height = sliderHeight + 'px';
|
276 | zoomRangeInput.style.transformOrigin = '';
|
277 | zoomInBtn.style.width = sliderHeight + 'px';
|
278 | zoomInBtn.style.height = sliderHeight + 'px';
|
279 | }
|
280 | else {
|
281 | sliderHeight = this.size;
|
282 | sliderWidth = this.buttonSize;
|
283 | const rangeHeight = sliderHeight - sliderWidth * 2;
|
284 | zoomInBtn.style.width = sliderWidth + 'px';
|
285 | zoomInBtn.style.height = sliderWidth + 'px';
|
286 | zoomRangeContainer.style.width = sliderWidth + 'px';
|
287 | zoomRangeContainer.style.height = rangeHeight + 'px';
|
288 | zoomRangeInput.style.width = rangeHeight + 'px';
|
289 | zoomRangeInput.style.height = sliderWidth + 'px';
|
290 | zoomRangeInput.style.transformOrigin = rangeHeight / 2 + 'px ' + rangeHeight / 2 + 'px';
|
291 | zoomOutBtn.style.width = sliderWidth + 'px';
|
292 | zoomOutBtn.style.height = sliderWidth + 'px';
|
293 | }
|
294 | this._sliderDiv.style.width = sliderWidth + 'px';
|
295 | this._sliderDiv.style.height = sliderHeight + 'px';
|
296 |
|
297 | if (reorient) {
|
298 | this.reorient();
|
299 | }
|
300 |
|
301 | this.realign();
|
302 | }
|
303 | |
304 |
|
305 |
|
306 |
|
307 | reorient() {
|
308 | const zoomOutBtn = document.getElementById('zoomSliderOut');
|
309 | const zoomInBtn = document.getElementById('zoomSliderIn');
|
310 | const zoomRangeInput = document.getElementById('zoomSliderRange');
|
311 | if (this._sliderDiv === null || zoomOutBtn === null || zoomInBtn === null || zoomRangeInput === null)
|
312 | return;
|
313 |
|
314 | if (this.orientation === 'horizontal') {
|
315 | zoomRangeInput.style.transform = '';
|
316 | this._sliderDiv.insertBefore(zoomOutBtn, this._sliderDiv.firstChild);
|
317 | this._sliderDiv.appendChild(zoomInBtn);
|
318 | }
|
319 | else {
|
320 | zoomRangeInput.style.transform = 'rotate(-90deg)';
|
321 | this._sliderDiv.insertBefore(zoomInBtn, this._sliderDiv.firstChild);
|
322 | this._sliderDiv.appendChild(zoomOutBtn);
|
323 | }
|
324 | }
|
325 | |
326 |
|
327 |
|
328 |
|
329 | realign() {
|
330 | if (this._diagramDiv === null || this._sliderDiv === null)
|
331 | return;
|
332 | let sliderWidth = 0;
|
333 | let sliderHeight = 0;
|
334 | if (this.orientation === 'horizontal') {
|
335 | sliderWidth = this.size;
|
336 | sliderHeight = this.buttonSize;
|
337 | }
|
338 | else {
|
339 | sliderHeight = this.size;
|
340 | sliderWidth = this.buttonSize;
|
341 | }
|
342 |
|
343 | const diagramParent = this._diagramDiv.parentElement;
|
344 | const diagramLoc = this._diagramDiv.getBoundingClientRect();
|
345 | if (diagramParent !== null) {
|
346 | const parentLoc = diagramParent.getBoundingClientRect();
|
347 | const top = diagramLoc.top - parentLoc.top +
|
348 | this.alignment.y * this._diagramDiv.clientHeight + this.alignment.offsetY -
|
349 | this.alignmentFocus.y * sliderHeight + this.alignmentFocus.offsetY;
|
350 | const left = diagramLoc.left - parentLoc.left +
|
351 | this.alignment.x * this._diagramDiv.clientWidth + this.alignment.offsetX -
|
352 | this.alignmentFocus.x * sliderWidth + this.alignmentFocus.offsetX;
|
353 | this._sliderDiv.style.top = top + 'px';
|
354 | this._sliderDiv.style.left = left + 'px';
|
355 | }
|
356 | }
|
357 | |
358 |
|
359 |
|
360 |
|
361 | scaleToValue() {
|
362 | const slider = document.getElementById('zoomSliderRange');
|
363 | const diagram = this.diagram;
|
364 | const A = this._initialScale;
|
365 | const B = diagram.commandHandler.zoomFactor;
|
366 | const y1 = diagram.scale;
|
367 | slider.value = Math.round(Math.log(y1 / A) / Math.log(B)).toString();
|
368 | }
|
369 | |
370 |
|
371 |
|
372 |
|
373 | valueToScale() {
|
374 | const slider = document.getElementById('zoomSliderRange');
|
375 | const diagram = this.diagram;
|
376 | const x = parseFloat(slider.value);
|
377 | const A = this._initialScale;
|
378 | const B = diagram.commandHandler.zoomFactor;
|
379 | diagram.scale = A * Math.pow(B, x);
|
380 | }
|
381 | |
382 |
|
383 |
|
384 | remove() {
|
385 |
|
386 | this.diagram.removeDiagramListener('ViewportBoundsChanged', this.updateOnViewportBoundsChanged);
|
387 | if (this._sliderDiv !== null) {
|
388 | this._sliderDiv.innerHTML = '';
|
389 | if (this._sliderDiv.parentElement) {
|
390 | this._sliderDiv.parentElement.removeChild(this._sliderDiv);
|
391 | }
|
392 | this._sliderDiv = null;
|
393 | }
|
394 | }
|
395 | }
|