| | |
| | | closeMessage: 'Closed Gallery', |
| | | } |
| | | ); |
| | | this.modal.subscribe((event, data) => { |
| | | this.modal.subscribe((event) => { |
| | | if (event === 'modal-close') { |
| | | this.toggleGallery(false); |
| | | } |
| | |
| | | this.handleZoom(increment, e.clientX, e.clientY); |
| | | } |
| | | |
| | | clampPan() { |
| | | const BORDER = 32; // 2rem |
| | | const wrap = this.ui.gallery.wrap; |
| | | if (!wrap) return; |
| | | |
| | | const wrapRect = wrap.getBoundingClientRect(); |
| | | |
| | | // MUST use natural dimensions |
| | | const naturalW = 1920; |
| | | const naturalH = 1920; |
| | | |
| | | // But they must be constrained by how the CSS fits them (max-width: 90vw, max-height: 85vh) |
| | | // So compute the base display size: |
| | | const displayRatio = Math.min( |
| | | wrapRect.width / naturalW, |
| | | wrapRect.height / naturalH |
| | | ); |
| | | |
| | | const baseWidth = naturalW * displayRatio; |
| | | const baseHeight = naturalH * displayRatio; |
| | | |
| | | const scaledWidth = baseWidth * this.zoom.scale; |
| | | const scaledHeight = baseHeight * this.zoom.scale; |
| | | |
| | | // Allowed pan range |
| | | const minX = wrapRect.width - scaledWidth - BORDER; |
| | | const maxX = BORDER; |
| | | |
| | | const minY = wrapRect.height - scaledHeight - BORDER; |
| | | const maxY = BORDER; |
| | | |
| | | // clamp |
| | | this.zoom.x = Math.min(maxX, Math.max(minX, this.zoom.x)); |
| | | this.zoom.y = Math.min(maxY, Math.max(minY, this.zoom.y)); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | handleZoom(increment, clientX=null, clientY=null) { |
| | | const oldScale = this.zoom.scale; |
| | | let newScale = oldScale + increment; |
| | |
| | | /** |
| | | * |
| | | * @param {boolean} open |
| | | * @param {null|number} index |
| | | */ |
| | | toggleGallery(open, index= null) { |
| | | toggleGallery(open) { |
| | | if (open) { |
| | | // Disable native image dragging |
| | | this.ui.gallery.image.draggable = false; |