返回顶部
首页 > 资讯 > 前端开发 > JavaScript >微信小程序中怎么实现拖动图片实现移动、放大、旋转
  • 245
分享到

微信小程序中怎么实现拖动图片实现移动、放大、旋转

2024-04-02 19:04:59 245人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关微信小程序中怎么实现拖动图片实现移动、放大、旋转,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。微信小程序这里提供了两个apiwx

这篇文章将为大家详细讲解有关微信小程序中怎么实现拖动图片实现移动、放大、旋转,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

微信小程序这里提供了两个api

wx.createContext() 创建并返回绘图上下文context对象

  • getActions 获取当前context上存储的绘图动作,对应wx.drawcanvas(object)中的actions

  • clearActions 清空当前的存储绘图动作

wx.drawCanvas(object) 绘制

  • canvasId 画布标识,传入的cavas-id,这里的标识可以为Number,也可以是String

  • actions 绘图动作数组,由wx.createContext创建的context,调用getActions方法导出绘图动作数组。

最近接到一个任务,在微信小程序内拖动图片组件实现移动、放大、旋转,并记录这些图片的移动位置,放大比例,旋转角度,在一个画布上生成一张图片,最后保存到手机相册。

我的具体实现思路是这样的:

 一共三个功能,可以先把功能分为图片 拖动 和图片 旋转缩放 , 把图片的缩放和旋转做在了一起。

1.图片移动:可移动的图片肯定是要动态生成的,所以不能写死,应该是个数组,具备很多的属性。

例如:(并不是我项目的真实数据)

itemList: [{
      id: 1,
      image: '1.png',//图片地址
      top: 100,//初始图片的位置 
      left: 100,
      x: 155, //初始圆心位置,可再downImg之后又宽高和初始的图片位置得出
      y: 155,
      scale: 1,//缩放比例 1为不缩放
      angle: 0,//旋转角度
      active: false //判定点击状态
    }, {
      id: 2,
      image: '2.png',
      top: 50,
      left: 50,
      x: 155,
      y: 155,
      scale: 1,
      angle: 0,
      active: false

事件绑定图片上或者图片的父级,绑定bindtouchstart  bindtouchmove事件。再bindtouchstart事件里,获取手指点击的某一个图片的点击坐标,并记录在这个图片对象的属性里面,在bindtouchmove事件里,移动的时候记录移动后的坐标,并算出俩次滑动的距离差值,追加给图片对象的left、top、x、y上,最后把本次滑动的坐标赋值给bindtouchmove事件里拿到的坐标,作为老坐标。这样就可以实现图片的滑动。

注:代码里的 items  只是我定义的一个全局变量,是一个空数组,在onLoad函数里 items = this.data.itemLits; 

这样就不会频繁的去setData,我只需要处理items,处理完之后,再this.setData({itemLits:items })

WraptouchStart: function (e) {
    for (let i = 0; i < items.length; i++) { //旋转数据找到点击的
      items[i].active = false;
      if (e.currentTarget.dataset.id == items[i].id) {
        index = i;  //记录下标
        items[index].active = true; //开启点击属性
      }
    }
    
    items[index].lx = e.touches[0].clientX; // 记录点击时的坐标值
    items[index].ly = e.touches[0].clientY;
    this.setData({  //赋值 
      itemList: items
    })
  }
  , WraptouchMove: function (e) {
    //移动时的坐标值也写图片的属性里
    items[index]._lx = e.touches[0].clientX;
    items[index]._ly = e.touches[0].clientY;
    
    //追加改动值
    items[index].left += items[index]._lx - items[index].lx; // x方向
    items[index].top += items[index]._ly - items[index].ly;  // y方向
    items[index].x += items[index]._lx - items[index].lx;
    items[index].y += items[index]._ly - items[index].ly;
    
    //把新的值赋给老的值
    items[index].lx = e.touches[0].clientX; 
    items[index].ly = e.touches[0].clientY;
    this.setData({//赋值就移动了
      itemList: items
    })
  }

2.图片的旋转和缩放,因为图片上已经有了touch事件,所以解决办法采用常规的在图片的一角添加一个控件解决这个问题,控件大致如图:

微信小程序中怎么实现拖动图片实现移动、放大、旋转

左边控件是删除按钮,右边控件则是手指按着旋转切缩放图片的控件,绑定bindtouchstart  bindtouchmove事件。

index也是设置的全局变量。

// 触摸开始事件 items是this.data.itemList的全局变量,便于赋值 所有的值都应给到对应的对象里
  touchStart: function (e) {
    //找到点击的那个图片对象,并记录
    for (let i = 0; i < items.length; i++) {
      items[i].active = false;
 
      if (e.currentTarget.dataset.id == items[i].id) {
        console.log('e.currentTarget.dataset.id', e.currentTarget.dataset.id)
        index = i;
        console.log(items[index])
        items[index].active = true;
      }
    }
     //获取作为移动前角度的坐标
    items[index].tx = e.touches[0].clientX;
    items[index].ty = e.touches[0].clientY;
    //移动前的角度
    items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty)
    //获取图片半径
    items[index].r = this.getDistancs(items[index].x, items[index].y, items[index].left, items[index].top)
  },
  // 触摸移动事件 
  touchMove: function (e) {
    //记录移动后的位置
    items[index]._tx = e.touches[0].clientX;
    items[index]._ty = e.touches[0].clientY;
    //移动的点到圆心的距离 * 因为圆心的坐标是相对与父元素定位的 ,所有要减去父元素的OffsetLeft和OffsetTop来计算移动的点到圆心的距离
    items[index].disPtoO = this.getDistancs(items[index].x, items[index].y, items[index]._tx - this.sysData.windowWidth * 0.125, items[index]._ty - 10)
 
    items[index].scale = items[index].disPtoO / items[index].r; //手指滑动的点到圆心的距离与半径的比值作为图片的放大比例
    items[index].oScale = 1 / items[index].scale;//图片放大响应的右下角按钮同比缩小
 
    //移动后位置的角度
    items[index].angleNext = this.countDeg(items[index].x, items[index].y, items[index]._tx, items[index]._ty)
    //角度差
    items[index].new_rotate = items[index].angleNext - items[index].anglePre;
 
    //叠加的角度差
    items[index].rotate += items[index].new_rotate;
    items[index].angle = items[index].rotate; //赋值
 
    //用过移动后的坐标赋值为移动前坐标
    items[index].tx = e.touches[0].clientX;
    items[index].ty = e.touches[0].clientY;
    items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty)
 
    //赋值setData渲染
    this.setData({
      itemList: items
    })
  }

