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


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 相关文章推荐
文本加密解密
Jun 23 Javascript
JavaScript实现存储HTML字符串示例
Apr 21 Javascript
多个jQuery版本共存的处理方案
Mar 17 Javascript
jquery遍历table的tr获取td的值实现方法
May 19 Javascript
JS中常用的输出方式(五种)
Jun 12 Javascript
基于jQuery实现表格内容的筛选功能
Aug 21 Javascript
js 模仿锚点定位的实现方法
Nov 19 Javascript
详解Javascript中DOM的范围
Feb 13 Javascript
深入浅析Node环境和浏览器的区别
Aug 14 Javascript
vue单页面实现当前页面刷新或跳转时提示保存
Nov 02 Javascript
详解微信小程序框架wepy踩坑记录(与vue对比)
Mar 12 Javascript
浅谈Vue项目骨架屏注入实践
Aug 05 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下检测字符串是否是utf8编码的代码
2008/06/28 PHP
php读取mysql乱码,用set names XXX解决的原理分享
2011/12/29 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
2013/10/26 PHP
PHP编写RESTful接口的方法
2016/02/21 PHP
yii框架使用分页的方法分析
2019/07/25 PHP
利用jQuery 实现GridView异步排序、分页的代码
2010/02/06 Javascript
JS实现程序暂停与继续功能代码解读
2013/10/10 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
jquery实现的随机多彩tag标签随机颜色和字号大小效果
2014/03/27 Javascript
jQuery中阻止冒泡事件的方法介绍
2014/04/12 Javascript
jquery中attr和prop的区别分析
2015/03/16 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
2016/05/10 Javascript
基于JavaScript实现带缩略图的轮播效果
2017/01/12 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
2017/03/11 Javascript
Ionic3 UI组件之autocomplete详解
2017/06/08 Javascript
jquery获取链接地址和跳转详解(推荐)
2017/08/15 jQuery
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
Vue.js实现可排序的表格组件功能示例
2019/02/19 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
Vue 解决路由过渡动画抖动问题(实例详解)
2020/01/05 Javascript
JavaScript实现公告栏上下滚动效果
2020/03/13 Javascript
[06:48]DOTA2-DPC中国联赛2月26日Recap集锦
2021/03/11 DOTA
Python+django实现简单的文件上传
2016/08/17 Python
详解Python_shutil模块
2019/03/15 Python
python自动化之Ansible的安装教程
2019/06/13 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
pygame实现俄罗斯方块游戏(基础篇2)
2019/10/29 Python
Python实现Kerberos用户的增删改查操作
2020/12/14 Python
高中生期末评语
2014/01/28 职场文书
工作失职检讨书(精华篇)
2014/10/15 职场文书
如果用一句诗总结你的上半年,你会用哪句呢?
2019/07/16 职场文书
致男子1500米运动员的广播稿
2019/11/08 职场文书
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
Sql Server 行数据的某列值想作为字段列显示的方法
2022/04/20 SQL Server
Java 数组的使用
2022/05/11 Java/Android