前言

如今的H5运营活动中,有很多都是让用户拍照或者上传图片,然后对照片加滤镜、加贴纸、评颜值之类的。尤其是一些拍照软件公司的运营活动几乎全部都是这样的。

博主也做过不少,为了省事就封装了一个简单的图片拖拽、裁剪的插件。其实网上也有很多类似的插件,只不过有的功能冗余体积大,有的甚至还依赖jquery。索性自己搞一个轻量的,只是不支持缩放功能。

DEMO(手机上看效果比较好,PC上没有兼容处理),原码

实现

这里简略说下实现过程,只截取部分代码片段,有兴趣的可以看下原码,反正也很简单。

图片上传

这个DEMO里使用的上传方式是HTML5的 File Input,但是很多运营活动需要调用微信的上传&拍照接口,由于以前踩过坑这里就啰嗦两句,帮助新人绕开。

· 在 wx.config 中的 jsApiList 属性中添加 chooseImage 和 uploadImage API。

· 调用 chooseImage API,获得 localId。

wx.chooseImage({count: 1, // 默认9sizeType: ['original', 'compressed'],sourceType: ['album', 'camera'],success: (res) => {var localIds = res.localIds[0];console.log(localIds);}
});

需要注意的是这里的 localId 可以通过 img 标签的 src 属性进行展示,但是无法传给服务器接口或者通过 canvas 裁剪,所以还需要上传一步。

· 调用 uploadImage API,将之前得到的 localId 传入,获得 serverId。

wx.uploadImage({localId: localIds,isShowProgressTips: 1,success: (res) => {var serverId = res.serverId;console.log(serverId);}
});

有了 serverId 其实就可以得到保存在微信服务器上的图片了,只是博主之前还去多余的下载一道。

将一开始微信认证时获得的 accessToken 与 serverId 拼接到下面的链接即可直接引用

const imgUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + accessToken + "&media_id=" + serverId;

接下来就可以创建 image 对象,设置 src 属性,完成拖拽裁切等操作。

初始化

首先要对图片的尺寸进行调整:

· 若图片宽高比比容器的大,即图片比容器“扁”,就让图片的高度与容器保持一致,宽度自动适应保持原图比例不变

· 若图片宽高比比容器的小,即图片比容器“瘦”,就让图片的宽度与容器保持一致,高度自动适应保持原图比例不变

为了便于理解,我们假设容器高宽为1:1,为下图中红色线框区域:

代码片段