页面上是这样写的:

<!-- *************操作区域************* -->
    <block wx:for="{{itemList}}" wx:key="{{item.id}}">
      <!-- 圆心坐标 <text style='position:absolute;top:{{item.y}}px;left:{{item.x}}px;width:2px;height:2px;background-color:yellow;z-index:500'></text> -->
      <view class='touchWrap' style='transfORM: scale({{item.scale}});top:{{item.top}}px;left:{{item.left}}px; '>
        <view class='imgWrap {{item.active? "touchActive":""}}' >
          <image src='{{item.image}}' data-id='{{item.id}}' style='width:{{item.width}}px;height:{{item.height}}px;' bindtouchstart='WraptouchStart' bindload='loadImg' hidden='{{!item.isload}} bindtouchmove='WraptouchMove' bindtouchend='WraptouchEnd'></image>
          <image class='x' src='../../images/x.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-id='{{item.id}}' bindtap='deleteItem'></image>
          <image class='o' src='../../images/o.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-id='{{item.id}}' bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend='touchEnd'></image>
        </view>
      </view>
    </block>
<!-- **************操作区域************ -->

这样一来就解决了微信小程序内拖动图片实现移动、放大、旋转的问题,操作也比较顺滑,也耗费我近四天的时间才把我的小程序上线,代码有点混乱,如果各位大佬有什么意见可以给我留言,我的小程序名字是:水逆转运符文,以后会持续改进。

2018/5/7补充一条生成图片时,组件的属性:

微信小程序中怎么实现拖动图片实现移动、放大、旋转

