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


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 相关文章推荐
jQuery 页面载入进度条实现代码
Feb 08 Javascript
javascript 获取url参数和script标签中获取url参数函数代码
Jan 22 Javascript
js验证模型自我实现的具体方法
Jun 21 Javascript
html的DOM中document对象anchors集合用法实例
Jan 21 Javascript
JavaScript学习笔记之ES6数组方法
Mar 25 Javascript
AngularJS表单验证中级篇(3)
Sep 28 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
Sep 22 jQuery
详解React中合并单元格的正确写法
Jan 08 Javascript
如何使用Node.js爬取任意网页资源并输出PDF文件到本地
Jun 17 Javascript
JS获取动态添加元素的方法详解
Jul 31 Javascript
在vue中利用v-html按分号将文本换行的例子
Nov 14 Javascript
vue 封装 Adminlte3组件的实现
Mar 18 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
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
Laravel中encrypt和decrypt的实现方法
2017/09/24 PHP
ThinkPHP3.2框架操作Redis的方法分析
2019/05/05 PHP
jQuery TextBox自动完成条
2009/07/22 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
2012/01/04 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
2014/01/12 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
2014/09/24 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
2015/06/05 Javascript
JS随机调用指定函数的方法
2015/07/01 Javascript
JS中常用的输出方式(五种)
2016/06/12 Javascript
引用jquery框架后出错的解决方法
2016/08/09 Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
2016/09/24 Javascript
javascript读取文本节点方法小结
2016/12/15 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
jqGrid翻页时数据选中丢失问题的解决办法
2017/02/13 Javascript
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
代码分析Python地图坐标转换
2018/02/08 Python
Python爬虫实现简单的爬取有道翻译功能示例
2018/07/13 Python
Python基于百度云文字识别API
2018/12/13 Python
Python远程开发环境部署与调试过程图解
2019/12/09 Python
Pytorch中.new()的作用详解
2020/02/18 Python
Django 返回json数据的实现示例
2020/03/05 Python
pycharm部署、配置anaconda环境的教程
2020/03/24 Python
PyCharm配置anaconda环境的步骤详解
2020/07/31 Python
澳大利亚百货商店中销量第一的商务衬衫品牌:Van Heusen
2018/07/26 全球购物
财务助理岗位职责
2013/11/10 职场文书
大学军训感言400字
2014/03/11 职场文书
书香家庭事迹材料
2014/05/09 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
干部外出学习心得体会
2016/01/18 职场文书
分享几个JavaScript运算符的使用技巧
2021/04/24 Javascript
vue组件的路由高亮问题解决方法
2021/05/11 Vue.js
python pygame入门教程
2021/06/01 Python
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android