index.md 7.8 KB


localeCode: zh-CN order: 69 category: Plus title: Cropper 图片裁切 icon: doc-cropper dir: column brief: 通过设定裁切框的宽高比例,自由裁切图片

showNew: true

使用场景

Cropper 用于裁切图片,支持自定义裁切框样式,可通过拖动调整裁切框位置,被裁切图片位置;可缩放,旋转被裁切图片。

代码演示

如何引入

Cropper 从 v2.73.0 开始支持

import { Cropper } from '@douyinfe/semi-ui';

基本用法

通过 sr 设置被裁切的图片; 可通过 shape 设置裁切框形状,默认为方形。

import { Cropper, Button, RadioGroup, Radio } from '@douyinfe/semi-ui';

const containerStyle = {
  width: 550,
  height: 300,
  margin: 20,
}

function Demo() {
    const ref = useRef(null);
  const [shape, setShape] = useState('rect');

    const onButtonClick = useCallback(() => {
        const value = ref.current.getCropperCanvas();
        const previewContainer = document.getElementById('previewContainer');
        previewContainer.innerHTML = '';
        previewContainer.appendChild(value);
    }, []);

    const onShapeChange = useCallback((e) => {
        setShape(e.target.value);
    }, []);

    return <>
        <RadioGroup onChange={onShapeChange} value={shape}>
            <Radio value={'rect'}>rect</Radio>
            <Radio value={'round'}>round</Radio>
            <Radio value={'roundRect'}>roundRect</Radio>
        </RadioGroup>
        <Cropper
            ref={ref} 
            src={'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/other/image.png'}
            style={containerStyle}
            shape={shape}
        />
        <Button onClick={onButtonClick}>裁切</Button>
        <div id='previewContainer'/>
    </>;
}

render(<Demo />)

自定义裁切框比例

可通过 defaultAspectRatio 初始的裁切框比例(默认为 1)。可通过 aspectRatio 设置固定的裁切框比例。

设置 defaultAspectRatio仅对初始的裁切框比例生效, 拖动时,裁切框比例会随着拖动而变化。

设置 aspectRatio 时,裁切框比例固定,拖动时将裁切框将以此比例变化。

import { Cropper, Button, RadioGroup, Radio } from '@douyinfe/semi-ui';

const containerStyle = {
  width: 550,
  height: 300,
  margin: 20,
}

function Demo() {
    const ref = useRef(null);
    const shape = useState('rect');

    const onButtonClick = useCallback(() => {
        const value = ref.current.getCropperCanvas();
        const previewContainer = document.getElementById('previewContainer-aspect');
        previewContainer.innerHTML = '';
        previewContainer.appendChild(value);
    }, []);

    return <>
        <Cropper
            aspectRatio={3/4}
            ref={ref} 
            src={'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/other/image.png'}
            style={containerStyle}
        />
        <Button onClick={onButtonClick}>裁切</Button>
        <div id='previewContainer-aspect' />
    </>;
}

render(<Demo />)

受控旋转/缩放图片

通过 rotatezoom 控制图片旋转和缩放, 可通过 onZoomChange 拿到最新的 zoom 值。

import { Cropper, Button, Slider } from '@douyinfe/semi-ui';

const containerStyle = {
  width: 550,
  height: 300,
  margin: 20,
}

const actionStyle = {
  marginTop: 20,
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  width: 'fit-content'
}

function Demo() {
  const [rotate, setRotate] = useState(0);
  const [zoom, setZoom] = useState(1);
  const ref = useRef();

  const onZoomChange = useCallback((value) => {
    setZoom(value);
  })

  const onSliderChange = useCallback((value) => {
    setRotate(value);
  }, []);

  const onButtonClick = useCallback(() => {
    const value = ref.current.getCropperCanvas();
    const previewContainer = document.getElementById('previewContainer-control');
    previewContainer.innerHTML = '';
    previewContainer.appendChild(value);
  }, []);

  return (
      <div id='cropper-container'>
           <Cropper 
              ref={ref} 
              src={'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/other/image.png'}
              style={containerStyle}
              rotate={rotate}
              zoom={zoom}
              onZoomChange={onZoomChange}
           />
           <div style={actionStyle} >
            <span>Rotate</span>
            <Slider
              style={{ width: 500}}
              value={rotate}
              step={1}
              min={-360}
              max={360}
              onChange={onSliderChange}
            />
           </div>
           <div style={actionStyle} >
            <span>Zoom</span>
            <Slider
              style={{ width: 500}}
              value={zoom}
              step={0.1}
              min={0.1}
              max={3}
              onChange={onZoomChange}
            />
           </div>
           <br />
           <Button onClick={onButtonClick}>裁切</Button>
           <br />
           <div 
            // style={{ background: 'pink' }} 
           >
            <div id='previewContainer-control'
            />
          </div>
      </div>
  );
};

render(<Demo />)

裁切框设置

可通过 cropperBoxStyle, cropperBoxClassName 自定义裁切框样式。可通过 showResizeBox 设置是否展示裁切框边角的调整块。

import { Cropper, Button, Switch } from '@douyinfe/semi-ui';

const containerStyle = {
  width: 550,
  height: 300,
  margin: 20,
}

const centerStyle = {
    display: 'flex', 
    alignItems: 'center', 
    justifyContent: 'center',
    width: 'fit-content'
}

function Demo() {
    const ref = useRef(null);

    const onButtonClick = useCallback(() => {
        const value = ref.current.getCropperCanvas();
        const previewContainer = document.getElementById('previewContainer-cropperBox');
        previewContainer.innerHTML = '';
        previewContainer.appendChild(value);
    }, []);

    return <>
        <strong>showResizeBox = false,并修改边框颜色</strong>
        <Cropper
            ref={ref} 
            src={'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/other/image.png'}
            style={containerStyle}
            cropperBoxStyle={{ outlineColor: 'var(--semi-color-bg-0)'}}
            showResizeBox={false}
        />
        <Button onClick={onButtonClick}>裁切</Button>
        <div id='previewContainer-cropperBox'/>
    </>;
}

render(<Demo />)

API

属性 说明 类型 默认值
aspectRatio 裁切框比例 number -
className 类名 string -
cropperBoxClassName 裁切框类名 string -
cropperBoxStyle 裁切框样式 CSSProperties -
defaultAspectRatio 初始裁切框比例 number 1
imgProps 透传给 img 标签的属性 object -
fill 裁切结果中非图片部分的填充色 string 'rgba(0, 0, 0, 0)'
maxZoom 最大缩放倍数 number 3
minZoom 最小缩放倍数 number 0.1
onZoomChange 缩放回调 (zoom: number) => void -
rotate 旋转角度 number -
shape 裁切框形状 'rect' | 'round' | 'roundRect' 'rect'
src 图片地址 string -
showResizeBox 是否展示调整块 boolean true
style 样式 CSSProperties -
zoom 缩放比例 number -
zoomStep 缩放步长 number 0.1

Methods

绑定在组件实例上的方法,可以通过 ref 调用实现某些特殊交互

Name Description
getCropperCanvas 获取裁剪图片的 canvas

设计变量