小程序实现图片预览裁剪插件


Posted in Javascript onNovember 22, 2019

最近在帮工作室做一个小程序,在换背景图的时候需要预览图片,并且需要裁剪成固定的尺寸。因为小程序并不支持原生的dom操作,导致很多现有的插件都无法使用,所以花了半天专门做了一个小程序的预览裁剪插件。下面贴上代码和效果图。

wxml:

<canvas hidden='{{hide_canvas}}' id='cover-preview' bindtouchstart='canvas_start' bindtouchmove='canvas_move' bindtouchend='canvas_end' disable-scroll='true' canvas-id='cover-preview'>
  <cover-view catchtap='upload_bg' id='croper-sure'>确定</cover-view>
  <cover-view catchtap='cancel_croper' id='croper-cancel'>取消</cover-view>
  <cover-view id='croper'></cover-view>
 </canvas>

注意:canvas里面一定要用cover-view,否则无法覆盖canvas

js:

const ctx = wx.createCanvasContext('cover-preview');
var start_position = {};//移动图片时手指起始坐标
var tempFilePath;//图片路径
var tempWidth;//图片初始宽度
var tempHeight;//图片初始高度
var old_x = 0;//图片初始x坐标
var old_y = 0;//图片初始y坐标
var _touches = 1;//触屏的手指数
var old_scale = 1;//原始放大倍数
var new_scale = 1;//新的放大倍数
var is_move = false;//是否移动
var bg_url;
Page({
data: {
 hide_canvas:true,//绘图层显示控制变量
},
//选择并将图片输出到canvas
change_cover:function(){
  var that = this;
  wx.showModal({
   title: '提示',
   content: '更改我的封面',
   confirmColor: '#39bae8',
   success: function (res) {
    if (res.confirm) {
     
     
     wx.chooseImage({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res0) {
       
       tempFilePath = res0.tempFilePaths[0];
       that.setData({
        hide_canvas: false,
        // edit_url: tempFilePath
       })
       wx.getImageInfo({
        src: tempFilePath,
        success: function (res) {
         // console.log(res.width)
         // console.log(res.height)
         tempWidth = res.width;
         tempHeight = res.height;
         ctx.drawImage(tempFilePath,0, 0, 375,res.height/res.width*375);
         ctx.draw();
        }
       })
       
      }
     })
    } else if (res.cancel) {
     console.log('用户点击取消')
    }
   }
  })
 },
 //监听手指触摸事件,并判断是移动还是缩放,并记录初始状态
 canvas_start:function(e){
  // console.log(e);
  var touches = e.touches.length;
  if(touches == 1){
   _touches = 1;
   start_position = { x: e.touches[0].x, y: e.touches[0].y, timeStamp:e.timeStamp}
  }else if(touches == 2){
   _touches = 2;
   start_position = { x: e.touches[0].x, y: e.touches[0].y,x1: e.touches[1].x, y1: e.touches[1].y, timeStamp: e.timeStamp }
  }else{
   _touches = 1;
  }
 },
 //监听手指移动事件,并做出相应调整
 canvas_move: function (e) {
  // console.log(e);
  var touches = e.touches.length;
  if (_touches == 1 && e.timeStamp - start_position.timeStamp > 150) {
   ctx.drawImage(tempFilePath, old_x + e.touches[0].x - start_position.x, old_y + e.touches[0].y - start_position.y, 375 * new_scale, tempHeight / tempWidth * 375 * new_scale);
   ctx.draw();
   is_move = true;
  } else if (_touches == 2 && e.timeStamp - start_position.timeStamp > 150) {
   var change_x = Math.abs(Math.abs(e.touches[0].x - e.touches[1].x) - Math.abs(start_position.x - start_position.x1));
   var change_y = Math.abs(Math.abs(e.touches[0].y - e.touches[1].y) - Math.abs(start_position.y - start_position.y1));
   if(change_x - change_y > 10){
    old_scale = Math.abs(e.touches[0].x - e.touches[1].x) / Math.abs(start_position.x - start_position.x1);
   }else{
    old_scale = Math.abs(e.touches[0].y - e.touches[1].y) / Math.abs(start_position.y - start_position.y1);
   }
   ctx.drawImage(tempFilePath, old_x, old_y, 375 * old_scale * new_scale, tempHeight / tempWidth * 375 * old_scale * new_scale);
   ctx.draw();
   is_move = true;
  }else{
   is_move = false;
  }
 },
 //监听手指离开动作,并保存当前状态数据
 canvas_end: function (e) {
  // console.log(e);
  if (_touches == 1 && is_move) {
   old_x = old_x + e.changedTouches[0].x - start_position.x;
   old_y = old_y + e.changedTouches[0].y - start_position.y;
  } else if (_touches == 2 && is_move) {
   new_scale = old_scale * new_scale;
  }
  
 },
 //确定并上传背景图
 upload_bg:function(){
  var that = this;
  var screenWidth = wx.getSystemInfoSync().screenWidth;
  // console.log(screenWidth);
  wx.canvasToTempFilePath({
   x: 0,
   y: screenWidth / 750 * 400,
   width: screenWidth,
   height: screenWidth / 750 * 526,
   destWidth: screenWidth,
   screenHeight: screenWidth / 750 * 526,
   quality:1,
   canvasId: 'cover-preview',
   success: function (res) {
    that.setData({
     hide_canvas: true,
    })
    //res.tempFilePath即为生成的图片路径
    console.log(res.tempFilePath)
    
   }
  })
 },
 //取消图片预览编辑
 cancel_croper:function(){
  ctx.clearActions();
  this.setData({
   hide_canvas: true,
   // edit_url: tempFilePath
  })
 },
})

