您的位置:首页 > 移动开发

简单的移动端图片预览 包含放大缩小以及对各种手势的判定

2015-12-23 11:41 447 查看
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<title>title</title>
<link rel="stylesheet" type="text/css" href="../css/api.css"/>   //这个css的作用是去边距的,就是清除默认样式,设置自己的默认样式的
<style>
body, html {
width: 100%;
height: 100%;
}
header {
width: 100%;
height: 50px;
background-color: #23C6C8;
margin-bottom: 40px;
color: #fff;
font-size: 18px;
line-height: 50px;
vertical-align: middle;
text-indent: 2em;
}
.main {
width: 98%;
margin-left: 2%;
}
.each-div {
width: 60px;
height: 60px;
text-align: center;
line-height: 90px;
vertical-align: middle;
float: left;
}
.main img {
height: 40px;
}
.preview {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgba(0,0,0,0.8);
}
.preview-content {
position: relative;
top: 50px;
left: 0;
overflow: auto;
}
.preview img {
position: absolute;
}
</style>
</head>
<body>
<header>图片预览测试</header>
<div class="main">
<div class="each-div"><img src="images/icon_00.png"/></div>
<div class="each-div"><img src="images/icon_01.png"/></div>
<div class="each-div"><img src="images/icon_02.png"/></div>
<div class="each-div"><img src="images/icon_03.png"/></div>
<div class="each-div"><img src="images/icon_04.png"/></div>
<div class="each-div"><img src="images/icon_05.png"/></div>
<div class="each-div"><img src="images/icon_06.png"/></div>
<div class="each-div"><img src="images/icon_07.png"/></div>
<div class="each-div"><img src="images/icon_08.png"/></div>
<div class="each-div"><img src="images/icon_09.png"/></div>
<div class="each-div"><img src="images/icon_10.png"/></div>
<div class="each-div"><img src="images/icon_11.png"/></div>
<div class="each-div"><img src="images/icon_12.png"/></div>
<div class="each-div"><img src="images/icon_13.png"/></div>
<div class="each-div"><img src="images/icon_14.png"/></div>
<div class="each-div"><img src="images/icon_15.png"/></div>
<div class="each-div"><img src="images/icon_16.png"/></div>
<div class="each-div"><img src="images/icon_17.png"/></div>
<div class="each-div"><img src="images/icon_18.png"/></div>
<div class="each-div"><img src="images/icon_19.png"/></div>
<div class="each-div"><img src="images/icon_20.png"/></div>
<div class="each-div"><img src="images/icon_21.png"/></div>
</div>
</body>
<script type="text/javascript" src="jquery-2.1.1.js"></script>
<script type="text/javascript">
var isPress = 0;                   // 是否已经点击过,用来判断是单击还是双击,使用setTimeout来判断,如果在第一次点击完0.5秒内点击第二次,即判断为双击
var isBiger = false;               // 是否放大,在双击和双指放大缩小中均有使用。一旦缩放就自动判断为已经放大
var thisPicWidth, thisPicHeight;   // 图片在加载完成后的当前大小
var theSpaceSite;                  // 上一个点的各种数据

/*
* 点击触发图片预览效果,后面如果改点击事件改这里,同时清空thisPicHeight、thisPicWidth
*/
$('.main').on('click', '.each-div', function() {
thisPicHeight = 0;
thisPicWidth = 0;
var mySrc = $(this).find('img').attr('src');
addPreview( $(this).find('img').attr('src') );
});

/*
* 添加预览图片的界面,传入参数为图片地址
*/
function addPreview(src) {
var node = $('<div class="preview" id="preview"><div class="preview-content"><img src="' + src + '"/></div></div>');
$('body').append( node );
changeSize();
setClick();
};

/*
* 改变当前图片的大小,以及总的div的大小
*/
function changeSize() {
// 总的手机的高宽
var bodyHeight = $(document).height();
var bodyWidth = $(document).width();
// 原本图片的高宽
var imgHeightBefore = $('.preview').find('img').height();
var imgWidthBefore = $('.preview').find('img').width();
// 当前div的高需要减去头部的100像素,和宽
var contentHeight = bodyHeight - 100;
var contentWidth = bodyWidth;
$('.preview-content').width( contentWidth );
$('.preview-content').height( contentHeight );
// 判断横竖比例,以及该如何显示图片
var contentRatio = contentHeight / contentWidth;
var imageRatio = imgHeightBefore / imgWidthBefore;
if( contentRatio >= imageRatio ) {
thisPicWidth = contentWidth;
thisPicHeight =  Math.round( contentWidth * imageRatio );
$('.preview').find('img').width( thisPicWidth );
$('.preview').find('img').height( thisPicHeight );
} else {
thisPicHeight = contentHeight;
thisPicWidth =  Math.round( contentHeight / imageRatio );
$('.preview').find('img').width( thisPicWidth );
$('.preview').find('img').height( thisPicHeight );
};
// 给图片进行定位移位
$('.preview').find('img').css( 'top', ( contentHeight - thisPicHeight ) / 2 );
$('.preview').find('img').css( 'left', ( contentWidth - thisPicWidth ) / 2 );
};

/*
* 点击事件,触摸屏幕事件
*/
function setClick() {
/*
* 点击触发图片外面就关闭图片预览
*/
$('body').on('click', '.preview', function() {
isBiger = false;
$('.preview').remove();
});

/*
* 点击禁止关闭图片预览,与上一个配合
*/
$('body').on('click', '.preview img', function(e) {
e.stopPropagation();
});

var preview = document.getElementById('preview');
/*
* 触碰开始事件记录 1个 或 2个 的当前点的坐标等
*/
preview.ontouchstart = function(event) {
event.preventDefault();
var e = window.event || event;
if( isPress == 0 ) {
//singleFinger
isPress = 1;
} else {
if (e.touches[1]) {
// doubleFinger
// 第一个点的坐标,用于和下一个点进行比较,判断该如何缩放
var x1 = e.touches[1].clientX - this.offsetLeft,
x2 = e.touches[0].clientX - this.offsetLeft,
y1 = e.touches[1].clientY - this.offsetTop,
y2 = e.touches[0].clientY - this.offsetTop;
theSpaceSite = [{ 'x': x2 , 'y': y2 } , { 'x': x1 , 'y': y1 }];
} else {
//doubleClick
var x = e.touches[0].clientX - this.offsetLeft;
var y = e.touches[0].clientY - this.offsetTop;
doubleClick(x, y);
};
};
setTimeout( yanChi , 500 );
};

/*
* 移动事件,只处理双指放大缩小。其他的单指事件直接交给网页处理,即滑动事件。
*/
preview.ontouchmove = function(event) {
var e = window.event || event;
if (e.touches[1]) {
event.preventDefault();
// 将isBiger设为true,触发双击事件时必定为缩小至原样
isBiger = true;
var thisImageSite = { 'width': $('.preview img').width() , 'height': $('.preview img').height() };
var thisImageScroll = { 'left': $('.preview-content').scrollLeft() , 'top': $('.preview-content').scrollTop() };
var x0 = e.touches[0].clientX - this.offsetLeft,
x1 = e.touches[1].clientX - this.offsetLeft,
y0 = e.touches[0].clientY - this.offsetTop,
y1 = e.touches[1].clientY - this.offsetTop;
var thisDoubleMove = [{ 'left': x0 - theSpaceSite[0].x , 'top': y0 - theSpaceSite[0].y }, { 'left': x1 - theSpaceSite[1].x , 'top': y1 - theSpaceSite[1].y }];
if( x0 >= x1 ) {
var bigerNumber = 0;
} else {
var bigerNumber = 1;
}
var midSitePlace = { 'x': Math.abs(( x0 + x1 ) * 0.5) , 'y': Math.abs(( y0 + y1 ) * 0.5) };
changeImageSize( thisImageSite, thisImageScroll, thisDoubleMove, bigerNumber, midSitePlace );
theSpaceSite = [{ 'x': x0 , 'y': y0 } , { 'x': x1 , 'y': y1 }];
};
};
};

/*
* 延迟判断是双击或者是单击
*/
function yanChi() {
isPress = 0;
};