我的失误,忘了附上角度计算函数  countDeg :  


  countDeg: function (cx, cy, pointer_x, pointer_y) {
    var ox = pointer_x - cx;
    var oy = pointer_y - cy;
    var to = Math.abs(ox / oy);
    var angle = Math.atan(to) / (2 * Math.PI) * 360;//鼠标相对于旋转中心的角度
    console.log("ox.oy:", ox, oy)
    if (ox < 0 && oy < 0)//相对在左上角,第四象限,js中坐标系是从左上角开始的,这里的象限是正常坐标系 
    {
      angle = -angle;
    } else if (ox <= 0 && oy >= 0)//左下角,3象限 
    {
      angle = -(180 - angle)
    } else if (ox > 0 && oy < 0)//右上角,1象限 
    {
      angle = angle;
    } else if (ox > 0 && oy > 0)//右下角,2象限 
    {
      angle = 180 - angle;
    }
 
    return angle;
  }

计算触摸点到圆心的距离:

getDistancs(cx, cy, pointer_x, pointer_y) {
    var ox = pointer_x - cx;
    var oy = pointer_y - cy;
    return Math.sqrt(
      ox * ox + oy * oy
    );
  }

点击配件时的事件(因为再我测试在canvas中,图片不能是网络路径,所以需要下载): 【18/6/22】

tpDownload: function(data, isDownload) { //data为组件的参数,isDownload判断是否为https网络图片来判断是否需要下载
    if (yy < 0) { //改变生成图片时的位置
      speed = -speed
    }
    if (yy > 300) {
      speed = -speed
    }
    yy += speed;
    let _this = this;
    let newTpdata = {};
    newTpdata.id = data.id;
    newTpdata.itemid = data.itemid;
    newTpdata.top = 100 + yy;
    newTpdata.left = 100;
    newTpdata.width = _this.sysData.windowWidth / 4;
    newTpdata.scale = 1;
    newTpdata.angle = 0;
    newTpdata.rotate = 0;
    newTpdata.active = true;
    for (let i = 0; i < items.length; i++) {
      items[i].active = false;
    }
    if (isDownload) {
      wx.downloadFile({
        url: data.image,
        success: res => {
          newTpdata.image = res.tempFilePath;
          items.push(newTpdata);
          _this.setData({
            itemList: items
          })
          wx.hideLoading();
        }
      })
    } else {
      newTpdata.image = data.image;
      items.push(newTpdata);
      _this.setData({
        itemList: items
      })
      wx.hideLoading();
    }
  }

我的项目中生成canvas用到的代码 (绘图是通过保存按钮触发)

