使用pinchzoom实现头像剪裁
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用pinchzoom实现头像剪裁相关的知识,希望对你有一定的参考价值。
pinchzoom 官网 http://manuelstofer.github.io/pinchzoom/
PortraitClip.css
.pinch-page{ position:fixed; top:0; bottom:0; left:0; right:0; display:none; width:100%; height:100%; background-color:#333; z-index:9; } .pinch-page .top-mask, .pinch-page .bottom-mask{ position:absolute; left:0; top:0; right:0; display:block; background-color:rgba(0,0,0,0.6); z-index: 99; } .pinch-page .bottom-mask{ top:auto; bottom:0; } .pinch-page .pinch-zoom-container{ position:absolute!important; left:0; top:0; bottom:0; right:0; margin:auto; overflow: visible!important; z-index: 9; box-sizing: border-box; } .pinch-page .pinch-zoom-container:before{ content:""; position:absolute; top:0; bottom:0; left:0; right:0; display:block; width:100%; height:100%; z-index:999; border:1px solid #fff; box-sizing: border-box; } .pinch-page .pinch-zoom{ } .pinch-page .pinch-zoom-image{ display:block; width:100%; height:320px; background: no-repeat center center; background-size:contain; } .pinch-page .operation-bar{ position:absolute; left:0; right:0; bottom:0; display:block; height:60px; z-index: 999; background-color:rgba(51,51,51,0.6); } .pinch-page .operation-bar .cancel-btn{ position:absolute; top:0; bottom:0; left:0; display:block; height:60px; line-height: 60px; font-size:16px; color:#fff; padding:0 20px; } .pinch-page .operation-bar .save-btn{ position:absolute; top:0; bottom:0; right:0; display:block; height:60px; line-height: 60px; font-size:16px; color:#fff; padding:0 20px; }
PortraitClip.js
(function($){ /* ======================================== 页面渲染 ======================================== */ /* ======================================== 不可变字段 ======================================== */ var initialized = false; // 是否初始化 var container = null; var clientWidth = $(window).width(); var clientHeight = $(window).height(); var pinchZoomImageWidth = clientWidth; var pinchZoomImageHeight = clientWidth; var maskHeight = (clientHeight-clientWidth)/2; var pinchZoom = null; // pinchZoom 对象 /* ======================================== 可变字段 ======================================== */ var imageWidth = 0; var imageHeight = 0; var xOffset = 0; var yOffset = 0; var originScale = 0; var image = null; var callback = null; // 加载完之后的回调 // 构建DOM function render(){ var html = "<div class=‘pinch-page‘> "+ " <em class=‘top-mask‘></em> "+ " <div class=‘pinch-zoom‘> "+ " <div class=‘pinch-zoom-image‘></div> "+ " </div> "+ " <em class=‘bottom-mask‘></em> "+ " <div class=‘operation-bar‘> "+ " <a class=‘cancel-btn‘>取消</a> "+ " <a class=‘save-btn‘>选取</a> "+ " </div> "+ "</div> "; $(html).appendTo("body"); // 初始化 pinchZoom pinchZoom = new RTP.PinchZoom($(".pinch-zoom")); // 添加遮罩 $(".pinch-page .top-mask").css("height",maskHeight+"px"); $(".pinch-page .bottom-mask").css("height",maskHeight+"px"); $(".pinch-zoom-container,.pinch-zoom-image").css({ "width":pinchZoomImageWidth+"px", "height":pinchZoomImageHeight+"px" }); container = $(".pinch-page"); } // 绑定事件 function bindPageEvents(){ container.on("touchend",".save-btn",function(e){ e.stopPropagation(); e.preventDefault(); var transformCss = $(".pinch-zoom").css("-webkit-transform"); var positionInfo = retrievePositionInfo(transformCss); clipImage(positionInfo.scale,positionInfo.x,positionInfo.y,callback); $(container).hide(); }); container.on("touchend",".cancel-btn",function(e){ e.stopPropagation(); e.preventDefault(); $(container).hide(); }); container.on("touchstart touchmove touchend",function(e){ e.stopPropagation(); e.preventDefault(); }); } // 初始化方法 function init(){ if(initialized){ return; } initialized = true; render(); bindPageEvents(); } /* ======================================== common-method ======================================== */ // 刷新 头像剪裁容器 function loadImage(originImage,loadCallback){ if(!initialized){init();} // 如果未初始化则初始化 callback = loadCallback; $(container).find(".pinch-zoom-image").css("background-image","url("+originImage+")"); image = new Image(); image.onload = function(){ imageWidth = image.width; imageHeight = image.height; loadImageCallback(); $(container).show(); }; image.src=originImage; } // 图像加载回调 function loadImageCallback(){ if(imageWidth>imageHeight){ yOffset = (imageWidth-imageHeight)*pinchZoomImageWidth/imageWidth/2; originScale = pinchZoomImageWidth/imageWidth; }else{ xOffset = (imageHeight-imageWidth)*pinchZoomImageWidth/imageHeight/2; originScale = pinchZoomImageHeight/imageHeight; } var minZoom = 1; if(xOffset!=0){ minZoom = clientWidth/(clientWidth-2*xOffset); } if(yOffset!=0){ minZoom = clientWidth/(clientWidth-2*yOffset); } // 初始化 pinchZoom 对戏那个 pinchZoom.options.minZoom = minZoom; pinchZoom.options.tapZoomFactor = minZoom; pinchZoom.options.xOffset = xOffset; pinchZoom.options.yOffset = yOffset; var event = {touches:[{pageX:pinchZoomImageWidth/2,pageY:clientHeight/2}]}; setTimeout(function(){pinchZoom.handleDoubleTap(event);},300); } // 剪裁图像 function clipImage(scale,x,y,callback){ // 创建 canvas var canvasId ="canvas_"+new Date().getTime()+""+parseInt(Math.random()*10000); $("<canvas></canvas>").hide().attr("id",canvasId).appendTo("body"); var canvas=$("#"+canvasId)[0]; var ctx=canvas.getContext("2d"); // 释放canvas function releaseCanvas(){ $("#"+canvasId).remove(); } // canvas 宽度 高度 canvas.width = pinchZoomImageWidth; canvas.height= pinchZoomImageHeight; if(image.width>image.height){ y=y-yOffset; }else{ x=x-xOffset; } ctx.drawImage(image,x/originScale,y/originScale,pinchZoomImageWidth/scale/originScale,pinchZoomImageHeight/scale/originScale,0,0,pinchZoomImageWidth,pinchZoomImageHeight); var dataURL = canvas.toDataURL(); if(callback!=null){ callback(dataURL); } releaseCanvas(); } // 获取 pinch-zoom 缩放 偏移信息 function retrievePositionInfo(transformCss){ var infoStr = transformCss.replace("matrix(",""); infoStr = infoStr.replace(")",""); var arr = infoStr.split(","); var scale = arr[0]; var x = arr[4]; var y = arr[5]; if(x<0){ x = -1*x; } if(y<0){ y=-1*y; } var result = {scale:scale,x:x/scale,y:y/scale}; return result; } var PortraitClipUtil = {}; PortraitClipUtil.loadImage=loadImage; window.PortraitClipUtil = PortraitClipUtil; })(jQuery);
测试页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Pinchzoom.js Demo</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes" /> <link rel="stylesheet" href="css/common/PortraitClip.css" /> <style> body{margin:0;} </style> </head> <body style="height:900px;"> <button id="upload-image">上传图片</button> <image id="image" style="position: absolute;display:block;top:0;z-index:9999;"/> <script type="text/javascript" src="dist/js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="dist/js/pinchzoom-xiaomin.min.js"></script> <script type="text/javascript" src="js/common/PortraitClip.js"></script> <script> $("#upload-image").click(function(e){ PortraitClipUtil.loadImage("frog.jpg",function(dataURL){ $("#image").attr("src",dataURL); }); }); </script> </body> </html>
注:这边引入的是pinchzoom-xiaomin.min.js。对pinchzoom.min.js源代码有所变更。pinchzoom.js,pinchzoom.min.js,pinchzoom-xiaomin.js,pinchzoom-xiaomin.min.js在相应的附件中。
以上是关于使用pinchzoom实现头像剪裁的主要内容,如果未能解决你的问题,请参考以下文章
java web 网站头像上传处理 (springmvc +bootstrap+cropper)
java web 网站头像上传处理 (springmvc +bootstrap+cropper)