这篇文章主要介绍了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 src="assets/images/floorplan.jpeg" ng-pinch-zoom>

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

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

最新资讯
SpaceX首张船票已出 日(J)本(P)富豪成史上首个私人月球游客

SpaceX首张船票已出

去找嫦娥的竟然是一位日(J)本(P)人。
苹果Safari浏览器出漏洞:可能导致iOS/macOS崩溃重启

苹果Safari浏览器出漏

利用WebKit这一漏洞,攻击者可以让设备加载植入特定CSS
没有人的朋友圈

没有人的朋友圈

微信诞生7年,一方面我们努力的增加微信好友,努力给朋友
朋友圈力推微视,“头腾”大战仍在延续

朋友圈力推微视,“头腾

头腾大战延续?
这届iPhone若大卖,苹果来年还能再涨一波?

这届iPhone若大卖,苹果

越贵越买将给予苹果更为膨胀的心态,那么iPhone的价格走
最新文章
详解NodeJs开发微信公众号

详解NodeJs开发微信公

本篇文章给大家分享了NodeJs开发微信公众号的相关技术
详解webpack4多入口、多页面项目构建案例

详解webpack4多入口、

这篇文章主要介绍了详解webpack4多入口、多页面项目构
Vue仿支付宝支付功能

Vue仿支付宝支付功能

这篇文章主要介绍了Vue仿支付宝支付功能,非常不错,具有
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】

jquery ajaxfileuplod

点击一次上传, 当上传操作结束后才能操作界面,实现方式
JavaScript继承与多继承实例分析

JavaScript继承与多继

这篇文章主要介绍了JavaScript继承与多继承,结合实例
使用javascript做在线算法编程

使用javascript做在线

这篇文章主要介绍了使用javascript做在线算法编程的相