zepto+html5+php实现h5上传头像(移动端)下
zepto+html5+php实现h5上传头像(移动端)下
leona_lily 发表于3年前
zepto+html5+php实现h5上传头像(移动端)下
  • 发表于 3年前
  • 阅读 125
  • 收藏 2
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 有了图片,加载到另一个页面之后,就开始真正的截图操作的,还有通过判断一个手指还是两个手指实现移动和放大缩小功能!截图最麻烦,总是对不准,放大了以后截图会更明显!!!!

上一篇上传成功之后,开始在另一个页面通过传过来的图片的base64编码,来把这个src放到要显示图片的位置的img标签里面,当然预加载过程是要对图片进行成比例性的缩小,保证整张图片都在页面里面

页面结构很重要的,这会直接影响到你实现的过程和效果的麻烦程度,甚至会影响到后期的截图控制不了

history想法和做法:层次逐渐往上顺序是   底层div1 -->图片img-->背景带白色窟窿截窗的灰色div2-->和图片大小一致的div3。

实现的想法:是通过控制最上层的div3来同步img,然后根据背景div2的白窟窿截固定大小的区域

难度:因为白色窟窿其实是背景颜色中的一块区域,没有办法很好的固定住他,或者明确的找到他的位置,实现起来麻烦。

最终实现想法和做法:底层div1-->图片img1-->灰色背景层div2-->截窗div3里面在包含图片img2。

实现的想法:div3大小取设备的宽度和高度的60%,这样就可以通过offset来找位置,div3里面的图片img2设置overflow:hidden,控制img2和img1同步,截图截img1的图片,但是放大和缩小就只能在div3的小区域里面实现,不能针对整屏的图片实现,这还需要后期改善!

html代码:

<div id="wrapper1" style="border: 1px gray dotted;height: 92%;width: 99%;margin: 0 auto;">
   
    <div id="mainCutter" style="overflow: hidden; position: relative;width: 99%;height: 99%;">
    	
        <img id="imgPreview" src="<?php echo $imgsrc;?>" style=' position:absolute;'/>
        <div class="picbg" style="background:rgba(0,0,0,.5);"></div>
        <div class="cutDiv" id='cutDiv' style="overflow:hidden;position:fixed;">
        	<img id="moveBox" src="<?php echo $imgsrc;?>" style=' position:absolute;'/>
        </div>
    </div>
    <canvas id="cropper" style=" display:none;border:1px solid red;" >您的浏览器不支持画布</canvas>

</div>

  1. 图片预加载代码js
    <script type="text/javascript">
    	window.onload = function(){ 
    		var imgLoad = document.getElementById("imgPreview");
    		if(document.addEventListener){
    			imgLoad.addEventListener('load',AutoResizeImage(),false);
    		}
    		else{ 
    			imgLoad.attachEvent('onload',AutoResizeImage());
    		}
    	}
    </script>



function AutoResizeImage(){ 
	 var imgLen = $(img_preview).attr('src').length;
	 if (imgLen<100) { 
	 	$('.newHmLayer').show();
	 	$(img_preview).hide();
	 	return;
	 };
	 Options_image.width=img_preview.width;  
     Options_image.height=img_preview.height;  
     _initCropAndCut();
}
完整的js代码如下,包含判断触摸是两指还是一指

<script type="text/javascript"> 
	var input_browseFile = document.getElementById("browseFile");  
    var img_preview = document.getElementById("imgPreview");  
    var moveBox = document.getElementById("moveBox");
    var cutDiv = document.getElementById("cutDiv");
    var cutBox=document.getElementById("cutBox");  
    var tipBox=document.getElementById("tipBox");  
    var _cropper=document.getElementById("cropper");  
    var mainCutter=document.getElementById("mainCutter");  
    var tips2=$("#tips2");  
    var wrapper=document.getElementById("wrapper1");  
    var component_box=document.getElementById("component_box");
