javascript实现*编辑图片代码详解
当下我们项目中需要一个可*编辑图片的功能,当图片可能出现需要频繁编辑,同时能满足发现裁剪不满意想要微调的时候,会发现如果我们处理图片按照平常的习惯,如裁剪后上传服务器或者转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进行初始化的话,编辑区域展示将会受父元素,如图,放大图片时候会不方查看超出部分
所以在这里,为了图片编辑的*度,建议分开展示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 }) }
这样的话 我们就可以完全在自定义的全屏内编辑,保存效果如下,到这里我们就完成了第一部分功能,裁剪并保存数据和展示
重点介绍下我们用到的两个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的定位,才有了以上的计算形式。
此时,基本功能到此结束,如果说是应用在h5编辑中,设计到scale缩放的话,相关的数据计算都要算上scale的缩放值哦,不然就会出现展示图片和编辑图片大小不对等的状况。同时还有许多功能就不做展示了,设置裁剪框比例,编辑缩放等,欢迎尝试。
当然了,如果想要保存图片,也有相应的方法到处裁剪图片的数据
this.mycropper.getcroppedcanvas().todataurl('image/jpeg')
最后,我们可以看到,在整个功能过程中,我们需要的只是裁剪的数据,读写快,也不需要进行额外的图片存储,减少文件服务器存储的开销与优化。
感谢大家收看,欢迎讨论和指正。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Javascript实现图片不间断滚动的代码
-
javascript实现图片切换的幻灯片效果源代码
-
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
-
javascript判断回文数详解及实现代码
-
图文详解Heap Sort堆排序算法及JavaScript的代码实现
-
Javascript实现图片不间断滚动的代码
-
在Asp.Net Core中配置使用MarkDown富文本编辑器实现图片上传和截图上传(开源代码.net core3.0)
-
使用 Node.js 实现图片的动态裁切及算法实例代码详解
-
javascript实现*编辑图片代码详解
-
javascript 指定区域内图片等比例缩放实现代码 脚本之家整合版 原创