/*
* 双击触发这个事件,传入当前点击的地址,将图片方法两倍或者缩小至原样
*/
function doubleClick(x, y) {
if( isBiger == false ) {
//将图像放大到两倍大小
isBiger = true;
$('.preview').find('img').height( thisPicHeight * 2 );
$('.preview').find('img').width( thisPicWidth *2 );

//将图像放大后放到自己想要的位置上
var contentHeight = $('.preview-content').height();
var contentWidth = $('.preview-content').width();
if( contentHeight == thisPicHeight ) {
$('.preview-content').scrollTop( y );
if( contentWidth < 2 * thisPicWidth ) {
var scrollX = x - ( contentWidth - thisPicWidth ) / 2;
$('.preview-content').scrollLeft( scrollX );
};
} else if( contentWidth == thisPicWidth ) {
$('.preview-content').scrollLeft( x );
if( contentHeight < 2 * thisPicHeight ) {
var scrollY = y - ( contentHeight - thisPicHeight ) / 2;
$('.preview-content').scrollTop( scrollY );
};
} else {
alert('出了一个问题');
};
} else {
isBiger = false;
$('.preview').find('img').height( thisPicHeight );
$('.preview').find('img').width( thisPicWidth );
};
};

/*
* 双指缩放事件   这个逻辑可能不太好捋,有问题可以问我
* param thisImageSite   当前图片的大小
* param thisImageScroll 当前图片的scroll的位置
* param thisDoubleMove  两只手指分别移动了多少位置,带 + — 号的
* param bigerNumber     哪个手指在右边
* param midSitePlace    两个手指的中间点的坐标
*/
function changeImageSize( thisImageSite, thisImageScroll, thisDoubleMove, bigerNumber, midSitePlace ) {
// 下面是计算总共两只手指挪动了多少,是绝对值的相加。
// 不能分开算,不然图片会变形,所以取其中偏移量比较大的那个作为最后的偏移量。
var finalMove;
var leftTotalMove = Math.abs(thisDoubleMove[0].left) + Math.abs(thisDoubleMove[1].left),
topTotalMove = Math.abs(thisDoubleMove[0].top) + Math.abs(thisDoubleMove[1].top);
if( leftTotalMove >= topTotalMove ) {
finalMove = leftTotalMove;
} else {
finalMove = topTotalMove;
};

// 计算乘积,我只取了一种情况,就是两只手指分别向反方向移动才能缩放。 所以下面的第一个if判断就是是否是反方向的
var leftMultiple = thisDoubleMove[0].left * thisDoubleMove[1].left,
topMultiple = thisDoubleMove[0].top * thisDoubleMove[1].top;
if( leftMultiple <= 0 && topMultiple <= 0 ){
// 下面这两个判断是判断分别是放大还是缩小。 其实可以不用管,直接在里面写就可以了。
if( ( thisDoubleMove[0].left >= 0 && bigerNumber == 0 ) || ( thisDoubleMove[0].left < 0 && bigerNumber == 1 ) ){
$('.preview img').width( thisImageSite.width + finalMove );
$('.preview img').height( thisImageSite.height + ( finalMove * thisImageSite.width / thisImageSite.height ) );
$('.preview-content').scrollLeft( thisImageScroll.left + finalMove / 2 );
$('.preview-content').scrollTop( thisImageScroll.top + ( finalMove * thisImageSite.width / thisImageSite.height ) / 2 );
} else if( ( thisDoubleMove[0].left >= 0 && bigerNumber == 1 ) || ( thisDoubleMove[0].left < 0 && bigerNumber == 0 ) ) {
if( thisImageSite.width > thisPicWidth && thisImageSite.height > thisPicHeight ) {
$('.preview img').width( thisImageSite.width - finalMove );
$('.preview img').height( thisImageSite.height - ( finalMove * thisImageSite.width / thisImageSite.height ) );
$('.preview-content').scrollLeft( thisImageScroll.left - finalMove / 2 );
$('.preview-content').scrollTop( thisImageScroll.top - ( finalMove * thisImageSite.width / thisImageSite.height ) / 2 );
};
};
};
};
</script>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: