Giter Site home page Giter Site logo

advanced-cropper / react-advanced-cropper Goto Github PK

View Code? Open in Web Editor NEW
577.0 6.0 26.0 38.06 MB

The react cropper library that embraces power of the advanced cropper core to give the possibility to create croppers that exactly suited for your website design

Home Page: https://advanced-cropper.github.io/react-advanced-cropper/

License: Other

JavaScript 0.97% SCSS 6.21% TypeScript 74.66% CSS 0.35% MDX 17.81%
react cropper react-cropper library image-cropper advanced flexible react-component image-cropping image-manipulation

react-advanced-cropper's Introduction

React Advanced Cropper logo

Downloads Version
Documentation / Examples / Sandbox


โš ๏ธ It's the beta version. The API can be changed in the future. Therefore, it's recommended to fix the version with ~.


React Advanced Cropper is the advanced library that gives you opportunity to create your own croppers suited for any website design. It means that you are able to change not only the cropper appearance, you area able to customize its behavior also.

Features:

  • full mobile / desktop support
  • support all three main types of croppers right out of the box
  • support both canvas and coordinates modes, minimum and maximum aspect ratios, custom size restrictions
  • zoom, rotate, resize image
  • auto-zoom, transitions

Install

npm install --save react-advanced-cropper
yarn add react-advanced-cropper

Usage

import React, { useState } from 'react';
import { CropperRef, Cropper } from 'react-advanced-cropper';
import 'react-advanced-cropper/dist/style.css'

export const GettingStartedExample = () => {
	const [image, setImage] = useState(
		'https://images.unsplash.com/photo-1599140849279-1014532882fe?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1300&q=80',
	);

	const onChange = (cropper: CropperRef) => {
		console.log(cropper.getCoordinates(), cropper.getCanvas());
	};

	return (
		<Cropper
			src={image}
			onChange={onChange}
			className={'cropper'}
		/>
	)
};
/*
  Maybe you need to set the limits for the cropper sizes or its container sizes
  otherwise a cropping image will try to fill all available space
*/
.cropper {
  height: 600px;
  background: #DDD;
}

Cropper

Prop Type Description Default
src string The cropping image (link / base64)
stencilComponent Component The stencil component RectangleStencil
stencilProps object The props for the stencil component {}
className string The optional class for the root cropper block
imageClassName string The optional class for the cropping image
boundariesClassName string The optional class for the area.
backgroundClassName string The optional class for the background under the image
autoZoom boolean Enable / disable transitions true
transitions boolean, object Enable / disable auto zoom false
stencilSize object The size of the stencil in pixels
canvas boolean The flag that indicates if canvas should be used true
minWidth number The minimum width of the stencil (percents)
minHeight number The minimum height of the stencil (percents)
maxWidth number The maximum width of the stencil (percents)
maxHeight number The maximum height of the stencil (percents)
checkOrientation boolean Check if EXIF orientation should be checked true
resizeImage boolean, object The options for the image resizing (details) true
moveImage boolean, object The options for the image moving (details) true
rotateImage boolean, object The options for the image moving (details) false
imageRestriction string Set restrictions for image position ('fillArea' 'fitArea', 'stencil', 'none') 'fillArea'
defaultSize object, Function The function that returns the default size of the stencil or object
defaultPosition object, Function The function that returns the default position of the stencil or object
defaultTransforms object, Function The function that returns the default image transforms or object
wrapperComponent Component The wrapper component CropperWrapper
wrapperProps object The props for the wrapper component {}
backgroundWrapperComponent Component The background wrapper component CropperBackgroundWrapper
backgroundWrapperProps object The props for the background wrapper component {}

See the documentation for more props and details.

RectangleStencil

