起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10968|回复: 2

[分享] js对元素进行缩放、拖拽、旋转

[复制链接]

165

主题

626

帖子

1160

积分

金牌会员

Rank: 6Rank: 6

积分
1160
QQ
发表于 2018-6-1 17:57:43 | 显示全部楼层 |阅读模式
本帖最后由 邹胖胖 于 2018-6-1 18:33 编辑
  1. /** 打开 **/
  2.         Model.prototype.openPinch = function(){
  3.                 var id = this.getIDByXID("mathDivXid");/** 要操作的元素 **/
  4.         
  5.         var reqAnimationFrame = (function () {
  6.                 return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
  7.                     window.setTimeout(callback, 1000 / 60);
  8.                 };
  9.             })();
  10.         
  11.             var el = document.querySelector("#" + id);
  12.         
  13.             var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2);
  14.             var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2);
  15.         
  16.             var ticking = false;
  17.             var transform;   //图像效果
  18.             var timer;
  19.                 var initAngle = 0;  //旋转角度
  20.                 var initScale = 1;  //放大倍数
  21.                 var currentScale;
  22.         
  23.             this.mc = new Hammer.Manager(el);   //用管理器  可以同时触发旋转 拖拽  移动
  24.                 //var mc = new Hammer(el);              //旋转和移动互斥
  25.                 var mc = this.mc;
  26.                 /**
  27.                         ev.srcEvent.type  touchstart  touchend touchmove
  28.                         ev.deltaX  手势移动位移变量  
  29.                 */
  30.                 mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));  
  31.                 mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan'));
  32.             mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
  33.                 //结束时做一些处理
  34.             mc.on("hammer.input", function(ev) {
  35.                 if(ev.isFinal) {
  36.                                 console.log(START_X + "  " + transform.translate.x + "   " + ev.deltaX + "  " + ev.deltaY);
  37.                                 START_X = transform.translate.x ;
  38.                                 START_Y = transform.translate.y ;
  39.                 }
  40.                         
  41.             });
  42.             
  43.             mc.on("panstart panmove", onPan);
  44.             //mc.on("rotatestart rotatemove rotateend", onRotate);//旋转
  45.             mc.on("pinchstart pinchmove", onPinch);
  46.             
  47.                 /**
  48.                         第二次进入拖拽时  delta位移重置
  49.                         移动时 初始位置startxy不动。delta增加
  50.                 */
  51.                 function onPan(ev){
  52.                         if(!ev.isFinal) {
  53.                                 el.className = '';
  54.                                 console.log(START_X + "  " + START_Y + " |  " + ev.deltaX + "  " + ev.deltaY);
  55.                                 transform.translate = {
  56.                                         x: START_X + ev.deltaX,
  57.                                         y: START_Y + ev.deltaY
  58.                                 };
  59.                                 requestElementUpdate();
  60.                         }           
  61.                 }
  62.                
  63.                 function onPinch(ev){
  64.                         if(ev.type == 'pinchstart') {
  65.                                 initScale = transform.scale || 1;
  66.                         }
  67.                         el.className = '';
  68.                         transform.scale = initScale * ev.scale;
  69.                         
  70.                         /** 设置最大倍数为2,最小倍数为1 **/
  71.                         currentScale = ev.scale - 1;
  72.             currentScale = initScale + currentScale;
  73.             currentScale = currentScale > 4 ? 4 : currentScale;
  74.             currentScale = currentScale < 1 ? 1 : currentScale;
  75.             currentScale = currentScale < 1 ? 1 : currentScale;
  76.                         transform.scale = currentScale;
  77.                         
  78.                         requestElementUpdate();        
  79.                 }
  80.         
  81.                 /** 旋转相关 **/
  82.                 var preAngle = 0 ;
  83.                 var tempAngleFlag =0;
  84.                 var deltaAngle = 0;        
  85.                 var startRotateAngle = 0;
  86.                
  87.                 function onRotate(ev) {
  88.                         //点下第二个触控点时触发
  89.                 if(ev.type == 'rotatestart') {                           
  90.                                 startRotateAngle =  ev.rotation ;                        
  91.                                 tempAngleFlag = 0 ;
  92.                 }        
  93.                         if(ev.type == 'rotatemove'){
  94.                                 if(tempAngleFlag == 0){
  95.                                         preAngle = startRotateAngle;
  96.                                         tempAngleFlag ++;
  97.                                 }else{                                
  98.                                         deltaAngle = ev.rotation - preAngle;
  99.                                         el.className = '';
  100.                                         transform.rz = 1;  //非0  垂直xy轴
  101.                                         transform.angle = initAngle + deltaAngle;                                                                        
  102.                                         requestElementUpdate();        
  103.                                 }
  104.                         }
  105.                                 
  106.                         //旋转结束  记录当前图片角度        
  107.                         if(ev.type =='rotateend'){
  108.                                 initAngle = transform.angle;
  109.                         }        
  110.             }
  111.         
  112.             function updateElementTransform() {
  113.                 var value = [
  114.                 'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)',
  115.                 'scale(' + transform.scale + ', ' + transform.scale + ')',
  116.                 'rotate3d('+ transform.rx +','+ transform.ry +','+ transform.rz +',' + transform.angle + 'deg)'
  117.                 ];
  118.         
  119.                 value = value.join(" ");
  120.                 el.style.webkitTransform = value;
  121.                 el.style.mozTransform = value;
  122.                 el.style.transform = value;
  123.                 ticking = false;
  124.             }
  125.         
  126.             function requestElementUpdate() {
  127.                 if(!ticking) {
  128.                     reqAnimationFrame(updateElementTransform);
  129.                     ticking = true;
  130.                 }
  131.             }
  132.         
  133.             function logEvent(str) {
  134.             }
  135.                
  136.                 /**
  137.                         初始化设置
  138.                 */
  139.             function resetElement() {
  140.                 el.className = 'animate';
  141.                          transform = {
  142.                     translate: { x: START_X, y: START_Y },
  143.                     scale: 1,
  144.                     angle: 0,
  145.                     rx: 0,
  146.                     ry: 0,
  147.                     rz: 0
  148.                 };
  149.                 requestElementUpdate();
  150.             }
  151.                
  152.             resetElement();
  153.         };
  154.         
  155.         /** 关闭 **/
  156.         Model.prototype.offPinch = function(){
  157.             this.mc.destroy();
  158.         };
