手机版

微信小程序中拖动图片移动、放大、旋转的方法

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

屏幕就像一个数学坐标轴,在第四象限,以屏幕左上角为点,X轴向右正,向左负,Y轴正,负(这和数学是相反的)。以点为基点,在点的上下各画一个50宽100高的矩形,演示画布的基本用法

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

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

获取绘图操作的操作清除当前上下文中的操作,并清除wx.drawCanvas(对象)中的操作以清空当前存储的绘图操作wx.drawCanvas(对象)进行绘图

CanvasId画布Id,传入的cavas-id,其中id可以是Number或String动作绘制动作数组,以及由wx.createContext创建的上下文调用getActions方法导出绘制动作数组。最近接到一个任务,在微信小程序中拖动图片组件进行移动、放大、旋转,记录这些图片的移动位置、放大比例、旋转角度,在画布上生成一张图片,最后保存到手机相册中。

我的具体实现思路如下:

总共有三个功能,可以分为图像拖动和图像旋转缩放,图像缩放和旋转是一起完成的。

1.画面移动:动图必须是动态生成的,所以不能写死。它们应该是具有许多属性的数组。

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

Itemlist: [{id: 1,image:' 1.png ',//图片地址top: 100,///初始图片位置left: 100,x: 155,//初始中心位置,然后downImg,宽度和高度以及初始图片位置可以得到y: 155。Scale: 1,//scale 1未缩放角度: 0,//旋转角度active 3360 false//确定点击状态},{id: 2,image:' 2.png ',top3360 50,left: 50,x: 155,Y: 155,scale 3: 1,angle 3:active: false事件绑定图片或的父级在bindtouchstart事件中,获取手指点击某个图片的点击坐标,并记录在该图片对象的属性中。在bindtouchmove事件中,记录移动后的坐标,计算两张幻灯片之间的距离差,并将其添加到图片对象的左侧、顶部、x和y。最后,此幻灯片的坐标被分配给在bindtouchmove事件中获得的坐标,作为旧坐标。这样,图片就可以滑动了。

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

这样,我就不会经常去setData了。我只需要处理物品,然后是这个。setdata ({itemlits: items})。

包装触摸开始:函数(e) {对于(让I=0;一。项目。长度;i ) { //旋转数据找到点击的项目[i].active=falseif(e . CurrentTarget。数据集。id==items[I].id){ index=I;//记录下标项目[索引]。active=true//开启点击属性} }项[索引]。LX=e . touch[0]。clientX//记录点击时的坐标值项目[索引]。ly=e . touch[0]。clientYthis.setData({ //赋值itemList: items }) },WraptouchMove:函数(e) { //移动时的坐标值也写图片的属性里项目[索引]。_ LX=e . touch[0]。clientX项目[索引]。_ ly=e . touch[0]。clientY//追加改动值项目[索引]。左=项目[索引]。_lx -项目[索引]。LX;//x方向项目[索引]。top=项目[索引]。_ly -项目[索引].ly;//y方向项目[索引]。x=项目[索引]。_lx -项目[索引]。LX;项目[索引]。y=项目[索引]。_ly -项目[索引].ly;//把新的值赋给老的值项目[索引]。LX=e . touch[0]。clientX项目[索引]。ly=e . touch[0]。clientYthis.setData({//赋值就移动了itemList: items }) }2 .图片的旋转和缩放,因为图片上已经有了触控事件,所以解决办法采用常规的在图片的一角添加一个控件解决这个问题,控件大致如图:

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

指数也是设置的全局变量。

//触摸开始事件项目是this.data.itemList的全局变量,便于赋值所有的值都应给到对应的对象里touchStart:功能(e) { //找到点击的那个图片对象,并记录用于(设I=0;一。项目。长度;i ) { items[i].active=falseif(e . CurrentTarget。数据集。id==items[I].id){控制台。日志(' e.currentTarget.dataset.id ',e.currentTarget。数据集。id)索引=我;控制台。日志(项目[索引])项目[索引].active=true} } //获取作为移动前角度的坐标项目[索引]。tx=e .触摸[0].clientX项目[索引]。ty=e .触摸[0].clientY//移动前的角度项目[索引]。anglePre=这个。计数度数(项目[索引]).x,项目[索引]。y,项目[索引]。tx,项目[索引]。ty) //获取图片半径项目[索引]。r=这个。getdistants(items[index]).x,项目[索引]。y,项目[索引]。左侧,项目[索引]。top) },//触摸移动事件touchMove:函数(e) { //记录移动后的位置项目[索引]。_ tx=e .触摸[0]。clientX项目[索引]。_ ty=e . touch[0]。clientY//移动的点到圆心的距离* 因为圆心的坐标是相对与父元素定位的,所有要减去父元素的获取和偏移来计算移动的点到圆心的距离项目[索引]。disPtoO=这个。获取距离(项目[索引]).x,项目[索引]。y,项目[索引]。_ tx-这个。SysDATa。窗口宽度* 0.125,项目[索引]。_ty - 10)项[索引]。比例=项目[索引]。显示/项目[索引]。r;//手指滑动的点到圆心的距离与半径的比值作为图片的放大比例项目[索引]。oScale=1/items[index].规模;//图片放大响应的右下角按钮同比缩小//移动后位置的角度项目[索引]。下一个角度=这个。计数度数(项目[索引]).x,项目[索引]。y,项目[索引]。_tx,项目[索引]。_ty) //角度差项目[索引]。new_rotate=items[index].角度下一个-项目[索引]。anglePre//叠加的角度差项目[索引]。旋转=项目[索引]。新建_旋转项目[索引]。角度=项目[索引]。旋转;//赋值//用过移动后的坐标赋值为移动前坐标项目[索引]。tx=e .触摸[0].clientX项目[索引]。ty=e .触摸[0].客户项目[索引]。anglePre=这个。计数度数(项目[索引]).x,项目[索引]。y,项目[索引]。tx,项目[索引]。ty) //赋值设置数据渲染这个。setdata({项目列表:个项目})}页面上是这样写的:

!- *************操作区域* * * * * * * * * * *-块wx :为=“{ { Item list } }”wx :键=“{ { Item。id } } "!-圆心坐标文本样式=' position : absolutetop : { { item . y } } pxleft : { { item . x } } px宽度:2 px高度:2px背景-颜色:黄色;z-index :500 '/text-view class=' touch wrap ' style=' transform : scale({ { item。scale } });top : { { item . top } } px ' left : { { item . left } } px ' view class=' IMgwrap { { item }。主动?触摸活动的“:”} }“style=”变换:旋转({ { item。角度} }度);image src=' { { item。image } } ' data-id=' { { item。id } } ' style=' width : { { item }。宽度} } pxheight : { { item . height } } px ' bind touch start=' wrappoptouchstart ' bind load=' LoadIMg ' hidden=' { {!项目。is load } } bindtochmov=' wrappotuchmove ' bindtochend=' wrappotuchend '/image class=' x ' src='././images/x . png ' style=' transform : scale({ { item。oscale } });变换-原点:中心;data-id=' { { item。id } } ' bind tap=' deleteItem '/image image class=' o ' src='././images/o . png ' style=' transform : scale({ { item。oscale } });变换-原点:中心;data-id=' { { item。id } } ' bind tuchstart=' TouchStart ' bind tuchmove=' touch move ' bind tuchend=' touch end '/image/view/view/block!- **************操作区域************ - 这样一来就解决了微信小程序内拖动图片实现移动、放大、旋转的问题,操作也比较顺滑,也耗费我近四天的时间才把我的小程序上线,代码有点混乱,如果各位大佬有什么意见可以给我留言,我的小程序名字是:水逆转运符文,以后会持续改进。

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

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

/* *参数一和2为图片圆心坐标*参数3和四为手点击的坐标*返回值为手点击的坐标到圆心的角度*/countDeg:函数(cx,cy,pointer_x,pointer _ y){ var ox=pointer _ x-CX;var oy=pointer _ y-cy;var to=数学。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象限{角度=-(180度)度角)} else if (ox 0 oy 0)//右上角,1象限{ angle=angle} else if (ox 0 oy 0)//右下角,2象限{ angle=180-angle;}返回角度;}计算触摸点到圆心的距离:

getdistants(CX,cy,pointer_x,pointer _ y){ var ox=pointer _ x-CX;var oy=pointer _ y-cy;返回数学。sqrt(ox * ox oy * oy);}点击配件时的事件(因为再我测试在帆布中,图片不能是网络路径,所以需要下载): 【18/6/22】

tpDownload:函数(数据,IsDownload){//数据为组件的参数,isDownload判断是否为安全超文本传输协议网络图片来判断是否需要下载if (yy 0) { //改变生成图片时的位置速度=-速度} if(YY 300){速度=-速度} YY=速度;让这=这;让newTpdata={ };newtpdata。id=数据。id;newtpdata。itemid=数据。itemidnewtpdata . top=100 yynewtpdata . left=100 newtpdata。width=_ this。SysDATa。窗宽/4;newtpdata。比例尺=1;newtpdata。角度=0;newtpdata。旋转=0;newTpdata.active=truefor(设I=0;一。项目。长度;i ) { items[i].active=false} if(IsDownLoad){ wx。下载文件({ URL :数据。图片,成功: RES={ new TPDATa。image=RES . Tempfilepath物品。推送(new tpdata);_这个。setdata({项目列表:个项目})wx。隐藏加载();} })} else { newtpdata。图像=数据。图像;物品。推送(new tpdata);_这个。setdata({项目列表:个项目})wx。隐藏加载();} }我的项目中生成帆布用到的代码(绘图是通过保存按钮触发)

保存3330函数(){ this。setdata({ showcanvas 3330 true,canvasheight 3330 this。系统数据。windowheight * 0.85 })让obj=this。数据。项目;/* canvasWidth魏冄-肉桂是阿金;这个。数据。canvaspre云娥与云娥同在(80)*/让canvaswidth=this。系统数据。窗户宽度*这个。数据。canvaspre/100;页:1吾曰-肉桂范国祥-肉桂绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿绿,霍元龙(音译)num=1这个。系统数据。窗宽* 0.75吴经熊和吴经熊属性(道具)魏冄-肉桂云娥与云娥同在,哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟,你好prop=1 */让prop=(canvaswidth * num)/(this。系统数据。window width * 0.75);马斯坎瓦斯。save();马斯克坎瓦斯。begin path();//张肖明吗马斯坎瓦斯。setfillstyle(" # fff ");maskCanvas.fillRect(0,0,this.sysData.windowWidth,this。数据。canvasheight)maskcanvas。close path();马斯坎瓦斯。笔画();//你好let image={ w 3330 canvaswidth * num * 0.287,h 3330 canvaswidth * num * 0.287,r 3330 canvaswidth * num * 0.287/2 };//伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯伊留斯六氯环己烷吾曰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。数据。canvasheight * 0.15/)哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟马斯坎瓦斯。save();马斯克坎瓦斯。begin path();maskcancas。arc(canvaswidth/2,canvaswidth * num * hcw * obj。用户top/100 10图片。w/2,image.r,0,Math).PI * 2,false//maskcancas。stroke()maskcancas。clip()://阿金哥//你好马斯坎瓦斯。绘制图像。avatarrl,(canvasWidth - image.w)/2,canvaswidth * num * hcw * obj。用户top/100 10,image.w,image。h)maskcanvas。close path();马斯坎瓦斯。restore();//陈列夫马斯坎瓦斯。save();马斯克坎瓦斯。begin path();让fontsize=这个。sysdata。屏幕宽度/375 * 15;让textcolor=obj。color | | ' # 000maskcancas。setfont size(parse int(font size)* prop)maskcancas。setfillstyle(文本颜色)maskcancas。settext align(' center ')maskcancas。填充文本。昵称,canvasWidth/2,obj。tite top/100 * canvaswidth * num * hcw 10 * 0.9 * prop font size * prop);马斯坎瓦斯。close path();马斯坎瓦斯。笔画();/** * x * y *比例*属性*宽度*高度** *年items.forEach((currentValue,index)={ maskcancvas。save();马斯坎瓦斯。translate(canvaswidth *(1-num)/2.10);马斯克坎瓦斯。begin path();马斯坎瓦斯。翻译(当前值。x * prop,当前值。y * prop);//(中文)maskcanvas。旋转(当前值。角度*数学).PI/180号文件;//你好maskcancas。翻译((当前值。宽度*当前值。scale * prop/2)、-(当前值。高度*当前值。scale * prop/2))maskcancas。绘制图像(当前值。图像,0,0,当前值。宽度*当前值。比例*道具,当前值。高度*当前值。比例*道具);马斯坎瓦斯。restore();}) maskCanvas.draw(false,(e)={ wx。canvastonilepath({ { canvasid 3360 ' maskcancas),success 3330 RES={ this。setdata({ { canvastemimg 3330 RES . tempfile path } },this)} }朱塞佩朱塞佩朱塞佩朱塞佩,阿云阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜阿云娜,吴亚玲吴亚玲吴亚玲。

版权声明:微信小程序中拖动图片移动、放大、旋转的方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。