cropperjs
cropperjs copied to clipboard
How i can prenvent cropperselector to overlap on canvas on v2?
What is the equivalent of viewMode 1 on version 2?
May not support that currently.
PS: As of v2-beta, the cropper canvas is a window, and within the window, it is entirely free.
这个功能还是有必要的
I tried canceling the move event on certain conditions (like x or y < 0), but then I realised that is not not exactly true, as there could be image outside of the visible canvas area, so also getting the image size and matrix (for the scaling) does not satisfy the needs completely. I will try other approaches and keep an eye on this thread.
If you need restrictions, you can add the logic in the action event listener. This is how I use it in react. This code restricts the selection to the image on "move", "resize" and "scale".
useEffect(() => {
const cropperCanvas = document.querySelector('cropper-canvas')
if (!cropperCanvas) return
cropperCanvas.addEventListener('action', actionHandler)
return () => {
cropperCanvas.removeEventListener('action', actionHandler)
}
}, [])
function actionHandler(event) {
const cropperCanvas = document.querySelector('cropper-canvas')
if (!cropperCanvas) return
const cropperImage = cropperRef.current.getCropperImage()
if (!cropperImage) return
const selection = cropperRef.current.getCropperSelection()
if (!selection) return
const actionType = event.detail.action
// Extract image transform matrix
const matrix = cropperImage.$getTransform()
// Calculate the actual dimensions and position of the image
const imageActualWidth = cropperImage.$image.width * matrix[0]
const imageActualHeight = cropperImage.$image.height * matrix[3]
const imageActualX = matrix[4] + (cropperImage.$image.width - imageActualWidth) / 2
const imageActualY = matrix[5] + (cropperImage.$image.height - imageActualHeight) / 2
// Initialize new position and size with current values
let newX = selection.x
let newY = selection.y
let newWidth = selection.width
let newHeight = selection.height
if (actionType === 'move' || actionType === 'scale') {
// Calculate new position ensuring selection does not exceed image boundaries
newX = Math.max(imageActualX, Math.min(selection.x, imageActualX + imageActualWidth - selection.width))
newY = Math.max(imageActualY, Math.min(selection.y, imageActualY + imageActualHeight - selection.height))
if (actionType === 'scale') {
// Adjust the selection size if the image is scaled
newWidth = Math.min(newWidth, imageActualWidth)
newHeight = Math.min(newHeight, imageActualHeight)
// Adjust selection position again in case resizing has pushed it outside the image
if (newX + newWidth > imageActualX + imageActualWidth) {
newX = imageActualX + imageActualWidth - newWidth
}
if (newY + newHeight > imageActualY + imageActualHeight) {
newY = imageActualY + imageActualHeight - newHeight
}
}
} else if (actionType.includes('resize')) {
// Handle specific resize actions here
if (actionType === 'ne-resize') {
if (newX + newWidth > imageActualX + imageActualWidth) {
newWidth = imageActualX + imageActualWidth - newX // Prevent right side from going outside
}
// Ensure top edge does not exceed the image boundary
if (newY < imageActualY) {
newHeight += newY - imageActualY // Increase height to compensate for the upward movement
newY = imageActualY
}
}
// Correct resizing for 'sw-resize'
if (actionType === 'sw-resize') {
// Ensure bottom edge does not exceed the image boundary
if (newY + newHeight > imageActualY + imageActualHeight) {
newHeight = imageActualY + imageActualHeight - newY
}
// Adjust newX for 'sw-resize' if necessary (moved to the left beyond image boundary)
if (newX < imageActualX) {
newWidth += newX - imageActualX // Adjust width to maintain size while moving left
newX = imageActualX
}
}
// For north and west resize, adjust newX and newY
if (actionType === 'n-resize' || actionType === 'nw-resize') {
if (newY < imageActualY) {
newHeight += newY - imageActualY // Increase height to compensate for the upward movement
newY = imageActualY
}
newHeight = Math.min(newHeight, imageActualY + imageActualHeight - newY)
}
if (actionType === 'w-resize' || actionType === 'nw-resize') {
if (newX < imageActualX) {
newWidth += newX - imageActualX // Increase width to compensate for the leftward movement
newX = imageActualX
}
newWidth = Math.min(newWidth, imageActualX + imageActualWidth - newX)
}
// Correct newWidth and newHeight for south and east directions to not exceed image boundaries
if (actionType === 's-resize' || actionType === 'se-resize' || actionType === 'e-resize') {
if (newX + newWidth > imageActualX + imageActualWidth) {
newWidth = imageActualX + imageActualWidth - newX
}
if (newY + newHeight > imageActualY + imageActualHeight) {
newHeight = imageActualY + imageActualHeight - newY
}
}
}
// Ensure selection does not exceed canvas boundaries (optional check for resize)
if (newX + newWidth > cropperCanvas.clientWidth) {
newWidth = cropperCanvas.clientWidth - newX
}
if (newY + newHeight > cropperCanvas.clientHeight) {
newHeight = cropperCanvas.clientHeight - newY
}
// Update the selection if necessary
if (newX !== selection.x || newY !== selection.y || newWidth !== selection.width || newHeight !== selection.height) {
selection.$change(newX, newY, newWidth, newHeight)
}
}
As of v2.0.0-rc, you can use the <cropper-image>
element's transform
event to limit image boundaries, or use the <cropper-selection>
element's change
event to limit selection boundaries.