javascript实现自由编辑图片代码详解


Posted in Javascript onJune 21, 2019

当下我们项目中需要一个可自由编辑图片的功能,当图片可能出现需要频繁编辑,同时能满足发现裁剪不满意想要微调的时候,会发现如果我们处理图片按照平常的习惯,如裁剪后上传服务器或者转base64,都是不符合需求的。那么该怎么处理比较好呢?如何以尽量少的网络请求、少占用存储来解决应用场景呢?那么,便想到了只用纯数据来跟我们的功能打交道。

先安利个裁图神器cropperjs,个人认为是个易上手,配置和api方法蛮齐全的一个组件库。

项目内引入,一定不要漏了引用样式

import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';

这里我们以react为例

this.state = {
width: 640, //图片展示宽
height: 360, //图片展示高 
imgWidth: 640, //图片实际宽
imgHeight: 360, //图片实际高
imgLeft: 0, //图片左偏移
imgTop: 0, //图片上偏移
editing: false //是否编辑中
}
//展示图片的基本dom结构,我们使用外div内img的形式,来跟数据结合控制裁剪图片的展示
const { width, height, imgWidth, imgHeight, imgLeft, imgTop, editing } = this.state;
const containerStyle = {
width: `${width}px`,
height: `${height}px`
}
const imgStyle = {
width: `${imgWidth}px`,
height: `${imgHeight}px`,
left: `${imgLeft}px`,
top: `${imgTop}px`
}
.img-container {
overflow: hidden;
position: relative;
}
.crop-img {
position: absolute;
left: 0;
top: 0;
}
<div 
className="img-container" 
style={containerStyle}
>
<img 
className="crop-img"
src={picture} 
style={imgStyle} 
alt="pic"
></img>
</div>

简单来说就是外层元素控制裁剪展示的宽高,同时根据项目需求的元素定位也挂在这,内部img挂载图片实际大小和偏移。

cropperjs初始化后的元素,是会与初始化对象img处在同一dom层级,也就是说如果我们直接对展示img进行初始化的话,编辑区域展示将会受父元素,如图,放大图片时候会不方查看超出部分

javascript实现自由编辑图片代码详解

所以在这里,为了图片编辑的自由度,建议分开展示dom与用以初始化cropper对象的dom,在这里编辑区域为全屏幕为例,根据项目实际功能区域进行调整

