Keep cover crop image visible while zooming.
Do not revoke the preview blob URL until the dialog closes, so resizing the image on zoom does not blank it. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -158,6 +158,7 @@
|
||||
const cropState = {
|
||||
targetInput: null,
|
||||
hint: null,
|
||||
objectUrl: '',
|
||||
naturalW: 0,
|
||||
naturalH: 0,
|
||||
scale: 1,
|
||||
@@ -207,6 +208,13 @@
|
||||
|
||||
const w = cropState.naturalW * cropState.scale
|
||||
const h = cropState.naturalH * cropState.scale
|
||||
// Cover the crop window so zoom/pan never leaves it empty.
|
||||
const minX = size.maskLeft + size.maskW - w
|
||||
const maxX = size.maskLeft
|
||||
const minY = size.maskTop + size.maskH - h
|
||||
const maxY = size.maskTop
|
||||
cropState.x = Math.min(maxX, Math.max(minX, cropState.x))
|
||||
cropState.y = Math.min(maxY, Math.max(minY, cropState.y))
|
||||
img.style.width = `${w}px`
|
||||
img.style.height = `${h}px`
|
||||
img.style.left = `${cropState.x}px`
|
||||
@@ -250,31 +258,35 @@
|
||||
function openCoverCrop(file, targetInput, hint) {
|
||||
const modal = document.getElementById('cropModal')
|
||||
const img = document.getElementById('cropImage')
|
||||
if (cropState.objectUrl) URL.revokeObjectURL(cropState.objectUrl)
|
||||
cropState.targetInput = targetInput
|
||||
cropState.hint = hint
|
||||
cropState.scale = 0
|
||||
cropState.scale = 1
|
||||
cropState.x = 0
|
||||
cropState.y = 0
|
||||
const url = URL.createObjectURL(file)
|
||||
// Keep the blob URL alive until the dialog closes. Revoking it on load
|
||||
// makes the image vanish the next time width/height change (zoom).
|
||||
cropState.objectUrl = URL.createObjectURL(file)
|
||||
img.onload = () => {
|
||||
cropState.naturalW = img.naturalWidth
|
||||
cropState.naturalH = img.naturalHeight
|
||||
URL.revokeObjectURL(url)
|
||||
modal.classList.add('on')
|
||||
requestAnimationFrame(() => {
|
||||
if (!fitCropImage()) {
|
||||
setTimeout(() => fitCropImage(), 50)
|
||||
}
|
||||
if (!fitCropImage()) setTimeout(() => fitCropImage(), 50)
|
||||
})
|
||||
}
|
||||
img.src = url
|
||||
img.src = cropState.objectUrl
|
||||
}
|
||||
|
||||
function closeCoverCrop() {
|
||||
document.getElementById('cropModal').classList.remove('on')
|
||||
document.getElementById('cropImage').removeAttribute('src')
|
||||
const img = document.getElementById('cropImage')
|
||||
img.removeAttribute('src')
|
||||
if (cropState.objectUrl) {
|
||||
URL.revokeObjectURL(cropState.objectUrl)
|
||||
cropState.objectUrl = ''
|
||||
}
|
||||
cropState.targetInput = null
|
||||
cropState.scale = 0
|
||||
}
|
||||
|
||||
function exportCroppedFile() {
|
||||
|
||||
Reference in New Issue
Block a user