wxss:

#cover-preview{
 width: 100%;
 height: 100%;
 background-color: black;
}
#croper{
 width: 750rpx;
 height: 526rpx;
 position: absolute;
 top: 400rpx;
 left: 0;
 background-color: rgba(135,206,250,0.5);
}
 
#croper-sure{
 width: 120rpx;
 height: 50rpx;
 border-radius: 10rpx;
 color: black;
 background-color: rgba(135,206,250,0.8);
 font-size: 40rpx;
 position: absolute;
 top: 946rpx;
 right: 10rpx;
 text-align: center
}
#croper-cancel{
 width: 120rpx;
 height: 50rpx;
 border-radius: 10rpx;
 color: black;
 background-color: rgba(135,206,250,0.8);
 font-size: 40rpx;
 position: absolute;
 top: 946rpx;
 right: 150rpx;
 text-align: center
}

效果图

小程序实现图片预览裁剪插件

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

Javascript 相关文章推荐
Ajax一统天下之Dojo整合篇
Mar 24 Javascript
[推荐]javascript 面向对象技术基础教程
Mar 03 Javascript
js 覆盖和重载 函数
Sep 25 Javascript
浏览器解析js生成的html出现样式问题的解决方法
Apr 16 Javascript
jQuery实现表格颜色交替显示的方法
Mar 09 Javascript
jquery插件NProgress.js制作网页加载进度条
Jun 05 Javascript
jQuery实现延迟跳转的方法
Jun 05 Javascript
jQuery根据元素值删除数组元素的方法
Jun 24 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
May 03 Javascript
基于vue-element组件实现音乐播放器功能
May 06 Javascript
vue组件中的数据传递方法
May 14 Javascript
页面内锚点定位及跳转方法总结(推荐)
Apr 24 Javascript
Vue数据双向绑定底层实现原理
Nov 22 #Javascript
Node如何后台数据库使用增删改查功能
Nov 21 #Javascript
vue移动端使用appClound拉起支付宝支付的实现方法
Nov 21 #Javascript
微信小程序动态设置图片大小的方法
Nov 21 #Javascript
通过原生vue添加滚动加载更多功能
Nov 21 #Javascript
小程序api实现promise封装过程解析
Nov 21 #Javascript
如何基于原生javaScript生成带图片的二维码
Nov 21 #Javascript
You might like
codeigniter集成ucenter1.6双向通信的解决办法
2014/06/12 PHP
PHP对文件夹递归执行chmod命令的方法
2015/06/19 PHP
ThinkPHP中where()使用方法详解
2016/04/19 PHP
php getcwd与dirname(__FILE__)区别详解
2016/09/24 PHP
thinkPHP订单数字提醒功能的实现方法
2016/12/01 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
ExtJs扩展之GroupPropertyGrid代码
2010/03/05 Javascript
mysql输出数据赋给js变量报unterminated string literal错误原因
2010/05/22 Javascript
javascript正则表达式中参数g(全局)的作用
2010/11/11 Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
2011/12/06 Javascript
如何让DIV可编辑、可拖动示例代码
2013/09/18 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
可插入图片的TEXT文本框
2013/12/27 Javascript
JS 获取浏览器和屏幕宽高等信息代码
2014/03/31 Javascript
浅谈addEventListener和attachEvent的区别
2016/07/14 Javascript
移动端基础事件总结与应用
2017/01/12 Javascript
使用bat打开多个cmd窗口执行gulp、node
2017/02/17 Javascript
微信小程序解析富文本过程详解
2019/07/13 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
[01:07:21]NAVI vs VG Supermajor 败者组 BO3 第二场 6.5
2018/06/06 DOTA
Python实现的多线程端口扫描工具分享
2015/01/21 Python
Python简单删除目录下文件以及文件夹的方法
2015/05/27 Python
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
Python中%r和%s的详解及区别
2017/03/16 Python
python针对不定分隔符切割提取字符串的方法
2018/10/26 Python
python输入整条数据分割存入数组的方法
2018/11/13 Python
python 实现矩阵上下/左右翻转,转置的示例
2019/01/23 Python
django框架中ajax的使用及避开CSRF 验证的方式详解
2019/12/11 Python
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
超市创业计划书
2014/04/24 职场文书
环保倡议书300字
2014/05/15 职场文书
保险专业求职信
2014/07/07 职场文书
四风问题党员个人整改措施
2014/10/27 职场文书
2014年反洗钱工作总结
2014/11/22 职场文书
企业财务管理制度范本
2015/08/04 职场文书
详解OpenCV曝光融合
2022/04/29 Python