小程序图片剪裁加旋转的示例代码


Posted in Javascript onJuly 10, 2018

一个微信小程序图片剪裁组件,可以通过手势控制旋转缩放移动,也可以点击旋转进行90度旋转,先看下效果(视屏不知道为啥用不了,上个压缩过度的GIF先):

小程序图片剪裁加旋转的示例代码

图片剪裁毫无疑问用的是canvas,但是开发过小程序的同学应该了解小程序canvas的一些坑。比如小程序canvas的设定了画布的大小后不能像web的canvas那样通过css样式来调整画布在手机上显示的大小、还有canvas不能设置太大因为可能会在某些安卓机上导致小程序崩溃、canvas绘制过大的图片会让小程序变得非常卡顿等等。

网上能找到的图片剪裁框架大多采用在canvas上面直接绘制图片,然后通过监听canvas上的用户手势来控制图片移动旋转等,这样截出来的图片会出现模糊的问题,因为canvas的太小了。一种解决方法是,在页面上再放置一个隐藏的canvas大小设为原来的两倍或者再大一点也行用来作为实际剪裁图片的canvas,当然剪裁数据都是从第一个canvas那里来的。但是这样还是有些小问题,就是canvas绘制大的图片会出现卡顿的问题,这种方案在监听用户手势的变化的时候要不停的重新绘制canvas,卡顿变得更加严重,体验非常不好。

基于上面原因,我采用的是view里面放置图片,监听view上面的手势,通过css样式控制图片的旋转、缩放和移动,最后剪裁用隐藏的canvas。先看下页面布局:

<view class="container">
 <!-- 剪裁框与初始图片,剪裁框监听用户手势,获取移动缩放旋转值,images通过css样式显示变化 -->
 <view class="img" style="width:{{ width }}px; height:{{height}}px" catchtouchstart="touchstartCallback" catchtouchmove="touchmoveCallback" catchtouchend="touchendCallback" >
  <image style="transform: translate({{stv.offsetX}}px, {{stv.offsetY}}px) scale({{stv.scale}}) rotate({{ stv.rotate }}deg);width:{{originImg.width}}px; height: {{originImg.height}}px" src="{{ originImg.url }}"></image>
 </view>
 <view class='footer'>
   <view bindtap='uploadTap'>选择图片</view> 
   <view bindtap='rotate'>旋转</view>
   <view bindtap='cropperImg'>剪裁</view>
 </view>

 <!-- canvas长宽设为初始图片设置的长款的两倍,使剪裁得到的图片更清晰,也不至于过大 -->
 <canvas class='imgcrop' style="width:{{ width * 2 }}px;height:{{ height * 2}}px;" canvas-id='imgcrop'></canvas>
</view>

最重要的操作是图片在view中的位置变化如何在canvas中保持一致再剪裁出来,图片相对与view中的左上角坐标、图片的长度和宽度我们都是知道的,还有旋转值通过用户手势变化计算出来,旋转的时候将画布的中心移动到图片的中心点再旋转就行了。

let ctx = wx.createCanvasContext('imgcrop',this);
   let cropData = _this.data.stv;
   ctx.save();
   // 缩放偏移值
   let x = (_this.data.originImg.width - _this.data.originImg.width * cropData.scale) / 2;
   let y = (_this.data.originImg.height - _this.data.originImg.height * cropData.scale) / 2;

   //画布中点坐标转移到图片中心
   let movex = (cropData.offsetX + x) * 2 + _this.data.originImg.width * cropData.scale;
   let movey = (cropData.offsetY + y) * 2 + _this.data.originImg.height * cropData.scale;
   ctx.translate(movex, movey);
   ctx.rotate(cropData.rotate * Math.PI / 180);
   ctx.translate(-movex, -movey);
   
   ctx.drawImage(_this.data.originImg.url, (cropData.offsetX + x) * 2, (cropData.offsetY + y) * 2, _this.data.originImg.width * 2 * cropData.scale, _this.data.originImg.height * 2 * cropData.scale);
   ctx.restore();

查看完整代码请移步到:https://github.com/yuanwyj/Mini-Program-cropper, 喜欢的画点个start~~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery获取文本节点之 text()/val()/html() 方法区别
Mar 01 Javascript
jQuery选择器中含有空格的使用示例及注意事项
Aug 25 Javascript
javascript关于继承的用法汇总
Dec 20 Javascript
js+css实现tab菜单切换效果的方法
Jan 20 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
Jun 03 Javascript
jsTree使用记录实例
Dec 01 Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 Javascript
详解javascript中的Error对象
Apr 25 Javascript
微信小程序商品详情页底部弹出框
Nov 22 Javascript
vue实现自定义多选按钮
Jul 16 Javascript
解决vue init webpack 下载依赖卡住不动的问题
Nov 09 Javascript
用vue设计一个日历表
Dec 03 Vue.js
vue使用中的内存泄漏【推荐】
Jul 10 #Javascript
Vue脚手架的简单使用实例
Jul 10 #Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
Jul 10 #Javascript
微信小程序中换行空格(多个空格)写法详解
Jul 10 #Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
Jul 10 #Javascript
Angular5中提取公共组件之radio list的实例代码
Jul 10 #Javascript
ng-alain表单使用方式详解
Jul 10 #Javascript
You might like
《斗罗大陆》六翼天使武魂最强,为什么老千家不是上三宗?
2020/03/02 国漫
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php计算多维数组中所有值总和的方法
2015/06/24 PHP
ThinkPHP5框架实现简单的批量查询功能示例
2018/06/07 PHP
JavaScript中的splice()方法使用详解
2015/06/09 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
2015/09/18 Javascript
javascript随机抽取0-100之间不重复的10个数
2016/02/25 Javascript
AngularJS中的按需加载ocLazyLoad示例
2017/01/11 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
Vue2.0表单校验组件vee-validate的使用详解
2017/05/02 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
2017/12/28 Javascript
JavaScript动态创建二维数组的方法示例
2019/02/01 Javascript
webpack 代码分离优化快速指北
2019/05/18 Javascript
在Python下尝试多线程编程
2015/04/28 Python
Python使用urllib2模块实现断点续传下载的方法
2015/06/17 Python
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
详解django中使用定时任务的方法
2018/09/27 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
2019/05/09 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
K最近邻算法(KNN)---sklearn+python实现方式
2020/02/24 Python
python不同系统中打开方法
2020/06/23 Python
Python列表推导式实现代码实例
2020/09/09 Python
Python制作运行进度条的实现效果(代码运行不无聊)
2021/02/24 Python
HTML5 Canvas实现烟花绽放特效
2016/03/02 HTML / CSS
家乐福巴西网上超市:Carrefour巴西
2016/10/31 全球购物
阿迪达斯香港官网:adidas香港
2019/11/09 全球购物
公务员培训心得体会
2013/12/28 职场文书
12岁生日感言
2014/01/21 职场文书
《猫》教学反思
2014/02/26 职场文书
交通事故赔偿协议书
2014/04/15 职场文书
酒店爱岗敬业演讲稿
2014/09/02 职场文书
2014年城管工作总结
2014/11/20 职场文书
公司感谢信范文
2015/01/22 职场文书
工作检讨书范文
2015/01/23 职场文书
Mysql分析设计表主键为何不用uuid
2022/03/31 MySQL
从原生JavaScript到React深入理解
2022/07/23 Javascript