首页 > 编程 > JavaScript > 正文

AngularJS 仿微信图片手势缩放的实例

2019-11-19 15:16:35
字体:
来源:转载
供稿:网友

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文件上设定一个属性即可,是不是很简单呢?

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表