Code Monkey home page Code Monkey logo

Comments (8)

sekoyo avatar sekoyo commented on September 26, 2024 2

Nevermind my fix had a major problem 🤦‍♂️. So the solution I posted before still applies:

.ReactCrop {
  overflow: initial;
}

.ReactCrop__crop-selection {
  box-shadow: none;
}

.ReactCrop__crop-mask {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  clip-path: polygon(
    0% 0%,
    0% 100%,
    var(--pos-x) 100%,
    var(--pos-x) var(--pos-y),
    calc(var(--pos-x) + var(--pos-width)) var(--pos-y),
    calc(var(--pos-x) + var(--pos-width)) calc(var(--pos-y) + var(--pos-height)),
    var(--pos-x) calc(var(--pos-y) + var(--pos-height)),
    var(--pos-x) 100%,
    100% 100%,
    100% 0%
  );
}
<ReactCrop
  ...otherProps...
  style={
    crop
      ? {
          '--pos-x': `${crop.x}%`,
          '--pos-y': `${crop.y}%`,
          '--pos-width': `${crop.width}%`,
          '--pos-height': `${crop.height}%`,
        }
      : undefined
  }
>
  <img ...otherProps.../>
  {crop && <div className="ReactCrop__crop-mask" />}
</ReactCrop>

https://codesandbox.io/s/react-image-crop-demo-with-overflow-allowed-8sd6k6

from react-image-crop.

sekoyo avatar sekoyo commented on September 26, 2024 1

Yes I would like to solve this problem, as you said double image can work but was hesitant to load the image twice due to increased resources used especially on mobile. The alternative is to make a shape with a rectangular hole in it (e.g css clip path or an SVG) but again need to check the perf. I’m away without a computer until mid Feb though so can’t do any work on it yet.

from react-image-crop.

sekoyo avatar sekoyo commented on September 26, 2024 1

I have changed the way this is done now, please try v11

from react-image-crop.

10n37 avatar 10n37 commented on September 26, 2024

Here's is a workaround for who's faced the same issue

index.tsx

import 'react-image-crop/dist/ReactCrop.css'

import cn from 'classnames'
import useResizeObserver from 'use-resize-observer'

import ReactCrop, {
  PercentCrop,
  ReactCropProps,
  Crop as CropValue,
} from 'react-image-crop'
import { FC, useCallback, useLayoutEffect, useRef, useState } from 'react'

import styles from './index.module.scss'

export const Crop: FC<CropProps> = ({ className, src, ...props }) => {
  const [crop, setCrop] = useState<PercentCrop | undefined>()

  const { ref, width, height } = useResizeObserver<HTMLDivElement>()

  const cropValue = props.crop ?? crop

  const cropRef = useRef<ReactCrop | null>(null)
  const viewBoxRef = useRef<HTMLImageElement | null>(null)
  const cropImgRef = useRef<HTMLImageElement | null>(null)

  const classNames = cn(styles.crop, className)

  const setViewBox = useCallback(
    (crop: CropValue) => {
      if (!crop || !width || !height) return
      const { current: cropImage } = cropImgRef

      if (!cropImage) return

      const croppedX = width * (crop.x / 100)
      const croppedY = height * (crop.y / 100)

      const translateX = -croppedX
      const translateY = -croppedY

      cropImage.style.transform = `translateX(${translateX}px) translateY(${translateY}px)`
    },
    [props.crop]
  )

  const onChange: ReactCropProps['onChange'] = (pixelCrop, percentCrop) => {
    if (!width || !height) return

    if (!props.crop) {
      setCrop(percentCrop)
      setViewBox(percentCrop)
    }

    props.onChange?.(pixelCrop, percentCrop)
  }

  useLayoutEffect(() => {
    if (!cropValue) return

    setViewBox(cropValue)
  }, [cropValue])

  return (
    <ReactCrop
      ref={cropRef}
      className={classNames}
      crop={props.crop ?? crop}
      onChange={onChange}
      minHeight={50}
      minWidth={50}
      renderSelectionAddon={() => {
        return (
          <img
            style={{ height, width }}
            ref={cropImgRef}
            src={src}
            className={styles.cropImage}
          />
        )
      }}
    >
      <img
        ref={(originalRef) => {
          ref(originalRef)
          viewBoxRef.current = originalRef
        }}
        src={src}
      />
    </ReactCrop>
  )
}

index.module.scss

.crop {
  overflow: initial;

  :global(.ReactCrop__crop-selection) {
    box-shadow: 0 0 0 99999em rgb(0 0 0 / 50%);
    box-shadow: none;
  }

  :global(.ReactCrop__crop-selection) {
    border: none;
  }

  :global(.ReactCrop__selection-addon) {
    position: inherit;
    overflow: hidden;
    width: 100%;
    height: 100%;
  }

  :global(.ReactCrop__child-wrapper) {
    &:after {
      content: '';
      position: absolute;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
    }
  }

  .cropImage {
    position: sticky;
    z-index: -1;
  }

  :global(.ReactCrop__drag-handle) {
    $width: 8px;

    &:after {
      width: $width;
      height: $width;
      border: 1px solid var(--color-text-main-active);
      outline: none;
      border-radius: 50%;
      background-color: var(--color-primary);
    }
  }
}

from react-image-crop.

sekoyo avatar sekoyo commented on September 26, 2024

Ignore my previous post I realized I was being daft. I published a change which removes overflow:hidden in v 10.0.10 with a simpler solution than I was thinking before.

from react-image-crop.

10n37 avatar 10n37 commented on September 26, 2024

image
Idk why but i faced poor performance when using clip-path

from react-image-crop.

sekoyo avatar sekoyo commented on September 26, 2024

Hm good to know I was wondering about the perf. I guess clip-path+polygon doesn't perform so well. Perhaps even having 4 rectangles (divs) for the shadow on each side of the crop performs better 🤔 Another technique is to have the image rendered twice with the darkened layer in between, and the top image is just showing the crop area

from react-image-crop.

junzero741 avatar junzero741 commented on September 26, 2024

@DominicTobias
First, thank you for your effort on react-image-crop.
but there's a problem that it's not working well with circularCrop prop.
I assume that the reason is your clip-path code is considering only rectangular shape.

image

from react-image-crop.

Related Issues (20)

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.