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


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之函数直接量(function(){})()
Jun 29 Javascript
jQuery 操作XML入门
Dec 25 Javascript
js格式化金额可选是否带千分位以及保留精度
Jan 28 Javascript
javascript中return,return true,return false三者的用法及区别
Nov 17 Javascript
简单讲解AngularJS的Routing路由的定义与使用
Mar 05 Javascript
全面解析Bootstrap中tooltip、popover的使用方法
Jun 13 Javascript
js动态添加的DIV中的onclick事件简单实例
Jul 25 Javascript
bootstrapfileinput实现文件自动上传
Nov 08 Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
Jun 03 Javascript
vue组件间通信子与父详解(二)
Nov 07 Javascript
Vue时间轴 vue-light-timeline的用法说明
Oct 29 Javascript
vue 递归组件的简单使用示例
Jan 14 Vue.js
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
浅析Yii2中GridView常见操作
2016/04/22 PHP
使用jquery给input和textarea设定ie中的focus
2008/05/29 Javascript
javascript 简单抽屉效果的实现代码
2010/03/09 Javascript
jQuery自定义事件的简单实现代码
2014/01/27 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
javascript实现鼠标放上后下边对应内容变换的效果
2015/08/06 Javascript
node.js + socket.io 实现点对点随机匹配聊天
2017/06/30 Javascript
原生JS实现图片无缝滚动方法(附带封装的运动框架)
2017/10/01 Javascript
ES6/JavaScript使用技巧分享
2017/12/14 Javascript
深入浅析Vue全局组件与局部组件的区别
2018/06/15 Javascript
JS无限级导航菜单实现方法
2019/01/05 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
2019/09/20 Javascript
js脚本中执行java后台代码方法解析
2019/10/11 Javascript
vue使用一些外部插件及样式的配置代码
2019/11/18 Javascript
原生js实现的观察者和订阅者模式简单示例
2020/04/18 Javascript
vue-cli4项目开启eslint保存时自动格式问题
2020/07/13 Javascript
jQuery使用hide()、toggle()函数实现相机品牌展示隐藏功能
2021/01/29 jQuery
[47:45]Liquid vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
python实现自动登录人人网并采集信息的方法
2015/06/28 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
Python解析、提取url关键字的实例详解
2018/12/17 Python
Django REST Swagger实现指定api参数
2020/07/07 Python
Flask缓存静态文件的具体方法
2020/08/02 Python
html5本地存储_动力节点Java学院整理
2017/07/12 HTML / CSS
英国现代家具和装饰网站:PN Home
2018/08/16 全球购物
匡威意大利官方商店 :Converse意大利
2018/11/27 全球购物
环境工程与管理大学毕业生求职信
2013/10/02 职场文书
2014年班主任自我评价范文
2014/04/23 职场文书
2014年前台个人工作总结
2014/11/14 职场文书
离职信范本
2015/06/23 职场文书
2015年新教师个人工作总结
2015/10/14 职场文书
施工安全协议书
2016/03/22 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL