Releases: ValentinH/react-easy-crop
v4.1.3
Sorry for the spam, this version and the previous one were not meant to be released 🙈
⚠️ Pushed to main
- docs: add badge for auto [skip-ci] (@ValentinH)
Authors: 1
- Valentin Hervieu (@ValentinH)
v4.1.2
⚠️ Pushed to main
- docs: update CircleCI badge [skip-ci] (@ValentinH)
Authors: 1
- Valentin Hervieu (@ValentinH)
v4.1.1
Chores
- ci: fix publishFolder #364 (@ValentinH)
- chore: add auto for releasing in CI #363 (@ValentinH)
⚠️ Pushed to main
- ci: fix missing command to pull tags (@ValentinH)
- docs: fix typo (@ValentinH)
- Update README.md (@ValentinH)
Authors: 1
- Valentin Hervieu (@ValentinH)
v4.1.0
v4.0.3
v4.0.2
What's Changed
- docs: add trurl-master as a contributor for code, example by @allcontributors in #324
- docs: add raed667 as a contributor for infra by @allcontributors in #325
- docs: add cvolant as a contributor for code by @allcontributors in #326
- docs: add CodingWith-Adam as a contributor for doc by @allcontributors in #327
- docs: add liveboom as a contributor for code by @allcontributors in #328
- docs: add MatixYo as a contributor for code by @allcontributors in #329
- docs: add labithiotis as a contributor for code by @allcontributors in #330
- E2E: replace CSS assertions by visual regression with Percy by @ValentinH in #333
- docs: add oleksi-l as a contributor for doc by @allcontributors in #337
Full Changelog: v4.0.1...v4.0.2
v4.0.1
v4.0.0
🎉 Better rotation handling 🎉
Thanks to an awesome work by @trurl-master, we are now handling rotation properly when computing the output image coordinate. 🎉
in addition, the example code for generating the cropped image is now more efficient and should reduce the number of issues on iOS devices like reported in #91.
New initialCroppedAreaPercentages prop
initialCroppedAreaPercentages
is similar to initialCroppedAreaPixels
but more accurate as there is no rounding.
It minimizes the losses of save/restore operations. They're still present on some occasions as the JS floating-point operations accuracy is limited, but it allows to preserve the crop for much longer. initialCroppedAreaPixels
still can be used, but it's a bit risky.
⚠️ Breaking changes ⚠️
TL;DR: If you were not using the rotation
prop, there should be no breaking changes.
The croppedArea
and croppedAreaPixels
output by onCropComplete()
have changed when using the Cropper with a rotation different than 0.
Migration guide
The main impact this major version has is on the croppedAreaPixels
when used together with the rotation. As it now generates bounding box relative values, you will need to remake the part that generates the final image, taking that into account.
Here's an example implementation (codesandbox):
First, calculate the bounding box size:
const image = await createImage(...)
const rotRad = getRadianAngle(rotation)
const bBoxWidth =
Math.abs(Math.cos(rotRad) * image.width) +
Math.abs(Math.sin(rotRad) * image.height)
const bBoxHeight =
Math.abs(Math.sin(rotRad) * image.width) +
Math.abs(Math.cos(rotRad) * image.height)
Second, create a canvas element with the size of the bounding box:
const canvas = document.createElement('canvas')
canvas.width = bBoxWidth
canvas.height = bBoxHeight
Then, rotate the canvas context around the center of the canvas:
const ctx = canvas.getContext('2d')
ctx.translate(bBoxWidth / 2, bBoxHeight / 2)
ctx.rotate(rotRad)
Set context to point to the top-left corner of the rotated image:
ctx.translate(-image.width / 2, -image.height / 2)
Draw the image onto the rotated context:
ctx.drawImage(image, 0, 0)
What you have in the canvas at this point is a rotated image inside its bounding box. Now, you just need to extract the result using croppedAreaPixels
and repaint it on a canvas with the size of the final image:
const data = ctx.getImageData(
croppedAreaPixels.x,
croppedAreaPixels.y,
croppedAreaPixels.width,
croppedAreaPixels.height
)
// set the canvas size to the final image size - this will clear existing context
canvas.width = croppedAreaPixels.width
canvas.height = croppedAreaPixels.height
// paste the extracted image at the top left corner
ctx.putImageData(data, 0, 0)
croppedArea
If you somehow managed to use croppedArea
with rotation before - you're smarter than me. If not - now is the time. The approach is basically the same as with croppedAreaPixels
- you just need to convert percentages to pixels based on the image you're cropping
Here's how you can use percentages server-side and crop using sharp (codesandbox):
Rotate the image:
const image = sharp(...);
await image.rotate(rotation);
Get rotated image bounding box size (basically you need to create a new image out of the rotated one, otherwise the metadata won't change):
const meta = await sharp(await image.toBuffer()).metadata();
Alternatively, you can calculate the bounding box size using the same method we used for the client-side crop
Convert percentages to pixels:
const cropInfo = {
top: Math.round((croppedArea.y / 100) * meta.height),
left: Math.round((croppedArea.x / 100) * meta.width),
width: Math.round((croppedArea.width / 100) * meta.width),
height: Math.round((croppedArea.height / 100) * meta.height)
}
Extract the image:
const myCroppedImage = await image.extract(cropInfo)
Commits
- Change rotated crop area output by @trurl-master in #312
- Update readme video tutorials section by @CodingWith-Adam in #300
- Bump tmpl from 1.0.4 to 1.0.5 by @dependabot in #296
- Bump object-path from 0.11.7 to 0.11.8 in /docs by @dependabot in #295
New Contributors
- @CodingWith-Adam made their first contribution in #300
- @trurl-master made their first contribution in #312
Full Changelog: v3.5.3...v4.0.0