复制代码
使用系统提供的touch.js,会出现缩放后退拽不稳定,会闪动的情况,所以我找到了hammer.js。这是我试验的众多版本中最稳定的一个。用起来非常流畅;
页面引入hammer.js,调用openPinch()打开对元素的缩放、拖拽、旋转;调用offPinch()方法关闭操作,所以在openPinch中每次都要重新给全局变量this.mc赋值

hammer.min.rar

7.16 KB, 下载次数: 228

评分

参与人数 1威望 +15 收起 理由
ysk007 + 15 很给力!

查看全部评分

发表于 2018-6-13 13:22:10 | 显示全部楼层
压缩文件是min.js吗??  下载解压失败了,可以压缩为zip文件再上传

另外建议,提供一个完整的demo案例发来,方便大家参考!
qq:1912779713
WeX5教程--WeX5下载
回复 支持 反对

使用道具 举报

165

主题

626

帖子

1160

积分

金牌会员

Rank: 6Rank: 6

积分
1160
QQ
 楼主| 发表于 2018-6-13 18:34:30 | 显示全部楼层
本帖最后由 邹胖胖 于 2018-6-13 18:43 编辑
liangyongfei 发表于 2018-6-13 13:22
压缩文件是min.js吗??  下载解压失败了,可以压缩为zip文件再上传

另外建议,提供一个完整的demo案例发 ...

好的,demo见附件。
要操作的元素不限于图片,我测试过div、canvas等,都可以使用;
另外,使用这个插件要打包apk安装到手机上使用,在浏览器上貌似只能拖拽

hamDemo.zip

2.19 MB, 下载次数: 267

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-5-14 15:36 , Processed in 0.062780 second(s), 27 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表