Prop Type Description Default
aspectRatio number The aspect ratio
minAspectRatio number The minimum aspect ratio
maxAspectRatio number The maximum aspect ratio
className string The class for root block of the stencil component
previewClassName string The class for the preview component
movingClassName string The class applied when user drag the stencil
resizingClassName string The class applied when user resize the stencil
boundingBoxClass string The class for the bounding box component
handlerComponent Component The handler component
handlers object The object of handlers that should be visible or hidden.
handlerClassNames object The object of custom handler classes
handlerWrapperClassNames object The object of custom handler wrapper classes
lineComponent Component The handler component
lines object The object of lines that should be visible or hidden.
lineClassNames object The object of custom line classes
lineWrapperClassNames object The object of custom line wrapper classes

See the documentation for more props and details.

License

The source code of this library is licensed under MIT, the documentation content belongs to Norserium, except the photos that belong to their respective owners.

react-advanced-cropper's People

Contributors

masterlambaster avatar norserium avatar pchr-srf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-advanced-cropper's Issues

editor.setState() is working?

Hello! I want to save the editor state so when I remount it, it saves the previous changes.
But it doesn't seem to work.

editorState is the saved state.
image
image

Here is where I "get" the value store on the useState, but it has the default state anyway.
image

Any idea on how can I achieve this?

Unable to Change Wrapper Color to White

Hi, I have been attempting to change the color of the wrapper
from black to white. Despite my efforts, when I set it to white, I only get a shade of gray. However, if I choose any other color, it appears as expected. Is it possible to have the wrapper in white?

Screenshot 2023-12-07 at 12 47 42

How to handle images that are bigger than the screen

Thanks so much for this great library. I am using it inside a mui.com Dialog and all works fine except for when I have an image that is larger than the screen and then I need to scroll. Is there a solution? I feel like I am missing something very basic.

import { Button, IconButton, Typography } from '@mui/material'
import Box from '@mui/material/Box'
import Dialog from '@mui/material/Dialog'
import { CropperRef, Cropper, Coordinates } from 'react-advanced-cropper'
import 'react-advanced-cropper/dist/style.css'
import { useRef, useState } from 'react'
import CloseIcon from '@mui/icons-material/Close'
import RotateRightIcon from '@mui/icons-material/RotateRight'
import RotateLeftIcon from '@mui/icons-material/RotateLeft'
import FlipIcon from '@mui/icons-material/Flip'

// https://github.com/advanced-cropper/react-advanced-cropper/

interface Props {
  source: string
  handleSave: (form: FormData) => void
  handleClose: () => void
}
export default function ImageCropper(props: Props) {
  const cropperRef = useRef<CropperRef>(null)

  const [coordinates, setCoordinates] = useState<Coordinates | null>(null)

  const onChange = (cropper: CropperRef) => {
    setCoordinates(cropper.getCoordinates())
  }

  // TODO: fix this
  // @ts-ignore
  const defaultSize = ({ imageSize, visibleArea }) => {
    return {
      width: (visibleArea || imageSize).width,
      height: (visibleArea || imageSize).height,
    }
  }

  const handleSave = () => {
    if (cropperRef.current) {
      const canvas = cropperRef.current.getCanvas()
      if (canvas) {
        const form = new FormData()
        canvas.toBlob((blob) => {
          if (blob) {
            form.append('file', blob)
            props.handleSave(form)
          }
        }, 'image/png')
      }
    }
  }

  const handleFlip = (horizontal: boolean, vertical: boolean) => {
    if (cropperRef.current) {
      cropperRef.current.flipImage(horizontal, vertical)
    }
  }
  const handleRotate = (angle: number) => {
    if (cropperRef.current) {
      cropperRef.current.rotateImage(angle)
    }
  }

  const handleReset = () => {
    if (cropperRef.current) {
      cropperRef.current.reset()
    }
  }

  return (
    <Dialog open={true} fullScreen>
      <Box>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', }}>
          <Button variant='outlined' onClick={handleSave}>Save</Button>
          <Box sx={{ display: 'flex', alignItems: 'center' }}>
            <Typography variant="body1">
              Width: {coordinates?.width}&nbsp;
              Height: {coordinates?.height}&nbsp;
              Left: {coordinates?.left}&nbsp;
              Top: {coordinates?.top}&nbsp;
            </Typography>
            <Button variant='outlined' size='small' onClick={handleReset} sx={{ ml: 1 }}>Reset</Button>
            <Button variant='outlined' size='small' onClick={() => handleRotate(-90)} sx={{ ml: 1 }}><RotateLeftIcon /></Button>
            <Button variant='outlined' size='small' onClick={() => handleRotate(90)} sx={{ ml: 1 }}><RotateRightIcon /></Button>
            <Button variant='outlined' size='small' onClick={() => handleFlip(true, false)} sx={{ ml: 1 }}><FlipIcon /></Button>
          </Box>
          <IconButton onClick={props.handleClose}><CloseIcon /></IconButton>
        </Box>
        <Box sx={{ m: 1, maxHeight: '100%' }}>
          <Cropper
            ref={cropperRef}
            src={props.source}
            onChange={onChange}
            stencilProps={{
              grid: true
            }}
            defaultSize={defaultSize}
            className={'cropper'}
          />
        </Box>
      </Box>
    </Dialog>
  )
}

Metadata Getting erased

Hi all ! i am creating a image editor for my school project . i have created all components and successfully implemented editor but when i upload a image after doing some operations when i download that image the metadata is getting erased . but i doesn't want it to disappear . is there anyway to retain metadata ?

Warning: Can't perform a React state update on an unmounted component.

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function

Component that it barks a storm about is AbstractCropperComponent. within useAbstractCropperProps and this is using the FixedCropper.

React: 17
react-advanced-cropper: v0.19.2

Additional icons

We were wondering where can we get additional icons similar to icons that were used in example repo?

Error using in Next JS

I installed react-advanced-cropper in my nextjs 12.2 project and copy pasted the code below

import React, { useState, useRef } from "react";
import { CropperRef, Cropper } from "react-advanced-cropper";
import "react-advanced-cropper/dist/style.css";

const Uploader = () => {
  const [image, setImage] = useState(
    "https://images.unsplash.com/photo-1599140849279-1014532882fe?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1300&q=80"
  );

  const onChange = (cropper: CropperRef) => {
    console.log(cropper.getCoordinates(), cropper.getCanvas());
  };

  return <Cropper src={image} onChange={onChange} className={"cropper"} />;
};

export default Uploader;

I tried to import this Uploader component to a next page and this error popped up.

./node_modules/advanced-cropper/styles/index.scss
Global CSS cannot be imported from within node_modules.
Read more: https://nextjs.org/docs/messages/css-npm
Location: node_modules/react-advanced-cropper/dist/index.esm-bundler.js

This is what nextjs doc says about this case

Please check and let me know!

Preview to Canvas?

Is it possible/feasible to have the dynamic cropper preview image render directly to an HTML Canvas component?

What I have working at the moment is the normal preview to a React component, then on a button press I grab the image and render into an off-screen canvas. It would be very nice instead to be able to render the preview directly into a pre-prepared canvas. I would use this to render the preview image into some scene, and then paint various gradients or whatever over it. But this lacks the "live" update of the preview as it changes.

How to change the image to the stencil view?

Hi there,

I'm trying to set change the image to the stencil view without having to use cropper.getCanvas().toDataURL()
In a way I want the cropper to zoom in to the stencil view port. Is this possible, if yes, how do I accomplish this?

Thanks

How to get cropped area (only inside the stencils)?

I'm trying to crop an image and my stencilComponent is currently set to circle. I'd like the final cropped image to be circular (the part inside of the stencil area). How would I be able to achieve that?
image

Webpack style loader problem

Hello!
I had this problem trying to use react-advanced-cropper with webpack.
Here is my webpack.config:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin

module.exports = {
  entry: './src/index.ts',
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'index.[hash].js'
  },
  devServer: {
    host: '0.0.0.0',
    port: 4040,
    open: true,
    liveReload: true,
    historyApiFallback: true,
    static: {
      directory: path.join(__dirname, 'public')
    }
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.(ts|tsx)?$/,
        loader: 'ts-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './index.html' }),
    new ModuleFederationPlugin({
      name: 'workspace',
      filename: 'remoteEntry.js',
      exposes: { },
      shared: {
        react: { singleton: true, eager: true },
        'react-dom': { singleton: true, eager: true }
      }
    })
  ]
}

