AngularJS 仿微信图片手势缩放的实例
- 作者: 那晚越女说我?
- 来源: 51数据库
- 2021-08-28
angularjs 仿微信图片手势缩放的实例
前言:

最近,公司做一个混合应用项目,涉及到一个图片缩放功能,类似微信那样支持touch事件。
亲测,实现方案很不错,所以放出来,和大家分享一下,希望有人能用得到。
核心思想就是用到了css3的transform属性, 不多说,我们看代码:
'use strict';
/**
* @nginject
*/
module.exports = function () {
var _directive = {
restrict : 'a',
scope : false,
link : _link
};
function _link(scope, element, attrs) {
var elwidth, elheight;
// mode : 'pinch' or 'swipe'
var mode = '';
// distance between two touche points (mode : 'pinch')
var distance = 0;
var initialdistance = 0;
// image scaling
var scale = 1;
var relativescale = 1;
var initialscale = 1;
var maxscale = parseint(attrs.maxscale, 10);
if (isnan(maxscale) || maxscale <= 1) {
maxscale = 3;
}
// position of the upper left corner of the element
var positionx = 0;
var positiony = 0;
var initialpositionx = 0;
var initialpositiony = 0;
// central origin (mode : 'pinch')
var originx = 0;
var originy = 0;
// start coordinate and amount of movement (mode : 'swipe')
var startx = 0;
var starty = 0;
var movex = 0;
var movey = 0;
var image = new image();
image.onload = function() {
elwidth = element[0].clientwidth;
elheight = element[0].clientheight;
element.css({
'-webkit-transform-origin' : '0 0',
'transform-origin' : '0 0'
});
element.on('touchstart', touchstarthandler);
element.on('touchmove', touchmovehandler);
element.on('touchend', touchendhandler);
};
if (attrs.ngsrc) {
image.src = attrs.ngsrc;
} else {
image.src = attrs.src;
}
/**
* @param {object} evt
*/
function touchstarthandler(evt) {
var touches = evt.originalevent ? evt.originalevent.touches : evt.touches;
startx = touches[0].clientx;
starty = touches[0].clienty;
initialpositionx = positionx;
initialpositiony = positiony;
movex = 0;
movey = 0;
}
/**
* @param {object} evt
*/
function touchmovehandler(evt) {
var touches = evt.originalevent ? evt.originalevent.touches : evt.touches;
if (mode === '') {
if (touches.length === 1 && scale > 1) {
mode = 'swipe';
} else if (touches.length === 2) {
mode = 'pinch';
initialscale = scale;
initialdistance = getdistance(touches);
originx = touches[0].clientx -
parseint((touches[0].clientx - touches[1].clientx) / 2, 10) -
element[0].offsetleft - initialpositionx;
originy = touches[0].clienty -
parseint((touches[0].clienty - touches[1].clienty) / 2, 10) -
element[0].offsettop - initialpositiony;
}
}
if (mode === 'swipe') {
evt.preventdefault();
movex = touches[0].clientx - startx;
movey = touches[0].clienty - starty;
positionx = initialpositionx + movex;
positiony = initialpositiony + movey;
transformelement();
} else if (mode === 'pinch') {
evt.preventdefault();
distance = getdistance(touches);
relativescale = distance / initialdistance;
scale = relativescale * initialscale;
positionx = originx * (1 - relativescale) + initialpositionx + movex;
positiony = originy * (1 - relativescale) + initialpositiony + movey;
transformelement();
}
}
/**
* @param {object} evt
*/
function touchendhandler(evt) {
var touches = evt.originalevent ? evt.originalevent.touches : evt.touches;
if (mode === '' || touches.length > 0) {
return;
}
if (scale < 1) {
scale = 1;
positionx = 0;
positiony = 0;
} else if (scale > maxscale) {
scale = maxscale;
relativescale = scale / initialscale;
positionx = originx * (1 - relativescale) + initialpositionx + movex;
positiony = originy * (1 - relativescale) + initialpositiony + movey;
} else {
if (positionx > 0) {
positionx = 0;
} else if (positionx < elwidth * (1 - scale)) {
positionx = elwidth * (1 - scale);
}
if (positiony > 0) {
positiony = 0;
} else if (positiony < elheight * (1 - scale)) {
positiony = elheight * (1 - scale);
}
}
transformelement(0.1);
mode = '';
}
/**
* @param {array} touches
* @return {number}
*/
function getdistance(touches) {
var d = math.sqrt(math.pow(touches[0].clientx - touches[1].clientx, 2) +
math.pow(touches[0].clienty - touches[1].clienty, 2));
return parseint(d, 10);
}
/**
* @param {number} [duration]
*/
function transformelement(duration) {
var transition = duration ? 'all cubic-bezier(0,0,.5,1) ' + duration + 's' : '';
var matrixarray = [scale, 0, 0, scale, positionx, positiony];
var matrix = 'matrix(' + matrixarray.join(',') + ')';
element.css({
'-webkit-transition' : transition,
transition : transition,
'-webkit-transform' : matrix + ' translate3d(0,0,0)',
transform : matrix
});
}
}
return _directive;
};
上面代码中我们新建了一个directive,方便多个地方重用。
当我们建立好directive时候,该如何使用呢?
<img style="width:100%;" src="assets/images/floorplan.jpeg" ng-pinch-zoom>
我们只需要在img文件上设定一个属性即可,是不是很简单呢?
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
推荐阅读
热点文章
Angular中响应式表单的三种更新值方法详析
7
Angularjs实现下拉框联动的示例代码
7
详解AngularJS跨页面传值(ui-router)
2
详解AngularJS1.x学习directive 中‘& ’‘=’ ‘@’符号的区别使用
3
angular2路由切换改变页面title的示例代码
4
Angular2 组件间通过@Input @Output通讯示例
5
Angularjs中ng-repeat的简单实例
3
AngularJS 中ui-view传参的实例详解
4
浅谈Angular路由守卫
4
详解基于Angular4+ server render(服务端渲染)开发教程
4