var img = new Image(),_this = this;img.src = imgUrl;
img.style.webkitUserSelect = 'none';img.onload = function() {var imgWidth = img.width,imgHeight = img.height,imgRate = imgWidth / imgHeight,conRate = conWidth / conHeight;if (imgRate > conRate) { //宽型var imgCurrentHeight = _this.opts.conHeight,imgCurrentWidth = imgCurrentHeight * imgRate,maxOffset = conWidth - imgCurrentWidth;img.setAttribute('width', 'auto');img.setAttribute('height', _this.opts.conHeight);//......} else { //高型var imgCurrentWidth = _this.opts.conWidth,imgCurrentHeight = imgCurrentWidth / imgRate,maxOffset = conHeight - imgCurrentHeight;img.setAttribute('width', '100%');//......}
}

上述代码就完成了基本的图片大小调整,其中 conWidth, conHeight 是插件接收的容器高与宽,maxOffset 是图片允许拖拽的最大偏移量。

拖拽

这里我使用了一个比较轻量的手势库——hammer.js,通过手势的位移改变图片的 translate 属性值。

这里只截取横向拖拽的代码片段,纵向类似

hammer.on('pan', function(e) {var current = img.style.transform ? img.style.transform.split('(')[1].split('px')[0] : 0,move = Number(current) + (e.deltaX * (_this.opts.speed/10));if (move >= 0 || move <= maxOffset) {return;}img.style.transform = 'translateX('+move+'px)';_this.cutData.moveX = Math.abs(move);_this.cutData.moveY = 0;
});

opts.speed 值为插件初始化时设置的拖动速度,这里速度值算法比较简单,有兴趣的朋友可优化使其更平滑些。cutData 用于缓存拖动的位置,用于之后的裁剪。

裁剪

这里使用了 canvas 对图片进行裁剪返回 base64码,可以将 base64码直接展示或者通过 POST 接口传到服务器处理(GET请求长度会超)

cut: function() {var canvas = document.createElement('canvas'),img = document.querySelector('#cutImgObj'),data = this.cutData,cutWidth = this.opts.conWidth / data.scaleRate,cutHeight = this.opts.conHeight / data.scaleRate;canvas.width = cutWidth;canvas.height = cutHeight;canvas.getContext('2d').drawImage(img, data.moveX/data.scaleRate, data.moveY/data.scaleRate, cutWidth, cutHeight, 0, 0, cutWidth, cutHeight);return canvas.toDataURL('image/png');
},

这里要说明下,由于图片进行了缩放,所以需要将画布调整到原图的尺寸,同时记录的拖动位置也需要除以缩放比例。

调用

· 初始化

var cutter = new Cutter(picAreaDom, {imgUrl: url, //图片链接conWidth: containerDom.offsetWidth, //容器宽度conHeight: containerDom.offsetWidth * 1.2, //容器高度speed: 2, //拖动速度callback: function() {//doSomething...}
});

这里有个地方要说明下,虽然 Cutter 中的 conWidth,conHeight 属性默认为 picAreaDom 的宽高,但如果 picAreaDom 的父级元素为 display:none,那么就获取不到 picAreaDom 尺寸(DEMO中单页应用机制导致的),这时候就需要显式传入裁剪区域的宽高。

callback 为初始化完成时的回调函数,保存实例化对象 cutter,用于之后的裁剪。

· 裁剪

var result = cutter.cut();

result 值即为裁剪后的 base64码。

最后一个小提示,如果需要重新上传图片裁剪,记得将容器中的 img 对象移除。具体的细节可以参考原码,整体比较简单。

-转载

转载于:https://www.cnblogs.com/wenJiaQi/p/6401127.html

自制一个H5图片拖拽、裁剪插件(原生JS)相关推荐

  1. html列表拖拽排序插件,JS拖拽排序插件Sortable.js用法实例分析

    本文实例讲述了JS拖拽排序插件Sortable.js用法.分享给大家供大家参考,具体如下: 最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好 ...

  2. 图片上传裁剪插件cropper.js的API详解

    jQuery.cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用.    cropp ...

  3. 盒子拖拽效果,原生js实现

    原生js实现拖拽效果 <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...

  4. 拖拽排序插件Sortable.js在拖动的时候不能滑动鼠标滚轮滚动屏幕的问题

    只是一个小问题 在使用sortable.js的时候遇到拖动的时候不能滑动鼠标滚轮控制滚动条,找了很多地方,也看了文档,原来是没有找到那个点: forceFallback: false, // igno ...

  5. 使用jQuery开发一个基于HTML5的漂亮图片拖拽上传web应用

    昨天我们介绍了一款HTML5文件上传的jQuery插件:jQuery HTML5 uploader,今天我们将开发一个简单的叫upload center的图片上传程序,允许用户使用拖拽方式来上传电脑上 ...

  6. cropperjs图片上传裁剪插件

    cropperjs是一款非常强大却又简单的图片裁剪工具,它可以进行非常灵活的配置,支持手机端使用,支持包括IE9以上的现代浏览器.(关键是使用方法简单,几行代码就可以搞定) 实践效果图 如图,可以对指 ...

  7. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  8. Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  9. 类似新浪微博和google图片的HTML5实现图片拖拽上传功能

    2019独角兽企业重金招聘Python工程师标准>>> 来源: http://www.lovesunlife.com/?p=315 这篇文章对google图片为蓝本就拖拽上传功能分析 ...

  10. 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能

    原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...

最新文章

  1. 如何将通达信的预警股票发送到微信
  2. 哪个瞬间你对科研圈彻底失望了?
  3. 进击吧! Blazor !第二期 页面制作
  4. codeforces 266B-C语言解题报告
  5. 设置XMLHttpRequest“ withCredentials”属性问题,axios请求不成功
  6. mac在命令行里获取root权限
  7. 实践案例丨利用小熊派开发板获取土壤湿度传感器的ADC值
  8. PowerVR 6XT/6XE系列移动GPU
  9. 数据科学20个最好的Python库
  10. 小程序的各种场景及实现
  11. android 系统字体无效,android内嵌H5页面,字体设置失效的问题
  12. tkinter教程目录
  13. MATLAB---画三角函数图像
  14. koolshare DDNS 配置
  15. springboot 自定义starter
  16. 07 Java 工程师面试技巧篇
  17. golang反射修改结构体字段(reflect.flag.mustBeAssignable using value obtained using unexported field) 2020.8.18
  18. 如何解决HEVC编码格式不能播放的问题?
  19. 关于感染型病毒的那些事(一)
  20. 拿捏了,阿里2022最新JDK源码深度解析小册,Github全站热榜第二

热门文章

  1. Mybatis原理解析(二)SqlSession的创建过程
  2. 至少出现k次重复的子串的最大长度
  3. Oracle9i中监视索引的使用
  4. Spring中的FactoryBean
  5. [线筛五连]线筛欧拉函数
  6. [2018.03.29 T2] 公交旅行
  7. ssh: connect to host gitee.com port 22: Connection timed out fatal: Could not read from remote repos
  8. 黑马品优购项目的总结二
  9. zabbix监控nginx的状态
  10. Linux文件描述符和输入输出重定向