I think that is a problem with the style import line at the cropper usage component and it integration with webpack loaders:

import React, { useState } from 'react'
import { CropperRef, Cropper } from 'react-advanced-cropper'
import 'react-advanced-cropper/dist/style.css'

export default () => {
  const [image] = useState(
    'https://images.unsplash.com/photo-1599140849279-1014532882fe?fit=crop&w=1300&q=80'
  )

  const onChange = (cropper: CropperRef) => {
    console.log(cropper.getCoordinates(), cropper.getCanvas())
  }

  return (
    <Cropper
        src={image}
        onChange={onChange}
        className={'cropper'}
    />
  )
}

The styles just not works, so, the cropper not appears.
Thank you!

Set default cropping area?

Maybe a simple thing to do, but I couldn't figure it out:
I want to set the default croppping area (the area with the handles) when initializing a cropper. In my case it should be 100% of the visible image on the screen. To make it less easy: I don't know the visible area in pixel in advance, because of a responsive display.
Any suggestion is appreciated ...

Regards,

How to set rectangular stencil to unchangeable image aspect ratio

Hi
I'm looking for a way to set the stencil aspect ratio to the same value as the loaded image aspect ratio and at the same time prohibit to change this aspect ratio. I think the stencil initially appears with the image aspect ratio, but then a user can change this ratio.
Note, a user should still be able to change the stencil area.

Any ideas?
Thanks

Incorrect typing when following recipes example

Recent update to types in [email protected]

advanced-cropper/advanced-cropper@9e1f9d0#diff-548739e5d5fd25933664a482d08d17882450cb3a3401c3c3c0f3f7c8f390bca1R454

