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 相关文章推荐
firefox中JS读取XML文件
Dec 21 Javascript
使一个函数作为另外一个函数的参数来运行的javascript代码
Aug 13 Javascript
发一个自己用JS写的实用看图工具实现代码
Jul 26 Javascript
javascript void(0)的妙用
Oct 21 Javascript
javascript 最常用的10个自定义函数[推荐]
Dec 26 Javascript
基于prototype扩展的JavaScript常用函数库
Nov 30 Javascript
文本框根据输入内容自适应高度的代码
Oct 24 Javascript
jquery ajax jsonp跨域调用实例代码
Dec 11 Javascript
jQuery绑定事件-多种实现方式总结
May 09 Javascript
VUE中v-model和v-for指令详解
Jun 23 Javascript
原生js实现密码输入框值的显示隐藏
Jul 17 Javascript
jquery点击回车键实现登录效果并默认焦点的方法
Mar 09 jQuery
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
Apache, PHP在Windows 9x/NT下的安装与配置 (一)
2006/10/09 PHP
php 文件缓存函数
2011/10/08 PHP
PHP 多维数组的排序问题 根据二维数组中某个项排序
2011/11/09 PHP
php获取网页标题和内容函数(不包含html标签)
2014/02/03 PHP
PHP函数import_request_variables()用法分析
2016/04/02 PHP
在 Laravel 项目中使用 webpack-encore的方法
2019/07/21 PHP
可以将word转成html的js代码
2010/04/11 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
IE6 fixed的完美解决方案
2011/03/31 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
2014/08/30 Javascript
JavaScript处理解析JSON数据过程详解
2015/09/11 Javascript
JavaScript程序设计之JS调试
2015/12/09 Javascript
原生JavaScript编写canvas版的连连看游戏
2016/05/29 Javascript
js return返回多个值,通过对象的属性访问方法
2017/02/21 Javascript
详解如何在angular2中获取节点
2017/11/23 Javascript
axios中cookie跨域及相关配置示例详解
2017/12/20 Javascript
vue结合element-ui使用示例
2019/01/24 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
2020/05/24 Javascript
python中wx将图标显示在右下角的脚本代码
2013/03/08 Python
Python FTP操作类代码分享
2014/05/13 Python
python使用多线程不断刷新网页的方法
2015/03/31 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
2017/01/28 Python
Python使用修饰器执行函数的参数检查功能示例
2017/09/26 Python
Pandas DataFrame数据的更改、插入新增的列和行的方法
2019/06/25 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
Sperry澳大利亚官网:源自美国帆船鞋创始品牌
2019/07/29 全球购物
马来西亚在线健康商店:Medipal Malaysia
2020/04/13 全球购物
管理专员自荐信
2014/01/26 职场文书
《美丽的田园》教学反思
2014/03/01 职场文书
农业局学习党的群众路线教育实践活动心得体会
2014/03/07 职场文书
幼儿园家长评语大全
2014/04/16 职场文书
党支部考察鉴定意见
2015/06/02 职场文书
SSM项目使用拦截器实现登录验证功能
2022/01/22 Java/Android