//--逻辑,点击图片上传选择后将加载预览图片  
var Options={  
    width:$(wrapper).width(),  
    height:$(wrapper).height(),  
    cutWidth:$(wrapper).width()/2,  
    cutHeight:$(wrapper).height()/2,  
    cutMinSize:50,//裁剪框最小尺寸,即最小可以缩放到这个size,width及height任意一个都无法小于这个值。  
  
    //--系统自带,运行时自动运算,请不要修改。  
    cropViewWidth:0,//在画布里面显示的最大宽度  
    cropViewHeight:0,//在画布里面显示的最大高度  
    cropLeft:0,  
    cropTop:0,
    //lili记录图片的原始大小和上左边距  
    currentImgWidth:0,
    currentImgHeight:0,
    currentImgWidth1:0,
    currentImgHeight1:0,
    currentLeft:0,
    currentTop:0,
    //lil移动框的位移偏移
    moveleft:0,
    moveTop:0,
    moveViewLeft:0,
    moveViewTop:0,

    //--四象限。用于判断距离。  
    cutBoxLimitX1:0,  
    cutBoxLimitX2:0,  
    cutBoxLimitY1:0,  
    cutBoxLimitY2:0,  
    initStatus:false//当前组件是否已经初始化了。  
};  
var Options_image={  
    width:0,  
    height:0,  
    imgData:""  
}    
function AutoResizeImage(){ 
	 var imgLen = $(img_preview).attr('src').length;
	 if (imgLen<100) { 
	 	$('.newHmLayer').show();
	 	$(img_preview).hide();
	 	return;
	 };
	 Options_image.width=img_preview.width;  
     Options_image.height=img_preview.height;  
     _initCropAndCut();
}
function LoadingImage(){  
   // $(img_preview).css({"width":"","height":""});  
}  
function _initCropAndCut(){  
    //--计算比例,将其放到canvas里面。  
    var scale = Math.max(Options_image.width/Options.width,Options_image.height/Options.height);  
    if(scale>1){  
       Options.cropViewWidth=parseInt(Math.floor(Options_image.width/scale));  
       Options.cropViewHeight=parseInt(Math.floor(Options_image.height/scale));  
    }  
    else{  
       Options.cropViewWidth=Options_image.width;  
       Options.cropViewHeight=Options_image.height;  
    }  
    //--计算画布里面的图像的位置。  
    Options.cropLeft=parseInt((Options.width-Options.cropViewWidth)/2);  
    Options.cropTop=parseInt((Options.height-Options.cropViewHeight)/2);  
    //--计算裁剪框实际大小及实际位置。  
    //计算裁剪框的位置。  
    Options.moveViewLeft= parseInt(Options.cropLeft+Options.moveleft);
    Options.moveViewTop = parseInt(Options.cropTop+Options.moveTop);
    //-四象限。  
    Options.cutBoxLimitX1=0;  
    Options.cutBoxLimitX2=Options.cropViewWidth;  
    Options.cutBoxLimitY1=0;  
    Options.cutBoxLimitY2=Options.cropViewHeight;
    Options.currentImgWidth1=Options.cropViewWidth;
    Options.currentImgHeight1=Options.cropViewHeight;  
    $(img_preview).css({"width":Options.cropViewWidth+"px","height":Options.cropViewHeight+"px","left": Options.cropLeft+"px","top":Options.cropTop+"px"}); 
    var imgLeft1 = $(img_preview).offset().left;
    var imgTop1 = $(img_preview).offset().top;
    $(cutDiv).css({
    	width: $(window).width()*0.6,
    	height: $(window).width()*0.6,
    	top:'50%',
    	left:'50%',
    	marginLeft:-$(window).width()*0.3,
    	marginTop:-$(window).width()*0.3
    });
    $(moveBox).css({"width":Options.cropViewWidth+"px","height":Options.cropViewHeight+"px"}); 
    $(moveBox).offset({left:imgLeft1,top:imgTop1});
  
    Options.initStatus=true;  
}   
    //--添加缩放功能。  
Options_move={  
    beginX1:0,  
    beginY1:0,
    beginX2:0,  
    beginY2:0,
    beginX3:0,  
    beginY3:0,  
    beginLength:0,
    endX1:0,  
    endY1:0,
    endX2:0,  
    endY2:0, 
    endX3:0,  
    endY3:0, 
    endLength:0
    };  
/** 
 * 拖动裁剪框的逻辑处理。 
 * */  
