1import{DialogCloseEvent}from"@theme/dialog";import{clamp,preventDefault,isMobileBreakpoint}from"@theme/utilities";import{Component}from"@theme/component";const MIN_ZOOM=1,MAX_ZOOM=5,DEFAULT_ZOOM=1.5,DOUBLE_TAP_DELAY=300,DOUBLE_TAP_DISTANCE=50,DRAG_THRESHOLD=10;export class DragZoomWrapper extends Component{requiredRefs=["image"];#controller=new AbortController;#scale=DEFAULT_ZOOM;#initialDistance=0;#startScale=DEFAULT_ZOOM;#translate={x:0,y:0};#startPosition={x:0,y:0};#startTranslate={x:0,y:0};#isDragging=!1;#initialized=!1;#animationFrame=null;#lastTapTime=0;#lastTapPosition=null;#hasDraggedBeyondThreshold=!1;#hasManualZoom=!1;get#image(){return this.refs.image}connectedCallback(){super.connectedCallback(),this.#image&&(this.#initResizeListener(),window.addEventListener(DialogCloseEvent.eventName,this.#resetZoom),isMobileBreakpoint()&&(this.#initEventListeners(),this.#updateTransform()))}#initResizeListener(){this.#resizeObserver.observe(this)}#initEventListeners(){if(this.#initialized)return;this.#initialized=!0;const{signal}=this.#controller,options={passive:!1,signal};this.addEventListener("touchstart",this.#handleTouchStart,options),this.addEventListener("touchmove",this.#handleTouchMove,options),this.addEventListener("touchend",this.#handleTouchEnd,options),this.#updateTransform()}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener(DialogCloseEvent.eventName,this.#resetZoom),this.#controller.abort(),this.#resizeObserver.disconnect(),this.#cancelAnimationFrame()}#handleResize=()=>{!this.#initialized&&isMobileBreakpoint()&&this.#initEventListeners(),this.#initialized&&this.#requestUpdateTransform()};#resizeObserver=new ResizeObserver(this.#handleResize);#handleTouchStart=event=>{preventDefault(event);const touchCount=event.touches.length;if(touchCount===2){const touch1=event.touches[0],touch2=event.touches[1];if(!touch1||!touch2)return;this.#startZoomGestureFromTouches(touch1,touch2)}else if(touchCount===1){const touch=event.touches[0];if(!touch)return;const currentTime=performance.now();if(currentTime-this.#lastTapTime>=DOUBLE_TAP_DELAY){this.#storeTapInfo(currentTime,touch),this.#startDragGestureFromTouch(touch);return}if(this.#lastTapPosition&&getDistance(touch,this.#lastTapPosition)<DOUBLE_TAP_DISTANCE){this.#handleDoubleTapFromTouch(touch),this.#lastTapTime=0,this.#lastTapPosition=null;return}this.#storeTapInfo(currentTime,touch),this.#startDragGestureFromTouch(touch)}};#startZoomGestureFromTouches(touch1,touch2){this.#initialDistance=getDistance(touch1,touch2),this.#startScale=this.#scale,this.#isDragging=!1}#startDragGestureFromTouch(touch){this.#startPosition={x:touch.clientX,y:touch.clientY},this.#startTranslate={x:this.#translate.x,y:this.#translate.y},this.#isDragging=!0,this.#hasDraggedBeyondThreshold=!1}#storeTapInfo(currentTime,touch){this.#lastTapTime=currentTime,this.#lastTapPosition={x:touch.clientX,y:touch.clientY}}#handleDoubleTapFromTouch(touch){const containerCenter={x:this.clientWidth/2,y:this.clientHeight/2};let targetZoom;if(this.#hasManualZoom?(targetZoom=MIN_ZOOM,this.#hasManualZoom=!1,this.#translate={x:0,y:0}):Math.abs(this.#scale-MIN_ZOOM)<.05?targetZoom=DEFAULT_ZOOM:targetZoom=MIN_ZOOM,targetZoom!==MIN_ZOOM){const oldScale=this.#scale;this.#scale=Math.min(MAX_ZOOM,targetZoom);const distanceFromCenter={x:touch.clientX-containerCenter.x,y:touch.clientY-containerCenter.y},scaleDelta=this.#scale/oldScale-1;this.#translate.x-=distanceFromCenter.x*scaleDelta/this.#scale,this.#translate.y-=distanceFromCenter.y*scaleDelta/this.#scale}else this.#scale=targetZoom,this.#translate={x:0,y:0};this.#requestUpdateTransform()}#handleTouchMove=event=>{preventDefault(event);const touchCount=event.touches.length;if(touchCount===2){const touch1=event.touches[0],touch2=event.touches[1];touch1&&touch2&&this.#processZoomGesture(touch1,touch2)}else if(touchCount===1&&this.#isDragging){const touch=event.touches[0];touch&&this.#processDragGesture(touch)}};#processZoomGesture(touch1,touch2){const midX=(touch1.clientX+touch2.clientX)/2,midY=(touch1.clientY+touch2.clientY)/2,currentDistance=getDistance(touch1,touch2),oldScale=this.#scale,newScale=currentDistance/this.#initialDistance*this.#startScale;this.#scale=clamp(newScale,MIN_ZOOM,MAX_ZOOM),this.#hasManualZoom=!0;const containerCenterX=this.clientWidth/2,containerCenterY=this.clientHeight/2,distanceFromCenterX=midX-containerCenterX,distanceFromCenterY=midY-containerCenterY,scaleDelta=this.#scale/oldScale-1;this.#translate.x-=distanceFromCenterX*scaleDelta/this.#scale,this.#translate.y-=distanceFromCenterY*scaleDelta/this.#scale,this.#requestUpdateTransform(),this.#isDragging=!1}#processDragGesture(touch){const distance=getDistance(touch,this.#startPosition);if(!this.#hasDraggedBeyondThreshold&&distance<DRAG_THRESHOLD)return;this.#hasDraggedBeyondThreshold=!0;const dx=touch.clientX-this.#startPosition.x,dy=touch.clientY-this.#startPosition.y;this.#translate.x=this.#startTranslate.x+dx/this.#scale,this.#translate.y=this.#startTranslate.y+dy/this.#scale,this.#requestUpdateTransform()}#handleTouchEnd=event=>{event.touches.length===0&&(this.#isDragging=!1,this.#requestUpdateTransform(),this.#hasDraggedBeyondThreshold=!1)};#constrainTranslation(){const containerWidth=this.clientWidth,containerHeight=this.clientHeight;if(!containerWidth||!containerHeight||!this.#image)return;if(this.#scale=clamp(this.#scale,MIN_ZOOM,MAX_ZOOM),this.#scale<=MIN_ZOOM){this.#translate.x=0,this.#translate.y=0;return}const wrapperRect=this.getBoundingClientRect(),imageElement=this.#image;
1let naturalWidth,naturalHeight;imageElement.naturalWidth>0&&imageElement.naturalHeight>0?(naturalWidth=imageElement.naturalWidth,naturalHeight=imageElement.naturalHeight):(naturalWidth=wrapperRect.width,naturalHeight=wrapperRect.width);const imageAspectRatio=naturalWidth/naturalHeight,wrapperAspectRatio=wrapperRect.width/wrapperRect.height;let actualImageWidth,actualImageHeight;imageAspectRatio>wrapperAspectRatio?(actualImageWidth=wrapperRect.width,actualImageHeight=actualImageWidth/imageAspectRatio):(actualImageHeight=wrapperRect.height,actualImageWidth=actualImageHeight*imageAspectRatio);const scaledImageWidth=actualImageWidth*this.#scale,scaledImageHeight=actualImageHeight*this.#scale,horizontalOverflow=Math.max(0,scaledImageWidth-wrapperRect.width),verticalOverflow=Math.max(0,scaledImageHeight-wrapperRect.height),maxTranslateX=horizontalOverflow/2/this.#scale,maxTranslateY=verticalOverflow/2/this.#scale;this.#translate.x=clamp(this.#translate.x,-maxTranslateX,maxTranslateX),this.#translate.y=clamp(this.#translate.y,-maxTranslateY,maxTranslateY),this.style.setProperty("--drag-zoom-scale",this.#scale.toString()),this.style.setProperty("--drag-zoom-translate-x",`${this.#translate.x}px`),this.style.setProperty("--drag-zoom-translate-y",`${this.#translate.y}px`)}#requestUpdateTransform=()=>{this.#animationFrame||(this.#animationFrame=requestAnimationFrame(this.#updateTransform))};#cancelAnimationFrame(){this.#animationFrame&&(cancelAnimationFrame(this.#animationFrame),this.#animationFrame=null)}#updateTransform=()=>{this.#animationFrame=null,this.#constrainTranslation(),this.style.setProperty("--drag-zoom-scale",this.#scale.toString()),this.style.setProperty("--drag-zoom-translate-x",`${this.#translate.x}px`),this.style.setProperty("--drag-zoom-translate-y",`${this.#translate.y}px`)};#resetZoom=()=>{this.#scale=DEFAULT_ZOOM,this.#startScale=DEFAULT_ZOOM,this.#translate.x=0,this.#translate.y=0,this.#startPosition={x:0,y:0},this.#startTranslate={x:0,y:0},this.#isDragging=!1,this.#lastTapTime=0,this.#lastTapPosition=null,this.#hasDraggedBeyondThreshold=!1,this.style.setProperty("--drag-zoom-scale",DEFAULT_ZOOM.toString()),this.style.setProperty("--drag-zoom-translate-x","0px"),this.style.setProperty("--drag-zoom-translate-y","0px")};destroy(){this.#controller.abort(),this.#cancelAnimationFrame()}}function getDistance(point1,point2){const x1=point1.x??point1.clientX,y1=point1.y??point1.clientY,x2=point2.x??point2.clientX,y2=point2.y??point2.clientY,dx=x1-x2,dy=y1-y2;return Math.sqrt(dx*dx+dy*dy)}customElements.get("drag-zoom-wrapper")||customElements.define("drag-zoom-wrapper",DragZoomWrapper); 2//# sourceMappingURL=/cdn/shop/t/140/assets/drag-zoom-wrapper.js.map?v=49654226587051563631788956619
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.