添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

最近写项目,遇到一个有意思的需求,分享一下实现过程:

需求简单描述:对现有图片(网络路径)进行裁剪,也可以上传一张图片进行裁剪,旋转,达到自己想要的效果。

应用技术:react hook,ant-design,react-cropper(插件)

项目中需要安装插件:

npm install react-cropper --save-dev

注:这里用的react-crooper 版本号 @1.2.0 ,不同版本存在使用中的差异,所以这里注明当前例子使用的是1.2.0。

组件中引用:

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

注:因项目中webpack配置的打包编译在css-loader这一块配置的时候,exclude 了node_module包中对css的编译,导致引入插件后编译通不过,需要 【include: [/[\\/]node_modules[\\/].*cropperjs/],】添加对cropperjs中的css进行编译操作。

父组件操作:

import React from 'react'
import CropperModal from './CropperModal'
import { getBase64Image, main } from 'utils'
const url = 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
export default () => {
    const [hooksModalFile,setHooksModalFile] = React.useState();
    const [modalVisible, setModalVisible] = React.useState();
    useEffect(()=>{
        main(userDetail.avatarUrl, (base64) => {
            const file = base64toFile(base64, '图片名称');
            setHooksModalFile(file);
            setModalVisible(true);
    },[hooksModalFile]);
    const getNewImgUrl = (event) => {
        // 转化后,并且已上传到图片库中的图片路径
    return <CropperModal
            uploadedImageFile={hooksModalFile}
            onClose={() => {
              setModalVisible(false);
            onSubmit={getNewImgUrl}

具体实现:

import React, { useState, useEffect, useCallback, useRef } from 'react'
import { Button, Upload } from 'antd';
import Cropper from 'react-cropper' // 引入Cropper
import 'cropperjs/dist/cropper.css' // 引入Cropper对应的css
import './index.scss'
export default ({ uploadedImageFile, onClose, onSubmit }) => {
  const [src, setSrc] = useState(null);
  const [fileList, setFileList] = React.useState([]);
  const cropperRef = useRef(null);
  const uploadProps = {
        beforeUpload: file1 => {
            setFileList([file1]);
            setIsShow(false);
            const fileReader = new FileReader();
            fileReader.onload = e => {
                const dataURL = e.target.result;
                setNewSrc(dataURL);
            fileReader.readAsDataURL(file1);
            return false;
        multiple: false,
        accept: '.png, .jpeg, .jpg',
  useEffect(() => {
    const fileReader = new FileReader()
    fileReader.onload = e => {
      const dataURL = e.target.result
      setSrc(dataURL)
    fileReader.readAsDataURL(uploadedImageFile)
  }, [uploadedImageFile])
  const handleSubmit = useCallback(() => {
    console.log('正在上传图片')
    // TODO: 这里可以尝试修改上传图片的尺寸
    cropperRef.current.getCroppedCanvas().toBlob(async blob => {
      console.log('blob', blob);
      // 创造提交表单数据对象
      const formData = new FormData()
      // 添加要上传的文件
      // formData.append('file', blob, filename)
      // 提示开始上传 (因为demo没有后端server, 所以这里代码我注释掉了, 这里是上传到服务器并拿到返回数据的代码)
      // 上传图片
      // 此处实现上传操作 ajax请求
      // 提示上传完毕
      //把选中裁切好的的图片传出去
      onSubmit(blob)
      // 关闭弹窗
      onClose()
  }, [onClose, onSubmit])
  return (
    <div className="hooks-cropper-modal">
      <div className="modal-panel">
        <div className="cropper-container-container">
          <div className="cropper-container">
            <Cropper
              src={src}
              className="cropper"
              ref={cropperRef}
              // Cropper.js options
              viewMode={1}
              zoomable={true}
              aspectRatio={1} // 固定为1:1  可以自己设置比例, 默认情况为自由比例
              guides={false}
              rotatable={true} // rotatable true 可旋转图片
              preview=".cropper-preview" // 预览的窗帘样式类名指定
          <div className="preview-container">
            <div className="cropper-preview" />
        <div className="button-row">
               <Upload
                listType="text"
                fileList={fileList}
                {...uploadProps}
                <Button type="default">替换封面</Button>
              </Upload>
          <div className="submit-button" onClick={handleSubmit}>

工具准备:

1. 需要将拿到的网络图片地址url,转化为文件类型格式(转化方式:a.需要将url转化为base64格式;b. base64格式转为文件类型)

const getBase64Image = (img) => {
  const canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0, img.width, img.height);
  const dataURL = canvas.toDataURL('image/png'); // 可选其他值 image/jpeg
  return dataURL;
const main = (src, cb) => {
  const image = new Image();
  image.src = `${src}?v=${Math.random()}`; // 处理缓存
  image.crossOrigin = '*'; // 支持跨域图片
  image.onload = function() {
    const base64 = getBase64Image(image);
    cb && cb(base64);
export { getBase64Image, main };

图片添加旋转功能:

const rotateClick = () => {
    console.log('cropperRef',cropperRef.current)
    cropperRef.current.cropper.rotate(90);

index.sass文件:

.hooks-cropper-modal {
  position: fixed;
  background-color: rgba(#000000, 0.3);
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  .modal-panel {
    width: 880px;
    height: 500px;
    background: white;
    padding: 20px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    .button-row {
      height: 50px;
      flex-shrink: 0;
      display: flex;
      justify-content: center;
      .submit-button {
        padding: 0 20px;
        height: 100%;
        color: #383838;
        font-size: 14px;
    .cropper-container-container {
      flex: 1;
      display: flex;
      align-items: stretch;
      justify-content: space-between;
      height: 100%;
      .cropper-container {
        flex: 0 0 600px;
        margin-right: 20px;
        .cropper {
          width: 100%;
          height: 100%;
      .preview-container {
        flex: 1;
        display: flex;
        align-items: flex-end;
        .cropper-preview {
          width: 180px;
          height: 180px;
          overflow: hidden;
          border: 1px solid #383838;

此次实现过程时间较短,功能实现相对粗糙了些,但基本需求效果均已实现,欢迎大佬们提出你的宝贵建议。

最近写项目,遇到一个有意思的需求,分享一下实现过程:需求简单描述:对现有图片(网络路径)进行裁剪,也可以上传一张图片进行裁剪,旋转,达到自己想要的效果。应用技术:react hook,ant-design,react-cropper(插件)项目中需要安装插件:npm install react-cropper --save-dev注:这里用的react-crooper 版本号 @1.2.0 ,不同版本存在使用中的差异,所以这里注明当前例子使用的是1.2.0。组件中引用:imp npm install --save react-cropper 您的项目中需要cropper.css ,来自 。 由于此项目依赖于 ,因此,对于更高版本的npm 3.0.0 ,它位于/node_modules/react-cropper/node_modules/cropperjs/dist/cropper.css或node_modules/cropperjs/dist/cropper.css中 重大更改(版本> = 2.0.0) 对ref支持已被删除。 使用onInitialized方法来获取cropper实例。 在2.
1. 安装 react-cropper npm install --save react-cropper //或者 yarn add react-cropper 2. 组件内引入 import Cropper from "react-cropper"; // 引入Cropper import "cropperjs/dist/cropper.css"; // 引入Cropper对应的css 3. 函数式组件 1. jsx文件 import { useState } from 'react';
最近公司项目在做一个求职工具类的小程序,小程序端有企业Logo的显示,为了保证图在小程序端的展示效果,所以要求在后台管理系统进行企业Logo上传时需要限定上传的图尺寸和比例。 为了减少管理人员的录入成本,需要在Logo上传前进行裁剪操作,保证上传进来的图都是规则的正方。,此处用到了react-cropper组件,本文主要介绍了react-cropper组件在Ant Design Pro项目中...
首先需要安装 react-avatar-editor 库: npm install --save react-avatar-editor 手机端的页面,我用的是material-ui的组件 import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogAct
使用 React+typescript 的组件库 react实现图的放大、缩小、旋转及移动功能组件 npm install react-image-zoom --save // 引入组件 import { ImgZoom } from 'react-image-zoom' // 代码示例 <ImgZoom dataSource={{ ImgZoom Component property propType required default description dataSource object url: '', scale: 1, rotate: 0, src={src}//图url style={{ height: 300, width: "100%" }} autoCropArea={1} // 默认裁剪框与画布比例 rotatable // 旋转 ref={crop.
可以看到对于图的缩放、旋转、下一张,反转等,符合我们做图展示框架的要求。 安装viewjs 因为前端使用的是react,所以我们找到一个viewjs的react实现, 项目引入:"react-viewer": "^3.2.1", 或:npm install react-viewer --save 在render函数里加入如下代码 view 遮罩 <Viewer visible={thi React-saga和React-thunk都是用于处理异步操作的中间件。 React-thunk是Redux官方推荐的中间件之一,它允许我们在Redux中编写异步操作,使得我们可以在Redux中处理异步操作,而不需要在组件中处理异步操作。Thunk是一个函数,它接收dispatch和getState作为参数,并返回一个函数,这个函数接收dispatch作为参数,并在异步操作完成后调用dispatch。 React-saga是另一个处理异步操作的中间件,它使用了ES6的Generator函数来处理异步操作。Saga使用了一种称为Effect的概念,它是一个简单的JavaScript对象,用于描述异步操作。Saga使用了一种称为yield的语法,它允许我们在Generator函数中暂停异步操作,并在异步操作完成后继续执行。 总的来说,React-thunk和React-saga都是用于处理异步操作的中间件,它们的实现方式不同,但都可以让我们在Redux中处理异步操作。选择哪种中间件取决于个人的喜好和项目的需求。 ### 回答2: React-Saga和React-Thunk都是React应用中用于处理异步操作的中间件。它们的主要目的是在Redux应用中,帮助我们管理异步操作。这两个中间件都可以让React应用更加的灵活、健壮和易于维护。 React-Saga的核心理念是利用生成器函数来处理异步操作,Saga通过使用生成器来让异步操作变得像同步操作一样,其中每个异步操作都会被转化为一个迭代器函数,这些函数可以被Saga调用和暂停。 Saga主要有以下几个特点: 1. Saga可以使异步操作更加同步和简单,让异步调用变得更容易。Saga使用了轻量级、高效的生成器函数,从而有效地减少了异步调用中的代码复杂度。 2. Saga可以很好地管理和协调多个异步操作。Saga可以在任意阶段暂停异步操作,等待其他异步操作完成之后再继续执行。 3. Saga可以捕获和控制异步操作的错误、超时和状态。当出现问题时,Saga可以修复错误或者更改异步操作的状态,保证应用程序的稳定性和可靠性。 React-Thunk的核心概念是利用闭包函数来处理异步操作,Thunk将异步操作转化为一个闭包函数,然后通过回调函数将其传递到Redux的异步流中。 Thunk的主要特点有以下几个: 1. Thunk可以轻松处理异步操作,没有复杂的代码逻辑或者概念。 2. Thunk主要使用了闭包函数来捕捉当前异步操作的上下文,使得处理异步操作更加的简单、方便和自然。 3. Thunk可以轻松控制异步操作的状态、结果和错误处理,保证应用程序的稳定性和可靠性。 总之,React-Saga和React-Thunk都是帮助我们管理和处理应用程序的异步操作的中间件。它们都有自己独特的实现方式和特点。我们可以根据自己的项目需求和开发团队的技能水平来选择适合我们的中间件。 ### 回答3: React-saga 和 React-thunk 都是针对 React 应用中异步操作的中间件。它们两个都可以用来控制异步流程,使得我们可以更好的管理 React 应用程序中异步操作的数据和状态。 相较于 react-thunk, react-saga 是一个更加强大的中间件,它基于 generator 函数的概念,可以用来控制非常复杂的异步流程,使得我们可以在操作时更加精细地掌控多个异步操作的执行顺序和状态。 如果说 react-thunk 的核心概念是将异步操作封装进一个函数里,而在需要时调用这个函数即可,那么 redux-saga 的核心概念则是分离出一个独立的 Generator 函数来代表所有的异步业务逻辑。 redux-saga 可以让你从另一个角度处理异步流程,使你能够同步处理异步操作,不同的 Saga 可以用一种集中且易于理解的方式组合起来,组成它们自己的执行序列。 总而言之,React-saga和React-thunk 都是 React 应用程序开发中非常实用的工具,对于管理异步操作和数据状态非常有帮助。但是针对不同的开发需求,我们需要选择相应的中间件,来实现我们最好的业务逻辑。所以我们在使用的时候需要根据实际情况选择适合的中间件进行操作,以达到最好的效果。 认真的小孩有糖吃: virtual Dom 是一种编程思想.这个概念里,UI以一种理想化的,或者说’虚拟的’表现形式保存于内存中,通过ReactDom等类库使之与真实的Dom同步,这个过程叫做协调(diff) 由于真实dom 过于庞大,每个真实dom对象 都存在非常多的属性,并且这些属性很多使用不到,如果去对比真实dom之间的差异,操作太慢,成本太高,并且轻微的操作都会导致页面的重新排版,非常消耗性能 相对于dom对象,js对象处理就非常快啦,在内存中通过diff算法对比新旧js对象,可以批量,最小化的执行dom操作,提高性能