moveBox.addEventListener("touchstart",function(event){  
  event.preventDefault();  
  event.stopPropagation();  
  //一根手指的时候 移动
  if(event.touches.length == 1){
	    Options_move={  
	        beginX1:0,  
	        beginY1:0,  
	        endX1:0,  
	        endY1:0  
	    };  
	    var beginX=event.changedTouches[0].clientX;  
	    var beginY=event.changedTouches[0].clientY;  
	    Options_move.beginX1=beginX;  
	    Options_move.beginY1=beginY;  
   }
   //多个手指 放大缩小
  if(event.touches.length > 1){ 
  		Options_move.beginX3=event.touches[0].clientX;   //初始手指位置
   		Options_move.beginY3=event.touches[0].clientY;
   		Options_move.beginX2=event.touches[1].clientX;
   		Options_move.beginY2=event.touches[1].clientY;
   		var movex = Options_move.beginX3-Options_move.beginX2;
   		var movey = Options_move.beginY3-Options_move.beginY2;
   		Options_move.beginLength=Math.sqrt(movex*movex + movey*movey);

  }

},false);  
moveBox.addEventListener("touchmove",function(event){  
    event.preventDefault();  
    event.stopPropagation();  
    //--  
    if (event.touches.length == 1) {
		    var beginX=event.changedTouches[0].clientX;  
		    var beginY=event.changedTouches[0].clientY;  
		    Options_move.endX1=beginX;  
		    Options_move.endY1=beginY;  
		    //--计算是否发生位移,根据位移来定位裁剪框位置。  
		    //位移量。  
		    var _d_x=Options_move.endX1-Options_move.beginX1;  
		    var _d_y=Options_move.endY1-Options_move.beginY1;  
		    //--当前图片原始位置。  
		    var _new_x=Options.cropLeft;  
		    var _new_y=Options.cropTop;
		    //当前移动框的原始位置
		    var _newMove_x=Options.moveViewLeft;
		    var _newMove_y=Options.moveViewTop; 

		    _new_x+=_d_x;  
		    _new_y+=_d_y;
		    _newMove_x+=_d_x;
		    _newMove_y+=_d_y; 
		    //--判断是否在矩形边框,假如超出去,那么就取最终点。  
		    //--注意,判断相关点的范围。  
		  
		    Options.cropLeft=_new_x;  
		    Options.cropTop=_new_y;
		    Options.moveViewLeft = _newMove_x;
		    Options.moveViewTop = _newMove_y;  
		    Options.currentImgWidth = Options.cropViewWidth;
		    Options.currentImgHeight = Options.cropViewHeight;
		    _resizecropView();  
		    //---将这一点的放回前一点。  
		    Options_move.beginX1=Options_move.endX1;  
		    Options_move.beginY1=Options_move.endY1;  
  };
  //两个手指
  if (event.touches.length > 1) { 
  	//alert('开始移动')
  		Options_move.endX3 = event.touches[0].clientX;  //手指移动中的位置确定
  		Options_move.endY3 = event.touches[0].clientY;
  		Options_move.endX2 = event.touches[1].clientX;
  		Options_move.endy2 = event.touches[1].clientY;
  		var moveEndx = Options_move.endX3-Options_move.endX2;
  		var moveEndy = Options_move.endY3-Options_move.endy2;
  		Options_move.endLength = Math.sqrt(moveEndy*moveEndy + moveEndx*moveEndx);
  		//计算两指之间的距离是放大还是缩小   距离四舍五入
  		var moveCompare = Math.ceil(Options_move.endLength/Options_move.beginLength);
  		var moveScale =(Options_move.endLength/Options_move.beginLength).toFixed(2);
  		Options.currentImgWidth = Options.cropViewWidth;
  		Options.currentImgHeight = Options.cropViewHeight;
  		var imgLeft = Options.cropLeft;
  		var imgTop = Options.cropTop;
  		var curMoveLeft = Options.moveViewLeft;
  		var curMoveTop = Options.moveViewTop;
  		if(moveCompare>1){ 
  			Options.cropViewWidth = Options.currentImgWidth*1.02;
  			Options.cropViewHeight = Options.currentImgHeight*1.02;
  			var _x_ = Options.cropViewWidth-Options.currentImgWidth;
  			var _y_ = Options.cropViewHeight-Options.currentImgHeight;
  			Options.cropLeft = imgLeft-parseInt(_x_/2);
  			Options.cropTop = imgTop-parseInt(_y_/2);
  			Options.moveViewLeft = curMoveLeft-parseInt(_x_/2);
  			Options.moveViewTop = curMoveTop-parseInt(_y_/2);
  		}
  		else{ 
  			Options.cropViewWidth = Options.currentImgWidth*0.98;
  			Options.cropViewHeight = Options.currentImgHeight*0.98;
  			var _x_ = Options.currentImgWidth-Options.cropViewWidth;
  			var _y_ = Options.currentImgHeight-Options.cropViewHeight;
  			Options.cropLeft = imgLeft+parseInt(_x_/2);
  			Options.cropTop = imgTop+parseInt(_y_/2);
  			Options.moveViewLeft = curMoveLeft+parseInt(_x_/2);
  			Options.moveViewTop = curMoveTop+parseInt(_y_/2);
  		}
  		//alert('图片左边=='+Options.cropLeft+'====图片上面====='+Options.cropTop)
  		Options_move.beginX2 = Options_move.endX2;
  		Options_move.beginY2 = Options_move.endY2;
  		Options_move.beginY3 = Options_move.endY3;
  		Options_move.beginX3 = Options_move.endX3;
  		_resizecropView();
  };
},false);  
moveBox.addEventListener("touchend",function(event){  
    event.preventDefault();  
    event.stopPropagation();  
    return;  
  
},false);  
 /** 
 * 根据相关参数重新resize裁剪框 
 * */  
