H5在移动端实现图片裁剪缩放功能

最近在做一个固定比例的框,去放大缩小图片,让用户去裁切图片的过程。

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); 


    }  
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值