react移动端svg等图片拖拽缩放

谁借莪1个温暖的怀抱¢ 2021-09-08 15:24 710阅读 0赞

react移动端图片缩放拖拽

  1. 使用es6类的方法实现
  2. /**
  3. *定义svg,png,jpeg图片移动端缩放功能
  4. *
  5. * 可拖拽,看缩放
  6. let zoomEl = document.getElementById('zoomEl');
  7. let zoom = new Zoom({
  8. el:zoomEl,
  9. options:{'top': zoomEl.offsetTop+50, 'left': zoomEl.offsetLeft+50, 'width': 400, 'height': 400 }
  10. });
  11. zoom.setScale(1)
  12. * @class Zoom
  13. */
  14. class Zoom{
  15. /**
  16. *Creates an instance of Zoom.
  17. * @param {el,options:{top,left,width,height}} ops 参数配置
  18. * @memberof Zoom
  19. */
  20. constructor(ops){
  21. //参数配置
  22. this.ops = Object.assign({
  23. minScale:1,
  24. maxScale:3,
  25. top:50,
  26. left:50,
  27. },ops.options)
  28. //展示的存放容器
  29. this.el = ops.el;
  30. this.lastSapce = 0;
  31. this.touchState = 0;
  32. this.lastPoint = null;
  33. this.targetPoint = null;
  34. //放大缩小的倍数 当前缩放倍数
  35. this.minScale = this.ops.minScale || 1;
  36. this.maxScale = this.ops.maxScale || 10;
  37. // dom 的尺寸参数
  38. this.width = this.ops.width;
  39. this.height = this.ops.height;
  40. this.top = this.ops.top;
  41. this.left = this.ops.left;
  42. this.scale = 1;
  43. // 初始位置以及初始宽高
  44. this.originTop = this.ops.top;
  45. this.originLeft = this.ops.left;
  46. this.originW = this.width;
  47. this.originH = this.height;
  48. // 图片中心点
  49. this.centerX = this.left + this.originW/2;
  50. this.centerY = this.top + this.originH/2;
  51. this.el.style.position = "absolute";
  52. this.init();
  53. }
  54. /**
  55. *初始化数据
  56. *
  57. * @memberof Zoom
  58. */
  59. init(){
  60. this.el.addEventListener('touchmove',this.touchmoveHandler);
  61. this.el.addEventListener('touchstart',this.touchmoveHandler);
  62. this.el.addEventListener('touchend',this.touchEndHandler);
  63. this.el.addEventListener('touchcancel',this.touchEndHandler);
  64. this.el.addEventListener('touchstart',this.dbclickHandler);
  65. this.el.zoom = this;
  66. }
  67. getTouches(event){
  68. let touches = event.touches;
  69. if(!touches){
  70. touches = event.originalEvent.touches;
  71. }
  72. return touches;
  73. }
  74. getTouchsDistance(t1,t2){
  75. let dx = parseInt(t1.pageX - t2.pageX);
  76. let dy = parseInt(t1.pageY - t2.pageY);
  77. let d = Math.pow((dx*dx+dy+dy),0.8);
  78. return d.toFixed(5);
  79. }
  80. restView(){
  81. this.el.style.width = this.width +"px";
  82. this.el.style.height = this.height +"px";
  83. this.el.style.top = this.top +"px";
  84. this.el.style.left = this.left +"px";
  85. }
  86. dbclickHandler(event){
  87. event.stopPropagation();
  88. event.preventDefault();
  89. let el = event.currentTarget;
  90. let zoom = el.zoom;
  91. let time = new Date(event.timeStamp).getTime();
  92. let touchs = zoom.getTouches(event);
  93. if (touchs.length == 1) {
  94. if (!el.lastClickTime) {
  95. el.lastClickTime = time;
  96. }else{
  97. if (time - el.lastClickTime < 300) {
  98. el.lastClickTime = 0;
  99. if (zoom.scale != 1) {
  100. zoom.setScale(1);
  101. }else if(zoom.scale == 1){
  102. zoom.setScale(2);
  103. }
  104. }else{
  105. el.lastClickTime = time;
  106. }
  107. }
  108. }
  109. zoom.touchStartTime = new Date().getTime();
  110. return false;
  111. }
  112. drage(touch){
  113. if (this.lastPoint == null) {
  114. this.lastPoint = {
  115. x:touch.pageX,
  116. y:touch.pageY,
  117. }
  118. }else{
  119. let dx = parseInt(touch.pageX - this.lastPoint.x);
  120. let dy = parseInt(touch.pageY - this.lastPoint.y);
  121. this.lastPoint.x = touch.pageX;
  122. this.lastPoint.y = touch.pageY;
  123. this.left += dx;
  124. this.top += dy;
  125. this.setTransform(false);
  126. }
  127. }
  128. zoom(touchs){
  129. this.lastPoint = null;
  130. let t1 = touchs[0];
  131. let t2 = touchs[1];
  132. let x1 = t1.pageX;
  133. let x2 = t2.pageX;
  134. let y1 = t1.pageY;
  135. let y2 = t2.pageY;
  136. let d = this.getTouchsDistance(t1,t2);
  137. if (this.touchState == 0) {
  138. this.lastSapce = d;
  139. this.touchState = 1;
  140. this.pointX = (x2 + (x1 - x2) / 2 - this.left)/this.scale;
  141. this.pointY = (y2 + (y1 - y2) / 2 - this.top)/this.scale;
  142. }else if(this.touchState == 1){
  143. let scaleChange = ((d / this.lastSapce) - 1) * 2;
  144. let scale = this.scale + scaleChange / 2;
  145. this.setScale(scale,this.pointX,this.pointY);
  146. this.lastSapce = d;
  147. }
  148. }
  149. touchmoveHandler(event){
  150. event.stopPropagation();
  151. event.preventDefault();
  152. let el = event.currentTarget;
  153. let zoom = el.zoom;
  154. let touchs = zoom.getTouches(event);
  155. if (touchs.length == 1) {
  156. zoom.drage(touchs[0]);//拖动处理
  157. }else if (touchs.length >= 2) {
  158. zoom.lastPoint = null;//终止拖动事件
  159. zoom.zoom(touchs);//缩放处理
  160. }
  161. return false;
  162. }
  163. touchEndHandler(event){
  164. let zoom = event.currentTarget.zoom;
  165. zoom.touchState = 0;
  166. zoom.lastPoint = null;
  167. zoom.lastSapce = 0;
  168. let minSpace = 20;
  169. let parentWidth = zoom.el.parentElement.offsetWidth;
  170. let parentHight =zoom.el.parentElement.offsetHeight;
  171. let scale = zoom.scale;
  172. if(scale < zoom.minScale){
  173. scale = zoom.minScale;
  174. }
  175. if(scale > zoom.maxScale){
  176. scale = zoom.maxScale;
  177. }
  178. if(scale != zoom.scale){
  179. zoom.preSetScale(scale,zoom.lastPointX,zoom.lastPointY);
  180. }
  181. if((zoom.left + zoom.width) < minSpace){
  182. zoom.left = - zoom.width + minSpace;
  183. }
  184. if(zoom.left >= (parentWidth - minSpace)){
  185. zoom.left = parentWidth - minSpace;
  186. }
  187. if((zoom.top + zoom.height) < minSpace){
  188. zoom.top = - zoom.height + minSpace;
  189. }
  190. if(zoom.top >= (parentHight - minSpace)){
  191. zoom.top = parentHight - minSpace;
  192. }
  193. zoom.setTransform(true);
  194. return;
  195. }
  196. setTransform(needAnimation,originX,originY){
  197. let distanceX = this.left - this.originLeft;
  198. let distanceY = this.top - this.originTop;
  199. let scale = this.scale;
  200. originX = originX == undefined ? (this.originTop + 'px') : originX;
  201. originY = originY == undefined ? (this.originLeft + 'px') : originY;
  202. this.el.style.transformOrigin = 'left top';
  203. this.el.style.transform = 'matrix('+scale+',0,0,'+scale+','+distanceX+','+distanceY+')';
  204. if(needAnimation == true){
  205. this.el.style.transition = 'all .3s ease-in-out 0s'
  206. }else{
  207. this.el.style.transition = ''
  208. }
  209. }
  210. destroy(){
  211. this.el.removeEventListener('touchmove',this.touchmoveHandler);
  212. this.el.removeEventListener('touchstart',this.touchmoveHandler);
  213. this.el.removeEventListener('touchend',this.touchEndHandler);
  214. this.el.removeEventListener('touchcancel',this.touchEndHandler);
  215. this.el.zoom = null;
  216. }
  217. setScale(scale,pointX,pointY){
  218. this.preSetScale(scale,pointX,pointY);
  219. this.setTransform(false);
  220. }
  221. preSetScale(scale,pointX,pointY){
  222. if (scale < 0.5) {
  223. scale = 0.5;
  224. }
  225. if (pointX ==undefined) {
  226. this.left = this.centerX - this.originW / 2 - this.originW/2*(scale - 1);
  227. this.top = this.centerY - this.originH / 2 - this.originH/2*(scale - 1);
  228. this.width = scale * this.originW;
  229. this.height = scale * this.originH;
  230. this.scale = scale;
  231. }else{
  232. this.width = scale * this.originW;
  233. this.height = scale * this.originH;
  234. this.left = this.left - pointX * (scale - this.scale);
  235. this.top = this.top - pointY * (scale - this.scale);
  236. this.lastPointX = pointX;
  237. this.lastPointY = pointY;
  238. this.scale = scale;
  239. }
  240. }
  241. }
  242. export default Zoom;

发表评论

表情:
评论列表 (有 0 条评论,710人围观)

还没有评论,来说两句吧...

相关阅读

    相关 vue3.0组件

    本人开发vue3.0拖拽缩放组件,持续更新中 (最新版本 0.3.0 支持 拖拽 、缩放、旋转、移动辅助线、激活和取消激活、复制粘贴、删除、键盘移动等功能,预计加入撤回操作、多