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在相应的附件中。
原文:http://antlove.blog.51cto.com/10057557/1844000