Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 3x 3x 3x 3x 3x 3x 3x 3x 1x 1x | import {useCallback, useState} from 'react' import PropTypes from 'prop-types' import {debounce} from '@s-ui/js/lib/function/debounce.js' import Injector from '@s-ui/react-primitive-injector' import getCroppedImg from './utils/cropImage.js' import {baseClass, DEFAULT_ASPECT, getRotationDegrees, noop} from './config.js' import ImageEditorCropper from './ImageEditorCropper.js' import ImageEditorDefault from './ImageEditorDefault.js' import ImageEditorSliders from './ImageEditorSliders.js' import {debouncingTimePropType} from './prop-types.js' const MoleculeImageEditor = ({ aspect = DEFAULT_ASPECT, cropLabelIcon, cropLabelText, debouncingTime, image, onChange, onCropping = noop, rotateLabelIcon, rotateLabelText, children = <ImageEditorDefault /> }) => { const [crop, cropSetter] = useState({x: 0, y: 0}) const [rotation, rotationSetter] = useState(0) const [zoom, zoomSetter] = useState(0) const setCrop = debouncingTime === undefined ? cropSetter : debounce(cropSetter, debouncingTime) const setRotation = debouncingTime === undefined ? rotationSetter : debounce(rotationSetter, debouncingTime) const setZoom = debouncingTime === undefined ? zoomSetter : debounce(zoomSetter, debouncingTime) const onCropComplete = useCallback( async (croppedArea, croppedAreaPixels, ...args) => { const cropCompleteHandler = async () => { const rotationDegrees = getRotationDegrees(rotation) onCropping(true) const [croppedImageUrl, croppedImageBlobObject] = await getCroppedImg(image, croppedAreaPixels, rotationDegrees) onChange(croppedImageUrl, croppedImageBlobObject) onCropping(false) } const callback = debouncingTime === undefined ? cropCompleteHandler : debounce(cropCompleteHandler, debouncingTime) await callback(croppedArea, croppedAreaPixels, ...args) }, [rotation, onCropping, image, onChange, debouncingTime] ) return ( <div className={baseClass}> <Injector image={image} crop={crop} zoom={zoom} rotation={rotation} aspect={aspect} onCropChange={setCrop} onCropComplete={onCropComplete} onRotationChange={setRotation} onZoomChange={zoom => setZoom((zoom - 1) * 100)} rotateLabelIcon={rotateLabelIcon} rotateLabelText={rotateLabelText} cropLabelIcon={cropLabelIcon} cropLabelText={cropLabelText} onZoomSliderChange={(event, {value}) => setZoom(value)} onRotateSliderChange={(event, {value}) => setRotation(value)} > {children} </Injector> </div> ) } MoleculeImageEditor.displayName = 'MoleculeImageEditor' MoleculeImageEditor.propTypes = { aspect: PropTypes.number, cropLabelIcon: PropTypes.node, cropLabelText: PropTypes.string, debouncingTime: debouncingTimePropType, image: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, onCropping: PropTypes.func, rotateLabelIcon: PropTypes.node, rotateLabelText: PropTypes.string, children: PropTypes.node } export default MoleculeImageEditor export {ImageEditorCropper as MoleculeImageEditorCropper, ImageEditorSliders as MoleculeImageEditorSliders} |