全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

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


# AngularJS  # 手势缩放  # 手势缩放的实现方法  # 手势缩放的实例  # angularjs实现简单的购物车功能  # 详解angularjs popup-table 弹出框表格指令  # AngularJs 延时器、计时器实例代码  # 详解angularJS+Ionic移动端图片上传的解决办法  # 基于AngularJS的简单使用详解  # AngularJS 打开新的标签页实现代码  # Angularjs实现上传图片预览功能  # 多个  # 如有  # 只需  # 要在  # 希望能  # 很简单  # 很不错  # 做一个  # 该如何  # 当我们  # 涉及到  # 谢谢大家  # 多说  # 大家分享  # 疑问请  # maxScale  # initialScale  # relativeScale  # isNaN  # lt 


相关文章: 如何在服务器上三步完成建站并提升流量?  如何快速辨别茅台真假?关键步骤解析  C++时间戳转换成日期时间的步骤和示例代码  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  深圳网站制作案例,网页的相关名词有哪些?  网站制作壁纸教程视频,电脑壁纸网站?  建站之星下载版如何获取与安装?  如何在腾讯云服务器上快速搭建个人网站?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  h5在线制作网站电脑版下载,h5网页制作软件?  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  深圳网站制作的公司有哪些,dido官方网站?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  建站之星如何配置系统实现高效建站?  江苏网站制作公司有哪些,江苏书法考级官方网站?  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  如何快速完成中国万网建站详细流程?  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  建站之星如何取消后台验证码生成?  宝塔建站无法访问?如何排查配置与端口问题?  唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?  制作企业网站建设方案,怎样建设一个公司网站?  建站之星安装后界面空白如何解决?  如何通过免费商城建站系统源码自定义网站主题与功能?  小型网站制作HTML,*游戏网站怎么搭建?  官网网站制作腾讯审核要多久,联想路由器newifi官网  网站插件制作软件免费下载,网页视频怎么下到本地插件?  如何快速搭建个人网站并优化SEO?  建站之星CMS建站配置指南:模板选择与SEO优化技巧  建站主机解析:虚拟主机配置与服务器选择指南  如何生成腾讯云建站专用兑换码?  网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  IOS倒计时设置UIButton标题title的抖动问题  个人网站制作流程图片大全,个人网站如何注销?  ,在苏州找工作,上哪个网站比较好?  如何在景安服务器上快速搭建个人网站?  建站主机SSH密钥生成步骤及常见问题解答?  如何在阿里云服务器自主搭建网站?  如何快速搭建安全的FTP站点?  网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?  网站按钮制作软件,如何实现网页中按钮的自动点击?  ,柠檬视频怎样兑换vip?  如何自定义建站之星模板颜色并下载新样式?  上海网站制作网站建设公司,建筑电工证网上查询系统入口?  网站制作大概多少钱一个,做一个平台网站大概多少钱?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  移民网站制作流程,怎么看加拿大移民官网? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。