首页  >  文章  >  web前端  >  AngularJS仿微信图片手势缩放代码

AngularJS仿微信图片手势缩放代码

小云云
小云云原创
2018-01-30 09:50:392205浏览

图片可以放大缩小这种功能很常见,本文主要介绍了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 : &#39;pinch&#39;)
    var originX = 0;
    var originY = 0;

    // start coordinate and amount of movement (mode : &#39;swipe&#39;)
    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({
        &#39;-webkit-transform-origin&#39; : &#39;0 0&#39;,
        &#39;transform-origin&#39;     : &#39;0 0&#39;
      });

      element.on(&#39;touchstart&#39;, touchstartHandler);
      element.on(&#39;touchmove&#39;, touchmoveHandler);
      element.on(&#39;touchend&#39;, 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 === &#39;&#39;) {
        if (touches.length === 1 && scale > 1) {

          mode = &#39;swipe&#39;;

        } else if (touches.length === 2) {

          mode = &#39;pinch&#39;;

          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 === &#39;swipe&#39;) {
        evt.preventDefault();

        moveX = touches[0].clientX - startX;
        moveY = touches[0].clientY - startY;

        positionX = initialPositionX + moveX;
        positionY = initialPositionY + moveY;

        transformElement();

      } else if (mode === &#39;pinch&#39;) {
        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 === &#39;&#39; || 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 = &#39;&#39;;
    }

    /**
     * @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 ? &#39;all cubic-bezier(0,0,.5,1) &#39; + duration + &#39;s&#39; : &#39;&#39;;
      var matrixArray = [scale, 0, 0, scale, positionX, positionY];
      var matrix   = &#39;matrix(&#39; + matrixArray.join(&#39;,&#39;) + &#39;)&#39;;

      element.css({
        &#39;-webkit-transition&#39; : transition,
        transition      : transition,
        &#39;-webkit-transform&#39; : matrix + &#39; translate3d(0,0,0)&#39;,
        transform      : matrix
      });
    }
  }

  return _directive;
};

上面代码中我们新建了一个directive,方便多个地方重用。

当我们建立好directive时候,该如何使用呢?


 <img style="width:100%;" src="assets/images/floorplan.jpeg" ng-pinch-zoom>

我们只需要在img文件上设定一个属性即可,是不是很简单呢?

相关推荐:

jQuery实现鼠标滚轮控制图片缩放

html5手机端页面缩放问题的解决详解

微信小程序中关于movable-view移动图片与双指缩放的实例详解

以上是AngularJS仿微信图片手势缩放代码的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn