const container = Z.by_id('container'); function getRandomColor() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; } for (let i = 0; i < 10000; ++i) { container.appendChild(Z.native('div', { innerText: i, className: 'image', style: { background: getRandomColor(), aspectRatio: '1 / ' + (Math.random() + 0.5), }, })); } const zoom = new (class { constructor() { this.committed = 5; container.style.gridTemplateColumns = `repeat(5, 1fr)`; container.classList.toggle('tiling', this.committed != 1); this.por = { x: 0, y: 0 }; this.eor = null; this.y_offset = 0; this.distance = 0; } update(distance, point) { const scale = distance / this.distance; const x = point.x - this.por.x; container.style.transform = `translate(${x}px, 0px) scale(${scale})`; } set reference({ point, distance }) { const rect = container.getClientRects()[0]; this.por = { x: point.x, y: point.y - rect.y }; container.style.transformOrigin = `${this.por.x}px ${this.por.y}px`; this.eor = Z.document.shadowRoot.elementFromPoint(point.x, point.y); const box_rect = this.eor.getBoundingClientRect(); this.y_offset = box_rect.y; this.distance = distance; } commit(distance) { const scale = distance / this.distance; this.committed = Math.round(Math.min(Math.max(this.committed / scale, 1), 20)); container.style.gridTemplateColumns = `repeat(${this.committed}, 1fr)`; container.classList.toggle('tiling', this.committed != 1); container.style.transform = 'scale(1)'; const rect = this.eor.getBoundingClientRect(); Z.document.scrollBy({ top: rect.y - this.y_offset, behavior: 'instant', }); } increase_line_by(n) { this.committed = Math.min(Math.max(this.committed + n, 1), 20); container.style.gridTemplateColumns = `repeat(${this.committed}, 1fr)`; container.classList.toggle('tiling', this.committed != 1); container.style.transform = 'scale(1)'; } }); Z.document.onwheel = (event) => { if (!event.ctrlKey) { return; } event.preventDefault(); zoom.increase_line_by(event.wheelDeltaY / 120); }; const pinch = new Pinch(Z.document); pinch.onstart = (event) => { zoom.reference = event; }; pinch.onpinch = (event) => { zoom.update(event.distance, event.point); }; pinch.onfinish = (event) => { zoom.commit(event.distance); };