save: function() {
    this.setData({
      showCanvas: true,
      canvasHeight: this.sysData.windowHeight * 0.85
    })
    let obj = this.data.item;
    
    let canvasWidth = this.sysData.windowWidth * this.data.canvasPre / 100; //
    
    let prop = (canvasWidth * num) / (this.sysData.windowWidth * 0.75);
    maskCanvas.save();
    maskCanvas.beginPath();
    //一张白图
    maskCanvas.setFillStyle('#fff');
    maskCanvas.fillRect(0, 0, this.sysData.windowWidth, this.data.canvasHeight)
    maskCanvas.closePath();
    maskCanvas.stroke();
    //图头像
    let image = {
      w: canvasWidth * num * 0.287,
      h: canvasWidth * num * 0.287,
      r: canvasWidth * num * 0.287 / 2
    };
    //画背景 hCw 为 1.7781 背景图的高宽比
    maskCanvas.drawImage(obj.bgImg, canvasWidth * (1 - num) / 2, 10, canvasWidth * num, canvasWidth * num * hCw)
    //画底图
    maskCanvas.drawImage('../../images/xcx.png', canvasWidth * (1 - num) / 2, canvasWidth * num * hCw + 15, canvasWidth * num, this.data.canvasHeight * 0.15)
    //画原
    maskCanvas.save();
    maskCanvas.beginPath();
    maskCanvas.arc(canvasWidth / 2, canvasWidth * num * hCw * obj.userTop / 100 + 10 + image.w / 2, image.r, 0, Math.PI * 2, false);
    // maskCanvas.stroke()
    maskCanvas.clip(); //截取
    //画头像
    maskCanvas.drawImage(obj.avatarUrl, (canvasWidth - image.w) / 2, canvasWidth * num * hCw * obj.userTop / 100 + 10, image.w, image.h)
    maskCanvas.closePath();
    maskCanvas.restore();
    //绘制文字
    maskCanvas.save();
    maskCanvas.beginPath();
    let fontSize = this.sysData.screenWidth / 375 * 15;
    let textColor = obj.color || '#000';
    maskCanvas.setFontSize(parseInt(fontSize) * prop)
    maskCanvas.setFillStyle(textColor)
    maskCanvas.setTextAlign('center')
    maskCanvas.fillText(obj.nickName, canvasWidth / 2, obj.titleTop / 100 * canvasWidth * num * hCw + 10 * 0.9 * prop + fontSize * prop);
    maskCanvas.closePath();
    maskCanvas.stroke();
    
    //画组件
    items.forEach((currentValue,index)=>{
      maskCanvas.save();
      maskCanvas.translate(canvasWidth * (1 - num) / 2, 10);
      maskCanvas.beginPath();
      maskCanvas.translate(currentValue.x * prop, currentValue.y * prop); //圆心坐标
      maskCanvas.rotate(currentValue.angle * Math.PI / 180); // 旋转值
      maskCanvas.translate(-(currentValue.width * currentValue.scale * prop / 2), -(currentValue.height * currentValue.scale * prop / 2))
      maskCanvas.drawImage(currentValue.image, 0, 0, currentValue.width * currentValue.scale * prop, currentValue.height * currentValue.scale * prop);
      maskCanvas.restore();
    })
    maskCanvas.draw(false, (e)=> {
      wx.canvasToTempFilePath({
        canvasId: 'maskCanvas',
        success: res => {
          this.setData({
            canvasTemImg: res.tempFilePath
          })
        }
      }, this)
    })
  }

关于微信小程序中怎么实现拖动图片实现移动、放大、旋转就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 微信小程序中怎么实现拖动图片实现移动、放大、旋转

