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


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代码小结
Aug 01 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
Oct 23 Javascript
Jquery validation remote 验证的缓存问题解决方法
Mar 25 Javascript
dedecms页面如何获取会员状态的实例代码
Mar 15 Javascript
深入理解jQuery中的事件冒泡
May 24 Javascript
jQuery 特性操作详解及实例代码
Sep 29 Javascript
详解Vue-基本标签和自定义控件
Mar 24 Javascript
老生常谈js中的MVC
Jul 25 Javascript
JavaScript与Java正则表达式写法的区别介绍
Aug 15 Javascript
JS简单实现滑动加载数据的方法示例
Oct 18 Javascript
require.js 加载过程与使用方法介绍
Oct 30 Javascript
微信小程序实现吸顶效果
Jan 08 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 数组使用详解 推荐
2011/06/02 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
PHP生成图片缩略图类示例
2017/01/12 PHP
ThinkPHP框架分布式数据库连接方法详解
2017/03/14 PHP
PHP反射原理与用法深入分析
2019/09/28 PHP
javascript 有用的脚本函数
2009/05/07 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
基于jQuery实现文本框只能输入数字(小数、整数)
2016/01/14 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
2017/04/07 Javascript
一次记住JavaScript的6个正则表达式方法
2018/02/22 Javascript
vue路由拦截及页面跳转的设置方法
2018/05/24 Javascript
[06:33]DOTA2亚洲邀请赛小组赛第二日 TOP10精彩集锦
2015/01/31 DOTA
[02:03]DOTA2亚洲邀请赛 HGT战队出场宣传片
2015/02/07 DOTA
用Python编写一个基于终端的实现翻译的脚本
2015/04/24 Python
详细解析Python中__init__()方法的高级应用
2015/05/11 Python
python利用正则表达式提取字符串
2016/12/08 Python
利用TensorFlow训练简单的二分类神经网络模型的方法
2018/03/05 Python
tensorflow实现读取模型中保存的值 tf.train.NewCheckpointReader
2020/02/10 Python
4行Python代码生成图像验证码(2种)
2020/04/07 Python
Python高并发解决方案实现过程详解
2020/07/31 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
英国第一的购买便宜玩具和游戏的在线购物网站:Bargain Max
2018/01/24 全球购物
Myprotein俄罗斯官网:欧洲第一运动营养品牌
2019/05/05 全球购物
Ruby如何定义一个类
2012/10/08 面试题
大学生新闻专业个人自我评价
2013/11/12 职场文书
教育实习生的自我评价分享
2013/11/21 职场文书
优秀教师工作感言
2014/02/16 职场文书
法人授权委托书
2014/04/03 职场文书
学校四群教育实施方案
2014/06/12 职场文书
迎新晚会策划方案
2014/06/13 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
无婚姻登记记录证明
2015/06/18 职场文书
总结Python常用的魔法方法
2021/05/25 Python
Vue2.0搭建脚手架
2022/03/13 Vue.js