- export function getMimeType(arrayBuffer, fallback = null) {
+ export function getMimeType(arrayBuffer: ArrayBuffer, fallback = null) {

Gives typescript compilation error when using code from recipes#load-image-from-a-disc

Argument of type 'string | ArrayBuffer | null | undefined' is not assignable to parameter of type 'ArrayBuffer'.
  Type 'undefined' is not assignable to type 'ArrayBuffer'.

59           type: getMimeType(e.target?.result, typeFallback),

I think getMimeType should accept string or even null(so it can fallback to 2nd argument)

Applying a transform to the preview only

I would like to apply a rotation transform to only the preview, not the image in the cropper itself.

When I try this, I think I am seeing some weird interaction between the cropper and the wrapper div containing the preview that I rotate that is confusing the calculated size applied to the preview.

For example, if I apply transform: rotate(90deg) to the preview wrapper component, it rotates correctly, but it halves the height of the preview content.

Obviously a normal div wouldn't lose half the height when rotated.

Anyone has any clues or examples on how I might get this working for preview?

`parentSelector` to have Cropper working inside iframe

Hi!
I have a modal (react-modal) attached to a parent iframe (via parentSelector).
Inside this modal I have the Cropper. The wheel event is working, while the cropping handles aren't working.
I think it is because the Cropper attaches events to the current window, while I should have them attached to the iframe document:

window.addEventListener('touchmove', this.onTouchMove, { passive: false });

I think this could be done by adding a parentSelector prop to the Cropper component and, if there is a parentSelector, attaching the events to it, instead of window.

What do you think about it?

Background image not filling the area in modal

Hi I'm having some trouble setting the image to crop.
There is some padding or gap on right and bottom to the crop-able box.
I'm using Next.js

Screenshot 2023-01-11 at 2 42 17 AM
This is how I integrated the the library.

import { CropperRef, Cropper, RectangleStencil } from 'react-advanced-cropper'
import 'react-advanced-cropper/dist/style.css'
import 'react-advanced-cropper/dist/themes/corners.css'

export const InputImageCropper = ({
  id,
  openModal,
  onSave,
  onClose,
  src
  stencilComponent = RectangleStencil,
  ...props
}: Prop) => {
  const cropperRef = useRef<CropperRef>(null)

  return (
    <>
      <Modal
        header="Select image"
        open={openModal}
        onClose={onClose}
        size="xl"
        footer={
          <>
            <Button onClick={onClose} variant="text" color="secondary">
              Cancel
            </Button>
            <Button onClick={onSave}>Save</Button>
          </>
        }
      >
        <Cropper
          ref={cropperRef}
          src={src}
          stencilComponent={stencilComponent}
          {...props}
        />
      </Modal>
    </>
  )
}

Zoom in and out doesn't work properly

zoom functionality doesn't work properly.
if i click on zoom-in even after delay then click on zoom-out it zoom-in the image

import { useEffect, useRef, useState } from "react";
import { Cropper, CircleStencil, CropperPreview } from "react-advanced-cropper";
import "react-advanced-cropper/dist/style.css";

import profile from "@/assets/images/profile.jpg";
import { debounce } from "../ImageCrop/utils/utils";

export default function AdvanceCropper() {
    const [image, setImage] = useState(profile);

    const cropperRef = useRef(null);
    const previewRef = useRef(null);
    const imageRef = useRef(null);
    const zoomRef = useRef(1);

    const [coordinates, setCoordinates] = useState(null);
    const [previewState, setPreviewState] = useState({
        state: null,
        image: null,
        transitions: null,
    });

    const onImageChange = (e) => {
        const { files } = e.target;
        if (files && files[0]) {
            // Create the blob link to the file to optimize performance:
            const blob = URL.createObjectURL(files[0]);
            console.log("blob", blob);
            // Get the image type from the extension. It's the simplest way, though be careful it can lead to an incorrect result:
            setImage(blob);
        } else {
            setImage("");
        }
    };

    const onChange = (cropper) => {
        console.log(cropper.getCoordinates(), cropper.getCanvas());
        // console.log(cropper.getCoordinates(), cropper.getCanvas()?.toDataURL?.()); // toDataURL bad approach
    };

    const onUpdate = (cropper) => {
        setPreviewState({
            state: cropper.getState(),
            image: cropper.getImage(),
            transitions: cropper.getTransitions(),
            loaded: cropper.isLoaded(),
            loading: cropper.isLoading(),
        });
    };

    const zoomIn = (val) => {
        // if (parseFloat(val)) {
        if (zoomRef.current + 1 <= 5) {
            if (cropperRef.current) {
                zoomRef.current += 1;
                console.log(zoomRef.current);
                cropperRef.current.zoomImage(zoomRef.current); // zoom-in 2x
            }
        }
        // }
    };
    const zoomOut = (val) => {
        // if (parseFloat(val)) {
        if (zoomRef.current - 1 >= 0) {
            if (cropperRef.current) {
                zoomRef.current -= 1;
                console.log(zoomRef.current);
                cropperRef.current.zoomImage(zoomRef.current); // zoom-in 2x
            }
        }
        // }
    };

    useEffect(() => {
        return () => {
            if (image) {
                URL.revokeObjectURL(image);
            }
        };
    }, [image]);

    return (
        <section className="advance-cropper-container">
            <section className="image-picker">
                <div className="upload-example">
                    <div className="buttons-wrapper">
                        <button className="button">
                            <label htmlFor="uploadImage">Upload image</label>
                            <input
                                ref={imageRef}
                                type="file"
                                accept="image/*"
                                id="uploadImage"
                                onChange={onImageChange}
                            />
                        </button>
                    </div>
                </div>

                <div className="zoom-actions">
                    <button onClick={debounce(zoomIn, 500)}>Zoom +</button>
                    <button onClick={debounce(zoomOut, 500)}>Zoom -</button>
                </div>
            </section>

            <div className="advance-cropper-settings">
                <Cropper
                    src={image}
                    ref={cropperRef}
                    onChange={onChange}
                    className={"cropper"}
                    stencilProps={{
                        grid: true,
                    }}
                    onUpdate={onUpdate}
                />

                <CropperPreview ref={previewRef} className="preview" {...previewState} />
            </div>
        </section>
    );
}

Minimal required package

Hi
I very much like the react advanced cropper. Got it working quickly.
I'm struggling with the required packaging. I used npm install to fetch everything. Then I found out by trial and error which packages are required to put onto my web server. From the node_modules folder, I've used react-advanced-cropper/dist and also the folders classnames and tslib. This works, but probably not all files are really required to get cropper running.
Is there a packaging which bundles all resources which are minimally required?

Thanks

Replacing CustomBackgroundWrapper with a custom component results in component not working

Description:
When replace the backgroundWrapperComponent provided in FixedCropper, the FixedCropper component doesn't work anymore and renders a white canvas.

Expected Behavior:
Replacing the backgroundWrapperComponent in FixedCropper should maintain the functionalities of the library.

Actual Behavior:
The component renders a white empty canvas

Steps to Reproduce:

  1. Create a custom background wrapper component
    image
  2. Pass it as props to backgroundWrapperComponent in FixedCropper
    image
  3. The result:
    image

Weird stencil behaviour

If you zoom in an image in rectangle mode then switch to circular stencil then the shape of the stencil would be an oval instead of being a circle

2022-09-22.08-58-39.mp4

Typescript Definitions issues

I am trying to use your library and there are some issues where the typescript definitions are throwing errors.

(alias) const CropperFade: FC<Props>
import CropperFade
Type '{ children: Element[]; className: string; visible: boolean; }' is not assignable to type 'IntrinsicAttributes & Props'.
  Property 'children' does not exist on type 'IntrinsicAttributes & Props'.ts(2322)

Is an example of this error.

I noticed the typescript definition outputs the results like this...

import { CSSProperties, FC } from 'react';
interface Props {
    visible?: unknown;
    className?: string;
    style?: CSSProperties;
}
export declare const CropperFade: FC<Props>;
export {};

It feel it is honestly better to use this when trying to support TypeScript etc. And react future versions...

Example of what I think it should be.

import { FC } from 'react';
type Props = {
    visible?: unknown
} & JSX.IntrinsicElements["div"]
export declare const CropperFade: FC<Props>;
export {};

To do this you would need to change the file to look like this

import React, { CSSProperties, FC } from 'react';
import cn from 'classnames';

type Props = {
	visible?: unknown
} & JSX.IntrinsicElements["div"]

export const CropperFade: FC<Props> = ({ visible, className, style, children }) => {
	return (
		<div
			style={style}
			className={cn(className, 'advanced-cropper-fade', Boolean(visible) && 'advanced-cropper-fade--visible')}
		>
			{children}
		</div>
	);
};

How to unzoom outside of image limits

Hi there,
First of all, thanks for this geat component :)

I'm trying to allow unzoom background image more than image limits. It can be useful to crop for example, a logo in horizontal format in a plain square stencil with filling areas outside the image by a default color.
Any idea to do this?

Thanks

resize work reverse in rtl app

Hi,

My app is RTL, so I have set the "dir" property of the "html" tag to "rtl". However, I'm facing an issue when trying to resize the cropper area by dragging its corners. The behavior seems to be reversed. When I drag the corners outward, the crop area becomes smaller, and when I drag them inward, it becomes larger.

I attempted to resolve this problem by changing the CSS direction property of the cropper container to "ltr," but it didn't solve the issue. Could you please advise me on what I should do to fix this problem?

Pass data to wrapperComponent

Hi @Norserium!

In the absolute-zoom Tutorial you explain how to make a custom wrapperComponent which can include a zoom slider.

Now I'd like to have a zoom slider and some buttons to change the ratio of the stencil (which is not difficult). But if the cropper is wrapped in a wrapperComponent which contains the slider, I would also like to put the buttons in the same place. Ideally I would also be able to define the available ratios from the parent component, but I don't know how.

So my question is: How can I pass data to the wrapperComponent?

Blinking issue with the image on page loads.

I have incorporated the CropperFade component to facilitate image display within our application. However, I am experiencing a persistent flickering or blinking effect under specific circumstances. This effect occurs when navigating between pages and returning to our application tab. Notably, the blinking effect, reminiscent of the initial image load, is observed both during the initial loading process and upon switching back to our application tab from another browser tab.

Potential Cause:
After careful examination, it seems that the recurring issue may be related to the re-rendering behavior triggered by the visible prop of the CropperFade component.

Request for Assistance:
I am reaching out to seek your guidance on addressing this concern. If you could provide insights or suggest potential solutions to mitigate the flickering effect associated with the CropperFade component's visible prop, it would greatly assist in enhancing the user experience within our application.

Thank you for your time and attention to this matter. I look forward to your valuable insights and recommendations.

Note: The Issue is only occurring on Safari Browser.

Typescript type issue

Screenshot 2023-05-11 at 2 13 52 PM I Just upgrade the version to 0.19.2 but getting this issue and not getting any solution for that.

Mouse resizing doesn't work

Hi, I'm trying to use react-advanced-cropper in my web application but my problem is that resizing the crop box with mouse doesn't work. resizing, moving and zooming does work with touch input and also zooming works with mouse scroll wheel. i've tested it with version 0.19.4 and 0.19.3. i'm giving the Cropper a base64 image and that's it.no onChange listeners or ref or states.

The image ratio changes while using Cropper Rotation

The image ratio changes while using Cropper Rotation, and it doesn't return to the default position after switching back to the vertical aligment.
The mobile cropper, which allows you to rotate the image without affecting the crop ratio, is exactly how I would like the default behavior to operate. Is it possible to crop an image using the imageEditor component while maintaining auto resize enabled, just like with the mobile cropper? I appreciate you reading and for this fantastic cropper. Thank you!

Screen.Recording.2023-03-13.at.12.42.38.PM.mov

How to set the maximum zoom?

I have been using this library and I have loved it, the documentation is a bit extensive and I am still in the process of reading it completely, therefore I have a question and that is how could I apply a maximum zoom to my images? because currently the user could do some kind of infinite zoom and I would like to restrict this feature to the users of my application

Image position limitations

Thank you for a great library - super happy with it so far!

I would like to get some advise on how to prevent this type of situation when doing image rotation (i.e. the image is not covering the crop area):
image

In the mobile-cropper example, there seems to be some post-transform position adjustments that is implemented. Is there a way to have this type of functionality, using react-advanced-cropper? I'd prefer to not make use of react-mobile-cropper, because it seems to get fewer updates.

Getting the cropped image result as a circle when using CircleStencil

I am using the CircleStencil with the cropper.

I am successfully getting the canvas and calling toBlob to upload the result:

const canvas = cropperRef.current?.getCanvas();

if (canvas) {
	const formData = new FormData();
	canvas.toBlob((blob) => {
		if (blob) {
			formData.append('file', blob, Date.now() + '.jpg');
			// formData uploaded successfully

However, the image uploaded is a square, not a circle.

Is there a way to get the circle-cropped image from the canvas?

Works with Remix?

I am trying to integrate this library into a Remix project, after moving away from react-cropper and cropperjs.

I am struggling because of the SSR constraints inherent with Remix.

I am OK with the cropper being client-side only, but the usual tricks to get a client only component with Remix are not working for me.

For example, I have tried using Suspense as described in this article https://tom-sherman.com/blog/remix-suspense-for-client-only-components and similar I found in Stack Overflow answers.

The problem boils down to this, as soon as I add <Cropper /> to my client-only component, I get this error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function
(for composite components) but got: object. You likely forgot to export your component from
the file it's defined in, or you might have mixed up default and named imports.

If I remove <Cropper /> from my client component, that error goes away and my component renders as expected.

That error message is I think misleading, I know the export is fine, because removing Cropper makes it all work. So I suspect there's some error being thrown when it tries to Render Cropper in this context.

I am on my first Remix project, so I may be missing some knowledge here, but I am totally stuck now.

Should this work? Anyone has any example Remix project with this library integrated?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.