推荐! 使用react-cropper-pro实现图片裁切压缩上传

简介: 推荐! 使用react-cropper-pro实现图片裁切压缩上传

在前端开发的过程中, 我们经常遇到文件上传或者图片上传的需求, 有些场景中可能还会要求上传图片后对图片进行裁切, 压缩. 对于不想加班的程序员来说, 第一要义就是使用斯第三方库. 虽然像我们熟悉的antd, element等库提供了上传组件:

image.png

但是这些第三方UI库一方面体积比较庞大, 不够轻量, 另一方面不支持裁切, 压缩等功能, 所以还是需要自己实现或者整合第三方库实现, 当然 antd 提供了一个图片裁切的库 antd-img-crop, 但是使用上极度“难受”(受限), 无法自由裁切图片, 同时也无法提供压缩能力:

image.png

所以这个方案也直接pass. 最终为了实现想要的效果,我还是决定牺牲自己, 手动实现一个支持上传裁切并压缩的组件, 并取名为react-cropper-pro.

image.png

react-cropper-pro 使用介绍

react-cropper-pro是一款简单轻量的图片上传 + 裁切 + 压缩 组件, 不依赖antd / element等第三方UI, 快速实现图片处理相关操作, 底层依赖react-cropper.

安装

yarn add react-cropper-pro

使用

import CropperPro from 'react-cropper-pro';
export default () => 
  <CropperPro 
    defaultImg="" 
    onChange={(file) => console.log(file)} 
    onDel={(image) => console.log('remove', image)} 
  />;

image.png

API介绍

image.png

技术实现

技术上主要有以下几个核心点:

  1. 实现文件上传组件样式(主要是覆盖原生input[file]的“纯洁UI”)
  2. 实现突图片裁切
  3. 实现图片压缩
  4. 包装成react组件并发布到npm

接下来和大家简单介绍一下实现细节.

1. 实现文件上传组件样式

image.png

我们都知道元素的input文件上传组件采用的默认样式非常简陋, 所以我们需要通过某种方式替换原生样式, 这里和大家分享一下我实现的方式.

image.png

其实很简单, 就是用定位的方式将一个同样大小的div覆盖在input上面, 然后把让div事件穿透, 能响应input的事件即可. 核心代码如下:

<div className="xi-cropper-upload">
          <input type="file" onChange={handleChange} accept="image/gif,image/jpeg,image/jpg,image/png" />
          <div className="xi-cropper-file">
          </div>
</div>

其次就是需要用户在上传完图片之后, 图片能展示在上传区域, 如下:

image.png

这块的完整代码如下:

<div className="xi-cropper-upload">
          <input type="file" onChange={handleChange} accept="image/gif,image/jpeg,image/jpg,image/png" />
          <div className="xi-cropper-file">
            {
              cropData ? <img src={cropData} /> : '+'
            }
            {
              !!cropData && <span className="xi-cropper-del" onClick={handleDel}>✕</span> 
            }
          </div>
        </div>

2. 实现突图片裁切

图片裁切这里我采用了 react-cropper 这个库, 虽然不能直接实现图片上传, 但是它的图片裁切能力还是很强大的. 我们需要实现的效果是图片上传后会出现上传弹窗, 显示裁切区域, 如下:

image.png

这里弹窗的实现我采用了React-Dom的createPortal API, 它可以实现弹窗dom挂载在指定的容器上, 很多组件库的组件比如抽屉, Modal, DropDown都采用了类似的实现原理, 我之前也写了一篇文章来介绍如何使用 createPortal 的, 感兴趣的朋友可以学习参考一下:

《精通react/vue组件设计》之配合React Portals实现一个功能强大的抽屉(Drawer)组件

这块的核心源码可以参考github仓库对应的第134行.

文件路径如下: github.com/MrXujiang/r…

3. 实现图片压缩

图片压缩这块主要是基于产品业务场景来设计, 这里我分了4个档:

  • 不压缩

如下:

image.png

这一块主要是利用了canvascropper 的能力, 我们通过控制canvas对象的宽高比例, 和canvas提供的toBlob 来实现图片的压缩, 核心代码如下:

if (typeof cropper !== "undefined") {
      setCropData(cropper.getCroppedCanvas().toDataURL());
      const rate = 1 / (4 - imgLevel);
      const { width, height } = cropper.getCropBoxData();
      cropper.getCroppedCanvas({
        width: width * rate,
        height: height * rate,
        imageSmoothingQuality: imgLevelValueMap[imgLevel],
        fillColor: 'transparent',
      }).toBlob((blob: Blob) => {
        if(blob) {
          const time = Date.now();
          let croppedFile:any = new File([blob], fileRef.current.name, {
            type: fileRef.current.type,
            lastModified: Date.now(),
          });
          croppedFile.uid = time;
          onChange && onChange(croppedFile)
        }else {
          new Error('图片裁切失败');
        }
        
      }, fileRef.current.type, rate)
    }

当然有关 canvastoBlob API不熟悉的朋友可以移步MDN:

developer.mozilla.org/zh-CN/docs/…

4. 包装成react组件并发布到npm

有关如何实现组件库以及如何优雅发布到NPM公仓的技术我之前在《趣谈前端》 也分享过, 感兴趣的朋友可以参考一下: 从零教你搭建组件系统《高级进阶必备》

应用场景

最后再来看看应用场景, 目前 react-cropper-pro 已经应用于H5-Dooring 可视化搭建平台中, 来实现图片更精准的控制:

image.png

感兴趣的朋友可以体验一下, 当然还有很多内容平台, 因为有富文本或者md等编辑器的写作能力, 所以也会涉及到对图片的控制, 所以这些都是 react-cropper-pro 的应用领域.

最后

开源不易, 欢迎搭建一起共建, 点个 star, 让生活更美好.

目录
相关文章
|
存储 缓存 前端开发
Antd Upload + React-Cropper 实现图片自定义区域剪裁并上传功能
通过Upload组件结合react-Cropper实现图片的裁剪上传组件封装,剖析antd-img-crop源码实现的逻辑,对自己封装的组件进行进一步优化,改造!
5567 0
Antd Upload + React-Cropper 实现图片自定义区域剪裁并上传功能
|
移动开发 前端开发 JavaScript
React 图片裁剪组件 Image Cropper
本文介绍了在React中实现图片裁剪功能的方法,涵盖基础知识、常见问题及解决方案。首先,通过第三方库如`react-image-crop`或`cropperjs-react`可轻松实现图片裁剪。接着,针对性能和兼容性问题,提供了优化图片加载、处理裁剪区域响应慢、解决浏览器差异等方案。最后,通过代码案例详细解释了如何创建一个基本的图片裁剪组件,并提出了优化建议,如使用`React.memo`、添加样式支持及处理大图片预览,帮助开发者避免常见错误并提升用户体验。
832 67
|
前端开发
Vue3 element-ui el-upload(上传组件) 上传图片后,隐藏上传按钮
Vue3 element-ui el-upload(上传组件) 上传图片后,隐藏上传按钮
1185 0
|
前端开发 安全 UED
React 文件预览组件:File Preview
在现代Web应用中,文件上传和预览功能至关重要。本文基于React库,详细介绍如何构建文件预览组件,涵盖文件选择器、图片预览、文件大小限制及多种文件类型支持。通过实际代码示例,解析常见问题如跨域请求、文件路径处理和状态管理,并提供解决方案。帮助开发者提升用户体验,减少误操作。
868 2
|
消息中间件 Java Kafka
zookeeper:Unexpected exception, exiting abnormally ::java.io.EOFException
zookeeper:Unexpected exception, exiting abnormally ::java.io.EOFException
606 1
zookeeper:Unexpected exception, exiting abnormally ::java.io.EOFException
|
小程序
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
本文介绍了Taro中`useShareAppMessage`的使用方法,需在页面配置`enableShareAppMessage: true`并重新编译。
918 0
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
弹性盒子的属性
弹性盒子的属性
360 0
|
Web App开发 前端开发 JavaScript
灵魂拷问-前端的作用--chrome插件篇
本文会从浏览器插件应用场景切入,穿插插件基础能力和常见入口的介绍,核心回答如下三个问题:插件可以被使用在哪些场景?不同的使用场景我们的主要代码实现思路是怎样的?我们可以从哪些角度入手自己开发一款可以落地实用的浏览器插件?
|
人工智能 小程序 前端开发
Ant Design Mini 支持微信小程序啦!
Ant Design Mini 支持微信小程序啦!
1121 0
Ant Design Mini 支持微信小程序啦!
|
前端开发 测试技术 开发工具