最近在做一个固定比例的框,去放大缩小图片,让用户去裁切图片的过程。
2018-03-29 目前的状态是画出了模型,并且可以在ios上实现放大缩小,使用gesturechange手势事件,但是安卓机不兼容,所以在找合适的解决方案中。
2018-03-30 尝试了寻找办法,就从最基础的事件找起,touch事件,于是乎,我就打印出关于touch事件的属性,经过试验,还有网上的资料,touch有一个touches属性,这个是用来记录屏幕的触点个数的,这个东西很关键,为我后来进行“手势缩放”提供了思路。“一根手指,用来移动图片;两根手指才可以进行缩放”。
touches是一个数组,每一个值都带有clientX,clientY属性值,通过这个我们就可以在屏幕或者画布中获取到对应的坐标位置了。
对于,放大缩小的比例计算:
step1:使用touchstart事件,分别获取到两个手指在屏幕中的坐标位置,记录在屏幕中两个手指的clientX1和clientX2位置,记为D1。
step2:使用touchmove事件,记录每一次在屏幕中两个手指的clientX1和clientX2位置,取到他们的绝对值,即距离,记为D2。
step3:获取到每一次的缩放比例scale = D1/D2,由于需要做边界控制,我将这个scale范围限定为0.5 <= scale <=2,对于屏幕的缩放应该足够。
接下去,就是代码部分,后期会实现优化。
2018-04-02
touchstart(e) {
e.preventDefault();
if(e.touches.length == 1){
this.singleStartY0 = e.touches[0].clientY;
this.singleStartX0 = e.touches[0].clientX;
}
if(e.touches.length == 2){
this.startClientX1 = e.touches[0].clientX ;
this.startClientX2 = e.touches[1].clientX ;
}
},
touchmove(e) {
e.preventDefault();
let zoom ;
let _this = this;
let t = null;
if(e.touches.length == 1){
let a = 0,b = 0;
this.singleMoveX0 = e.touches[0].clientX;
this.singleMoveY0 = e.touches[0].clientY;
this.singleMoveInstanceX = (this.singleMoveX0 - this.singleStartX0) ;
this.singleMoveInstanceY = (this.singleMoveY0 - this.singleStartY0) ;
console.log(this.singleMoveInstanceX,this.singleMoveInstanceY)
}
if(e.touches.length == 2){
this.moveClientX1 = e.touches[0].clientX;
this.moveClientX2 = e.touches[1].clientX;
zoom=Math.abs(this.moveClientX2-this.moveClientX1)/Math.abs(this.startClientX2-this.startClientX1).toFixed(2);
if(zoom > 2){
this.touchScale = 1.8;
}else if(zoom < 0.5){
this.touchScale = 0.5;
}else{
this.touchScale = zoom;
}
}
t = setTimeout(function(){
_this.gesturechange(_this.touchScale);
clearTimeout(t);
},300);
},
gesturechange(){
let img = new Image();
img.src = this.imgSrc;
let singleMoveInstanceX = this.singleMoveInstanceX ,singleMoveInstanceY = this.singleMoveInstanceY;
let scale = this.touchScale;
// 图片
let shade=document.getElementById('shade');
let imgContext=shade.getContext("2d");
// 遮罩层
let mask=document.getElementById('masker');
let maskContext=mask.getContext("2d");
let htmlBodyWidth = document.body.clientWidth;
let htmlBodyHeight = document.body.clientHeight;
this.canvasWidth = htmlBodyWidth + 'px';
this.canvasHeight = htmlBodyHeight + 'px';
img.οnlοad=function(){
imgContext.clearRect(0,0,htmlBodyWidth,htmlBodyHeight);
maskContext.clearRect(0,0,htmlBodyWidth,htmlBodyHeight);
imgContext.drawImage(img,singleMoveInstanceX,singleMoveInstanceY,htmlBodyWidth*scale ,(htmlBodyWidth/img.width)*(img.height)*scale);
//遮罩层
maskContext.fillStyle = 'rgba(0, 0, 0, 0.5)';
maskContext.fillRect(0,0,htmlBodyWidth,htmlBodyHeight);
//露空部分
maskContext.clearRect(0,htmlBodyHeight*0.5 -htmlBodyWidth*0.5 ,htmlBodyWidth,htmlBodyWidth);
}
}