欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-20 22:17:11
angularjs 仿微信图片手势缩放的实例 前言: 最近,公司做一个混合应用项目,涉及到一个图片缩放功能,类似微信那样支持touch事件。 亲测,实现方案很不错...

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

前言:

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

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