至于如何求取缩放后图片左上角的坐标值,在草稿纸上画来画去,画了很久......终于有点眉目。首先要找到一个缩放中心(这里做法是取双指的中点坐标,但是这个坐标必须要位于图片上,如果不在图片上,则取图片上离该中点坐标最近的点),然后存在下面这个等式
(缩放中心x坐标 - 缩放后图片左上角x坐标)/ 缩放后图片的宽度 = (缩放中心x坐标 - 缩放前图片左上角x坐标)/ 缩放前图片的宽度;(y坐标同理)
接下来看看下面这个例子(在visio找了很久都没有画坐标系的功能,所以只能手工画了)
绿色框是一张10*5的图片,蓝色框是宽高放大两倍后的图片20*10,根据上面的公式推算的x2 = sx - w2(sx - x1) / w1,y2 = sy - h2(sy - y1) / h1。
坚持...继续看看代码吧
_initEvent() { let $gesture = this.$refs.gesture, cClientRect = this.$refs.canvas.getBoundingClientRect(), scx = 0, //对于单手操作是移动的起点坐标,对于缩放是图片距离两手指的中点最近的图标。 scy = 0, fingers = {}; //记录当前有多少只手指在触控屏幕 //one finger let iX = this.imgX, iY = this.imgY; //two finger let figureDistance = 0, pinchScale = this.imgScale; $gesture.addEventListener('touchstart', e => { if (!this.imgLoaded) { return; } if (e.touches.length === 1) { let finger = e.touches[0]; scx = finger.pageX; scy = finger.pageY; iX = this.imgX; iY = this.imgY; fingers[finger.identifier] = finger; } else if (e.touches.length === 2) { let finger1 = e.touches[0], finger2 = e.touches[1], f1x = finger1.pageX - cClientRect.left, f1y = finger1.pageY - cClientRect.top, f2x = finger2.pageX - cClientRect.left, f2y = finger2.pageY - cClientRect.top; scx = parseInt((f1x + f2x) / 2); scy = parseInt((f1y + f2y) / 2); figureDistance = this._pointDistance(f1x, f1y, f2x, f2y); fingers[finger1.identifier] = finger1; fingers[finger2.identifier] = finger2; //判断变换中点是否在图片中,如果不是则去离图片最近的点 if (scx < this.imgX) { scx = this.imgX; } if (scx > this.imgX + this.imgCurrentWidth) { scx = this.imgX + this.imgCurrentHeight; } if (scy < this.imgY) { scy = this.imgY; } if (scy > this.imgY + this.imgCurrentHeight) { scy = this.imgY + this.imgCurrentHeight; } } }, false); $gesture.addEventListener('touchmove', e => { e.preventDefault(); if (!this.imgLoaded) { return; } this.maskShowTimer && clearTimeout(this.maskShowTimer); this.maskShow = false; if (e.touches.length === 1) { let f1x = e.touches[0].pageX, f1y = e.touches[0].pageY; this._drawImage(iX + f1x - scx, iY + f1y - scy, this.imgCurrentWidth, this.imgCurrentHeight); } else if (e.touches.length === 2) { let finger1 = e.touches[0], finger2 = e.touches[1], f1x = finger1.pageX - cClientRect.left, f1y = finger1.pageY - cClientRect.top, f2x = finger2.pageX - cClientRect.left, f2y = finger2.pageY - cClientRect.top, newFigureDistance = this._pointDistance(f1x, f1y, f2x, f2y), scale = this.imgScale + parseFloat(((newFigureDistance - figureDistance) / this.imgScaleStep).toFixed(1)); fingers[finger1.identifier] = finger1; fingers[finger2.identifier] = finger2; if (scale !== pinchScale) { //目前缩放的最小比例是1,最大是5 if (scale < this.imgMinScale) { scale = this.imgMinScale; } else if (scale > this.imgMaxScale) { scale = this.imgMaxScale; } pinchScale = scale; this._scale(scx, scy, scale); } } }, false); $gesture.addEventListener('touchend', e => { if (!this.imgLoaded) { return; } this.imgScale = pinchScale; //从finger删除已经离开的手指 let touches = Array.prototype.slice.call(e.changedTouches, 0); touches.forEach(item => { delete fingers[item.identifier]; }); //迭代fingers,如果存在finger则更新scx,scy,iX,iY,因为可能缩放后立即单指拖动 let i, fingerArr = []; for(i in fingers) { if (fingers.hasOwnProperty(i)) { fingerArr.push(fingers[i]); } } if (fingerArr.length > 0) { scx = fingerArr[0].pageX; scy = fingerArr[0].pageY; iX = this.imgX; iY = this.imgY; } else { this.maskShowTimer = setTimeout(() => { this.maskShow = true; }, 300); } //做边界值检测 let x = this.imgX, y = this.imgY, pClientRect = this.$refs.pCanvas.getBoundingClientRect(); if (x > pClientRect.left + pClientRect.width) { x = pClientRect.left } else if (x + this.imgCurrentWidth < pClientRect.left) { x = pClientRect.left + pClientRect.width - this.imgCurrentWidth; } if (y > pClientRect.top + pClientRect.height) { y = pClientRect.top; } else if (y + this.imgCurrentHeight < pClientRect.top) { y = pClientRect.top + pClientRect.height - this.imgCurrentHeight; } if (this.imgX !== x || this.imgY !== y) { this._drawImage(x, y, this.imgCurrentWidth, this.imgCurrentHeight); } }); }, _scale(x, y, scale) { let newPicWidth = parseInt(this.imgStartWidth * scale), newPicHeight = parseInt(this.imgStartHeight * scale), newIX = parseInt(x - newPicWidth * (x - this.imgX) / this.imgCurrentWidth), newIY = parseInt(y - newPicHeight * (y - this.imgY) / this.imgCurrentHeight); this._drawImage(newIX, newIY, newPicWidth, newPicHeight); }, _pointDistance(x1, y1, x2, y2) { return parseInt(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); }
内容版权声明:除非注明,否则皆为本站原创文章。