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


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 相关文章推荐
Javascript处理DOM元素事件实现代码
May 23 Javascript
原生js实现改变随意改变div属性style的名称和值的结果
Sep 26 Javascript
jquery validate添加自定义验证规则(验证邮箱 邮政编码)
Dec 04 Javascript
jQuery插件Tmpl的简单使用方法
Apr 27 Javascript
javascript入门教程基础篇
Nov 16 Javascript
java必学必会之static关键字
Dec 03 Javascript
JavaScript使用键盘输入控制实现数字验证功能
Aug 19 Javascript
jQuery简单自定义图片轮播插件及用法示例
Nov 21 Javascript
JS经典正则表达式笔试题汇总
Dec 15 Javascript
微信小程序实现页面跳转传值以及获取值的方法分析
Dec 18 Javascript
解决node修改后需频繁手动重启的问题
May 13 Javascript
Node.js API详解之 console模块用法详解
May 12 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
thinkphp,onethink和thinkox中验证码不显示的解决方法分析
2016/06/06 PHP
统一接口:为FireFox添加IE的方法和属性的js代码
2007/03/25 Javascript
地址栏上的一段语句,改变页面的风格。(教程)
2008/04/02 Javascript
Jquery通过Ajax方式来提交Form表单的具体实现
2013/11/07 Javascript
Jquery操作js数组及对象示例代码
2014/05/11 Javascript
javascript密码强度校验代码(两种方法)
2015/08/10 Javascript
理解javascript模块化
2016/03/28 Javascript
第七章之菜单按钮图标组件
2016/04/25 Javascript
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
2016/12/14 Javascript
JavaScript控制输入框中只能输入中文、数字和英文的方法【基于正则实现】
2017/03/03 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
2018/01/31 Javascript
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
基于Vue CSR的微前端实现方案实践
2020/05/27 Javascript
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
Python环境变量设置方法
2016/08/28 Python
Python遍历文件夹和读写文件的实现方法
2017/05/10 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
查看python安装路径及pip安装的包列表及路径
2019/04/03 Python
int在python中的含义以及用法
2019/06/27 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
pytorch::Dataloader中的迭代器和生成器应用详解
2020/01/03 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
瑰珀翠美国官网:Crabtree & Evelyn美国
2016/11/29 全球购物
英国户外服装品牌:Craghoppers
2019/04/25 全球购物
英国最大的天然和有机产品在线零售商之一:Big Green Smile
2020/05/06 全球购物
硅酸盐工业控制专业应届生求职信
2013/11/02 职场文书
劳动实践课感言
2014/02/01 职场文书
材料员岗位职责
2015/02/10 职场文书
生日宴会家属答谢词
2015/09/29 职场文书
《角的初步认识》教学反思
2016/02/17 职场文书
2016年最美孝心少年事迹材料
2016/02/26 职场文书
python数据可视化JupyterLab实用扩展程序Mito
2021/11/20 Python
Redis如何使用乐观锁(CAS)保证数据一致性
2022/03/25 Redis
德劲DE1105机评
2022/04/05 无线电
MongoDB支持的数据类型
2022/04/11 MongoDB
Django框架之路由用法
2022/06/10 Python