本文链接: https://lsjlt.com/news/65426.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 微信小程序中怎么实现拖动图片实现移动、放大、旋转
    这篇文章将为大家详细讲解有关微信小程序中怎么实现拖动图片实现移动、放大、旋转,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。微信小程序这里提供了两个APIwx...
    99+
    2024-04-02
  • 实现微信小程序中的图片旋转效果
    实现微信小程序中的图片旋转效果,需要具体代码示例微信小程序是一种轻量级的应用程序,为用户提供了丰富的功能和良好的用户体验。在小程序中,开发者可以利用各种组件和API来实现各种效果。其中,图片旋转效果是一种常见的动画效果,可以为小程序增添趣味...
    99+
    2023-11-21
    微信小程序 实现 图片旋转
  • 微信小程序怎么实现图片拖拽排序
    这篇文章主要介绍“微信小程序怎么实现图片拖拽排序”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“微信小程序怎么实现图片拖拽排序”文章能帮助大家解决问题。首先来看效果对于组件内部来说。笔者提供了一个参数...
    99+
    2023-06-29
  • 实现微信小程序中的图片放大缩小效果
    实现微信小程序中的图片放大缩小效果,需要具体代码示例在微信小程序中实现图片的放大缩小效果是一个常见需求,可以通过使用WXSS样式和WXSS样式来实现。下面将介绍具体的代码示例。1.在wxml文件中编写图片和相关的按钮组件:<view&...
    99+
    2023-11-21
  • 微信小程序如何实现图片双滑缩放大小
    这篇文章主要介绍了微信小程序如何实现图片双滑缩放大小 ,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在做小程序开发的过程中,后端传来一张图片地图,需要实现双手指滑动,使图片缩...
    99+
    2023-06-26
  • android Matrix实现图片随意放大缩小或拖动
    本文实例为大家分享了android Matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下 step1:新建一个项目DragAndZoom,并准备一张照片放在r...
    99+
    2022-06-06
    图片 matrix Android
  • 微信小程序实现裁剪图片大小
    本文实例为大家分享了微信小程序实现裁剪图片大小的具体代码,供大家参考,具体内容如下 效果图 .wxml <button bindtap="uploadtap">上传图片...
    99+
    2024-04-02
  • 微信小程序图片上传组件实现图片拖拽排序
    目录引言首先来看效果组件设计使用方式总结引言 图片上传组件是一个组件库目前来看必不可少的功能了。笔者近日给自己开源的toy工具库也添加了这一功能。相比原生和大部分组件库来说,它不仅支...
    99+
    2024-04-02
  • Android实现图片反转、翻转、旋转、放大和缩小
    ********************************************************************** android 实现图片的翻转 ...
    99+
    2022-06-06
    图片 反转 Android
  • Android实现旋转,放大,缩小图片的方法
    本文实例讲述了Android实现旋转,放大,缩小图片的方法。分享给大家供大家参考,具体如下: 项目中需要做到一个预览图片的功能 最初设想自定义个一个view,在onDraw中用...
    99+
    2022-06-06
    小图 方法 图片 Android
  • 使用微信小程序实现图片拖拽功能
    使用微信小程序实现图片拖拽功能引言:随着微信小程序的流行,更多的开发者开始探索小程序的各种功能和特性。其中,实现图片拖拽功能是一项常见的需求。本文将介绍如何使用微信小程序的API和组件,实现图片拖拽的效果,并提供具体的代码示例。一、设计思路...
    99+
    2023-11-21
    图片 微信小程序 拖拽
  • 微信小程序实现自动回复图片消息
    目录前提实现备注前提 小程序已经开通了“云开发”功能 在微信开发者工具中打开“云开发”,点“设置”,点击&ld...
    99+
    2023-01-17
    小程序自动回复 微信小程序自动回复 小程序自动回复图片
  • 微信小程序实现通过双向滑动缩放图片大小的示例分析
    这篇文章主要介绍了微信小程序实现通过双向滑动缩放图片大小的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。本文实例讲述了微信小程序实现...
    99+
    2024-04-02
  • 微信小程序怎么实现旋转木马效果
    这篇文章主要介绍“微信小程序怎么实现旋转木马效果 ”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“微信小程序怎么实现旋转木马效果 ”文章能帮助大家解决问题。文章涉及技术点微信小程序原生Swiper控件...
    99+
    2023-06-26
  • Android实现对图片放大、平移和旋转的功能
    先来看看要实现的效果图 在讲解中,需要大家提前了解一些关于图片绘制的原理的相关知识。 关于实现的流程      1、自定义View ...
    99+
    2022-06-06
    图片 Android
  • 微信小程序如何实现裁剪图片大小
    这篇文章主要介绍“微信小程序如何实现裁剪图片大小”,在日常操作中,相信很多人在微信小程序如何实现裁剪图片大小问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”微信小程序如何实现裁剪图片大小”的疑惑有所帮助!接下来...
    99+
    2023-06-30
  • 微信小程序实现卡片层叠滑动
    本文实例为大家分享了微信小程序实现卡片层叠滑动的具体代码,供大家参考,具体内容如下 实现效果: 1.左右滑动时,向相应方向移动一个卡片位置;2.点击某一项时,将点击项位置移动到中间...
    99+
    2024-04-02
  • 微信小程序如何实现选择图片和放大预览图片功能
    这篇文章给大家分享的是有关微信小程序如何实现选择图片和放大预览图片功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。视频中,老师也是看着官方文档,为学生们讲解,微信提供了系统的方...
    99+
    2024-04-02
  • 微信小程序实现上传图片
    本文实例为大家分享了微信小程序实现上传图片的具体代码,供大家参考,具体内容如下 //wxml <button class='button' bingtap="uploadSom...
    99+
    2024-04-02
  • 微信小程序实现图片上传
    微信小程序实现图片上传 最近做了个小程序,涉及到了图片上传的功能,今天给大家详细介绍下如何实现小程序图片上传,话不多说先上代码 首先是静态布局和样式部分 .wxml代码部分 ...
    99+
    2023-09-07
    微信小程序 小程序 微信
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作