|
@@ -8,11 +8,11 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
componentDidMount () {
|
|
|
- this.cropper = new Cropper(
|
|
|
- this.imgElement,
|
|
|
- this.props.opts.cropperOptions
|
|
|
- )
|
|
|
- if (this.props.opts.actions.granularRotate) {
|
|
|
+ const { opts } = this.props
|
|
|
+
|
|
|
+ this.cropper = new Cropper(this.imgElement, opts.cropperOptions)
|
|
|
+
|
|
|
+ if (opts.actions.granularRotate) {
|
|
|
this.imgElement.addEventListener('crop', (ev) => {
|
|
|
const rotationAngle = ev.detail.rotate
|
|
|
this.setState({
|
|
@@ -29,22 +29,63 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
save = () => {
|
|
|
- this.cropper.getCroppedCanvas()
|
|
|
+ const { opts, save, currentImage } = this.props
|
|
|
+
|
|
|
+ this.cropper.getCroppedCanvas(opts.cropperOptions.croppedCanvasOptions)
|
|
|
.toBlob(
|
|
|
- (blob) => this.props.save(blob),
|
|
|
- this.props.currentImage.type,
|
|
|
- this.props.opts.quality
|
|
|
+ (blob) => save(blob),
|
|
|
+ currentImage.type,
|
|
|
+ opts.quality
|
|
|
)
|
|
|
}
|
|
|
|
|
|
+ granularRotateOnChange = (ev) => {
|
|
|
+ const { rotationAngle, rotationDelta } = this.state
|
|
|
+ const pendingRotationDelta = Number(ev.target.value) - rotationDelta
|
|
|
+ cancelAnimationFrame(this.granularRotateOnInputNextFrame)
|
|
|
+ if (pendingRotationDelta !== 0) {
|
|
|
+ const pendingRotationAngle = rotationAngle + pendingRotationDelta
|
|
|
+ this.granularRotateOnInputNextFrame = requestAnimationFrame(() => {
|
|
|
+ this.cropper.rotateTo(pendingRotationAngle)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ renderGranularRotate () {
|
|
|
+ const { i18n } = this.props
|
|
|
+ const { rotationDelta, rotationAngle } = this.state
|
|
|
+
|
|
|
+ return (
|
|
|
+ // eslint-disable-next-line jsx-a11y/label-has-associated-control
|
|
|
+ <label
|
|
|
+ data-microtip-position="top"
|
|
|
+ role="tooltip"
|
|
|
+ aria-label={`${rotationAngle}º`}
|
|
|
+ className="uppy-ImageCropper-rangeWrapper uppy-u-reset"
|
|
|
+ >
|
|
|
+ <input
|
|
|
+ className="uppy-ImageCropper-range uppy-u-reset"
|
|
|
+ type="range"
|
|
|
+ onInput={this.granularRotateOnChange}
|
|
|
+ onChange={this.granularRotateOnChange}
|
|
|
+ value={rotationDelta}
|
|
|
+ min="-45"
|
|
|
+ max="44"
|
|
|
+ aria-label={i18n('rotate')}
|
|
|
+ />
|
|
|
+ </label>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
renderRevert () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('revert')}
|
|
|
+ aria-label={i18n('revert')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => {
|
|
|
this.cropper.reset()
|
|
|
this.cropper.setAspectRatio(0)
|
|
@@ -59,14 +100,15 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderRotate () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
onClick={() => this.cropper.rotate(-90)}
|
|
|
- aria-label={this.props.i18n('rotate')}
|
|
|
+ aria-label={i18n('rotate')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
|
<path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none" />
|
|
@@ -76,48 +118,15 @@ module.exports = class Editor extends Component {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- granularRotateOnChange = (ev) => {
|
|
|
- const { rotationAngle, rotationDelta } = this.state
|
|
|
- const pendingRotationDelta = Number(ev.target.value) - rotationDelta
|
|
|
- cancelAnimationFrame(this.granularRotateOnInputNextFrame)
|
|
|
- if (pendingRotationDelta !== 0) {
|
|
|
- const pendingRotationAngle = rotationAngle + pendingRotationDelta
|
|
|
- this.granularRotateOnInputNextFrame = requestAnimationFrame(() => {
|
|
|
- this.cropper.rotateTo(pendingRotationAngle)
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- renderGranularRotate () {
|
|
|
- return (
|
|
|
- <label
|
|
|
- data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
- aria-label={`${this.state.rotationAngle}º`}
|
|
|
- className="uppy-ImageCropper-rangeWrapper uppy-u-reset"
|
|
|
- >
|
|
|
- <input
|
|
|
- className="uppy-ImageCropper-range uppy-u-reset"
|
|
|
- type="range"
|
|
|
- onInput={this.granularRotateOnChange}
|
|
|
- onChange={this.granularRotateOnChange}
|
|
|
- value={this.state.rotationDelta}
|
|
|
- min="-45"
|
|
|
- max="44"
|
|
|
- aria-label={this.props.i18n('rotate')}
|
|
|
- />
|
|
|
- </label>
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
renderFlip () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('flipHorizontal')}
|
|
|
+ aria-label={i18n('flipHorizontal')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.scaleX(-this.cropper.getData().scaleX || -1)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -129,13 +138,14 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderZoomIn () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('zoomIn')}
|
|
|
+ aria-label={i18n('zoomIn')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.zoom(0.1)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" height="24" viewBox="0 0 24 24" width="24">
|
|
@@ -148,13 +158,14 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderZoomOut () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('zoomOut')}
|
|
|
+ aria-label={i18n('zoomOut')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.zoom(-0.1)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -166,13 +177,14 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderCropSquare () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('aspectRatioSquare')}
|
|
|
+ aria-label={i18n('aspectRatioSquare')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.setAspectRatio(1)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -184,13 +196,14 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderCropWidescreen () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('aspectRatioLandscape')}
|
|
|
+ aria-label={i18n('aspectRatioLandscape')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.setAspectRatio(16 / 9)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -202,13 +215,14 @@ module.exports = class Editor extends Component {
|
|
|
}
|
|
|
|
|
|
renderCropWidescreenVertical () {
|
|
|
+ const { i18n } = this.props
|
|
|
+
|
|
|
return (
|
|
|
<button
|
|
|
type="button"
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
- aria-label={this.props.i18n('aspectRatioPortrait')}
|
|
|
+ aria-label={i18n('aspectRatioPortrait')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.cropper.setAspectRatio(9 / 16)}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
|
@@ -241,7 +255,6 @@ module.exports = class Editor extends Component {
|
|
|
className="uppy-u-reset uppy-c-btn"
|
|
|
aria-label={i18n('save')}
|
|
|
data-microtip-position="top"
|
|
|
- role="tooltip"
|
|
|
onClick={() => this.save()}
|
|
|
>
|
|
|
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|