function _resizecropView(){  
    $(img_preview).css({"width":Options.cropViewWidth+"px","height":Options.cropViewHeight+"px","left":Options.cropLeft+"px","top":Options.cropTop+"px"});
    $(moveBox).css({"width":Options.cropViewWidth+"px","height":Options.cropViewHeight+"px"});
    $(moveBox).offset({left:$(img_preview).offset().left,top:$(img_preview).offset().top})  
}

$('#savePhone').click(function(){ 
	var cropper = document.getElementById('cropper');
	var scale_x=Options.currentImgWidth1/Options.cropViewWidth;
	var scale_y=Options.currentImgHeight1/Options.cropViewHeight;
    cropper.width = $(cutDiv).width();  
    cropper.height = $(cutDiv).height();
    var cutImage = cropper.getContext("2d");
    if ($(img_preview).offset().left<0) { 
    	le = parseInt(Math.abs($(img_preview).offset().left)+$(cutDiv).offset().left);
    }
    else{ 
    	le = parseInt($(cutDiv).offset().left-$(img_preview).offset().left);
    }
    if ($(img_preview).offset().top < 0) { 
    	rg =parseInt(Math.abs($(img_preview).offset().top)+$(cutDiv).offset().top);
    }
    else{ 
    	rg = parseInt($(cutDiv).offset().top-$(img_preview).offset().top);
    }
    var _o_x = parseInt(scale_x*le+scale_x*0.5*le);  
    var _o_y = parseInt(scale_y*rg+scale_y*0.4*rg);
    var _o_width = scale_x*$(cutDiv).width()
    var _o_height = scale_y*$(cutDiv).height()
    cutImage.drawImage(img_preview, _o_x,_o_y, _o_width, _o_width , 0, 0, cropper.width,cropper.height);
   $.ajax({
   	url: '/upload',
   	type: 'POST',
   	dataType: '',
   	data: 'file='+cropper.toDataURL("image/jpeg"),
   	success:function(res){ 
   		$('#sendHead').show();
   		$('#sendHead').css('z-index', '9999');
   		setTimeout(lodHref(),2000);
   	}
   })
})

function lodHref () {
	window.location.href = "/usercenter/index";
}



注:截图位置还是有一定的偏差,测试的时候因为电脑上不知道怎么模拟两个手指,没法放大缩小,所以只能通过手机上alert()来实现,挺麻烦的,如果能在手机上测就好了,不然来报错了都不知道是哪里的错,一顿alert呀




共有 人打赏支持
粉丝 9
博文 91
码字总数 37807
×
leona_lily
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: