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

前端之家收集整理的这篇文章主要介绍了AngularJS 仿微信图片手势缩放的实例前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

前言:

最近,公司做一个混合应用项目,涉及到一个图片缩放功能,类似微信那样支持touch事件。

亲测,实现方案很不错,所以放出来,和大家分享一下,希望有人能用得到。

核心思想就是用到了CSS3的transform属性, 不多说,我们看代码

/**

  • @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,.5,1) ' + duration + 's' : '';
  var matrixArray = [scale,scale,positionX,positionY];
  var matrix   = 'matrix(' + matrixArray.join(',') + ')';

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

}

return _directive;
};

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

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

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

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

猜你在找的JavaScript相关文章