.edit-container {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<div 
className="img-container" 
style={containerStyle}
>
<img 
className="crop-img"
src={picture} 
style={imgStyle} 
alt="pic"
></img>
</div>
//cropper初始化
this.myRef = React.createRef();
this.myCropper = new Cropper(this.myRef.current, options);
//options配置
const options = {
dragMode: 'move', //使裁剪时图片可拖动
background: false, //因为我们现在是全屏可编辑,需要隐藏掉默认的背景
}
//当然还有许多常见的配置项,如编辑框尺寸比例等,大家可自行查看api
//裁剪保存
save() {
const cropBoxData = this.myCropper.getCropBoxData(); //获取裁剪框数据
const canvasData = this.myCropper.getCanvasData(); //获取图片数据
this.setState({
width: cropBoxData.width,
height: cropBoxData.height,
imgLeft: canvasData.left - cropBoxData.left,
imgTop: canvasData.top - cropBoxData.top,
imgWidth: canvasData.width,
imgHeight: canvasData.height
})
}

这样的话 我们就可以完全在自定义的全屏内编辑,保存效果如下,到这里我们就完成了第一部分功能,裁剪并保存数据和展示

javascript实现自由编辑图片代码详解

javascript实现自由编辑图片代码详解

重点介绍下我们用到的两个api方法getCropBoxData和getCanvasData,getCanvasData是用来获取图片的实际数据的(当前的宽高,和相对于父元素可视区域的位移偏移量),getCropBoxData则是获取相对于图片区域的裁剪区相关数据。

那么后续的需求接着来了,我们怎么做到二次编辑的时候,能还原效果呢,嗯,其实在前面我们记录裁图数据的时候,把相应的数据关系再计算一遍就好了,在初始化cropper的options中增加配置

const options = {
dragMode: 'move',
background: false,
//控件初始化后重置相应配置
ready: () => {
const { width, height, imgWidth, imgHeight, imgLeft, imgTop } = this.state;
//根据实际需要出现裁图功能进行定位,此处left和top仅为测试暂时默认值定义
const left = 50; 
const top = 50;
this.myCropper.setCanvasData({
width: imgWidth,
height: imgHeight,
left: left,
top: top
});
this.myCropper.setCropBoxData({
left: left - imgLeft,
top: top - imgTop,
width: width,
height: height
})
}
}
this.myCropper = new Cropper(this.myRef.current, options);

这时候我们再点击裁图,就完美还原了,左边和上边的间隙就是setCanvasData的top和left,根据实际项目进行调整,setCropBoxData的left和top是相对于cropper-canvas的定位,才有了以上的计算形式。

javascript实现自由编辑图片代码详解

此时,基本功能到此结束,如果说是应用在h5编辑中,设计到scale缩放的话,相关的数据计算都要算上scale的缩放值哦,不然就会出现展示图片和编辑图片大小不对等的状况。同时还有许多功能就不做展示了,设置裁剪框比例,编辑缩放等,欢迎尝试。

当然了,如果想要保存图片,也有相应的方法到处裁剪图片的数据

this.myCropper.getCroppedCanvas().toDataURL('image/jpeg')

最后,我们可以看到,在整个功能过程中,我们需要的只是裁剪的数据,读写快,也不需要进行额外的图片存储,减少文件服务器存储的开销与优化。

cropperjs github

感谢大家收看,欢迎讨论和指正。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
读jQuery之十四 (触发事件核心方法)
Aug 23 Javascript
javaScript 利用闭包模拟对象的私有属性
Dec 29 Javascript
Three.js源码阅读笔记(光照部分)
Dec 27 Javascript
JS获取网页属性包括宽、高等等
Apr 03 Javascript
window.location的重写及判断location是否被重写
Sep 04 Javascript
Javascript冒泡排序算法详解
Dec 03 Javascript
js实现鼠标划过给div加透明度的方法
May 25 Javascript
NODE.JS跨域问题的完美解决方案
Oct 20 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
Dec 14 Javascript
理解javascript中的闭包
Jan 11 Javascript
[原创]微信小程序获取网络类型的方法示例
Mar 01 Javascript
Js逆向实现滑动验证码图片还原的示例代码
Mar 10 Javascript
JS中超越现实的匿名函数用法实例分析
Jun 21 #Javascript
微信小程序实现圆形进度条动画
Nov 18 #Javascript
JavaScript迭代器的含义及用法
Jun 21 #Javascript
js事件触发操作实例分析
Jun 21 #Javascript
微信小程序实现下拉刷新动画
Jun 21 #Javascript
vue elementUI使用tabs与导航栏联动
Jun 21 #Javascript
Ajax请求时无法重定向的问题解决代码详解
Jun 21 #Javascript
You might like
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
php实现的debug log日志操作类实例
2016/07/12 PHP
支付宝服务窗API接口开发php版本
2016/07/20 PHP
PHP实现的链式队列结构示例
2017/09/15 PHP
php防止表单重复提交实例讲解
2019/02/11 PHP
jQuery 位置插件
2008/12/25 Javascript
JavaScript中的this实例分析
2011/04/28 Javascript
JS文本框不能输入空格验证方法
2013/03/19 Javascript
js格式化时间和js格式化时间戳示例
2014/02/10 Javascript
javascript 回到顶部效果的实现代码
2014/02/17 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
2016/01/14 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
JS兼容所有浏览器的DOMContentLoaded事件
2018/01/12 Javascript
JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
2018/08/09 Javascript
Angular6 写一个简单的Select组件示例
2018/08/20 Javascript
小程序云开发实现数据库异步操作同步化
2019/05/18 Javascript
python网络编程实例简析
2014/09/26 Python
Python中的map()函数和reduce()函数的用法
2015/04/27 Python
python表格存取的方法
2018/03/07 Python
详解python3中的真值测试
2018/08/13 Python
Python Pandas批量读取csv文件到dataframe的方法
2018/10/08 Python
python做反被爬保护的方法
2019/07/01 Python
Python的赋值、深拷贝与浅拷贝的区别详解
2020/02/12 Python
Lungolivigno Fashion官网:高级时装在线购物
2020/10/17 全球购物
个人实用的自我评价范文
2013/11/23 职场文书
《雪地里的小画家》教学反思
2014/02/22 职场文书
精彩的演讲稿开头
2014/05/08 职场文书
开展读书活动总结
2014/06/30 职场文书
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
简单租房协议书(范本)
2014/10/13 职场文书
综合管理员岗位职责
2015/02/11 职场文书
mysql 直接拷贝data 目录下文件还原数据的实现
2021/07/25 MySQL
Java Spring Boot 正确读取配置文件中的属性的值
2022/04/20 Java/Android
PYTHON InceptionV3模型的复现详解
2022/05/06 Python