自制一个H5图片拖拽、裁剪插件(原生JS)
前言
如今的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)相关推荐
- html列表拖拽排序插件,JS拖拽排序插件Sortable.js用法实例分析
本文实例讲述了JS拖拽排序插件Sortable.js用法.分享给大家供大家参考,具体如下: 最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好 ...
- 图片上传裁剪插件cropper.js的API详解
jQuery.cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用. cropp ...
- 盒子拖拽效果,原生js实现
原生js实现拖拽效果 <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...
- 拖拽排序插件Sortable.js在拖动的时候不能滑动鼠标滚轮滚动屏幕的问题
只是一个小问题 在使用sortable.js的时候遇到拖动的时候不能滑动鼠标滚轮控制滚动条,找了很多地方,也看了文档,原来是没有找到那个点: forceFallback: false, // igno ...
- 使用jQuery开发一个基于HTML5的漂亮图片拖拽上传web应用
昨天我们介绍了一款HTML5文件上传的jQuery插件:jQuery HTML5 uploader,今天我们将开发一个简单的叫upload center的图片上传程序,允许用户使用拖拽方式来上传电脑上 ...
- cropperjs图片上传裁剪插件
cropperjs是一款非常强大却又简单的图片裁剪工具,它可以进行非常灵活的配置,支持手机端使用,支持包括IE9以上的现代浏览器.(关键是使用方法简单,几行代码就可以搞定) 实践效果图 如图,可以对指 ...
- 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
- Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
- 类似新浪微博和google图片的HTML5实现图片拖拽上传功能
2019独角兽企业重金招聘Python工程师标准>>> 来源: http://www.lovesunlife.com/?p=315 这篇文章对google图片为蓝本就拖拽上传功能分析 ...
- 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能
原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...
最新文章
- 如何将通达信的预警股票发送到微信
- 哪个瞬间你对科研圈彻底失望了?
- 进击吧! Blazor !第二期 页面制作
- codeforces 266B-C语言解题报告
- 设置XMLHttpRequest“ withCredentials”属性问题,axios请求不成功
- mac在命令行里获取root权限
- 实践案例丨利用小熊派开发板获取土壤湿度传感器的ADC值
- PowerVR 6XT/6XE系列移动GPU
- 数据科学20个最好的Python库
- 小程序的各种场景及实现
- android 系统字体无效,android内嵌H5页面,字体设置失效的问题
- tkinter教程目录
- MATLAB---画三角函数图像
- koolshare DDNS 配置
- springboot 自定义starter
- 07 Java 工程师面试技巧篇
- golang反射修改结构体字段(reflect.flag.mustBeAssignable using value obtained using unexported field) 2020.8.18
- 如何解决HEVC编码格式不能播放的问题?
- 关于感染型病毒的那些事(一)
- 拿捏了,阿里2022最新JDK源码深度解析小册,Github全站热榜第二
热门文章
- Mybatis原理解析(二)SqlSession的创建过程
- 至少出现k次重复的子串的最大长度
- Oracle9i中监视索引的使用
- Spring中的FactoryBean
- [线筛五连]线筛欧拉函数
- [2018.03.29 T2] 公交旅行
- ssh: connect to host gitee.com port 22: Connection timed out fatal: Could not read from remote repos
- 黑马品优购项目的总结二
- zabbix监控nginx的状态
- Linux文件描述符和输入输出重定向