鼠标与触屏环境下捏合缩放+拖拽功能的缩放原点异常问题求助
鼠标与触屏环境下捏合缩放+拖拽功能的缩放原点异常问题求助
大家好,我现在在做一个触屏显示器上的图片交互功能:希望能实现放大图片局部、拖拽移动、并从拖拽结束点缩小的效果。我用了GSAP库来做拖拽和缩放,配合Hammer.js处理触屏事件。
目前基础功能已经跑通了,但遇到一个问题:如果我先放大图片,然后拖拽到图片的另一端,再缩小的时候,图片不会以我当前鼠标/触摸的位置为原点缩放。但如果在同一个位置反复缩放,效果是完全正常的。我怀疑是transform-origin和translate3D()的冲突导致的,但不确定是不是漏了什么明显的细节。
有没有大佬能帮忙看看问题出在哪,或者给点建议?
复现提示:需要引入GSAP主库,以及Draggable和Observer插件。
HTML代码
<img src="https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg?t=st=1736502806~exp=1736506406~hmac=55191bc567a6b56fa91081c238a86595d5a85ff785179070a8deb52b1ba05041&w=1380" class="zoom-item">
CSS代码
body { display: flex; justify-content: center; align-items: center; overflow: hidden; } .box { width: 300px; height: 300px; background: red; }
JavaScript代码
let image = document.querySelector(".zoom-item"), hammer = new Hammer(image), mousePosArr = [], pinchPosArr = []; hammer.get("pinch").set({ enable: true }); hammer.on("pinchstart", (e) => { let pinchX = e.srcEvent.offsetX, pinchY = e.srcEvent.offsetY; pinchPosArr.push(pinchX, pinchY); zoomDrag[0].disable(); }); hammer.on("pinch", (e) => { console.log(pinchPosArr); let roundedX = Math.ceil(pinchPosArr[0]), roundedY = Math.ceil(pinchPosArr[1]); switch (e.additionalEvent) { case "pinchout": //round the numbers to nearest whole one zoom_control("+=0.03", roundedX, roundedY); break; case "pinchin": if (gsap.getProperty(e.target, "scale") >= 1.2) { zoom_control("-=0.03", roundedX, roundedY); } break; } }); hammer.on("pinchend", () => { pinchPosArr = []; zoomDrag[0].enable(); }); let zoomObserver = Observer.create({ target: ".zoom-item", type: "wheel", // Will only fire on the wheel scroll ease: "linear", // makes the animations more slower wheelSpeed: 0.1, // Changed how fast the zoom in happens onUp: (self) => { mousePosArr = []; let mouseX = self.event.offsetX, mouseY = self.event.offsetY; mousePosArr.push(mouseX, mouseY); // Creates an array and pushes each instance of mouseX and mouseY into the array const [posA, posB] = mousePosArr.slice(-2); // slice() helps me grab the last two added items into the array //using the posA and posB means that it zoom into wherever my mouse currently is console.log(image.style.scale); zoom_control("+=0.3", posA, posB); }, onDown: (self) => { // Will only fire if the scale is above the 1.2 if (gsap.getProperty(self.target, "scale") >= 1.2) { zoom_control("-=0.3", mousePosArr[0], mousePosArr[1]); } } }), zoomDrag = Draggable.create(".zoom-item", { zIndexBoost: false, // zIndexBoost set to false to stop it creasing on each click onDrag: () => { zoomObserver.disable(); }, onDragEnd: () => { zoomObserver.enable(); } }); function zoom_control(scaleNum, transformX, transformY) { gsap.set(image, { transformOrigin: `${transformX}px ${transformY}px` }); let scaleSetter = gsap.quickSetter(image, "css"); scaleSetter({ scale: scaleNum }); }
备注:内容来源于stack exchange,提问作者WesCritch
相关产品推荐
相关产品推荐

