I've seen this problem online e.g:
HTML5 canvas drawImage with at an angle
http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/
But I was unsuccessful in applying them to my problem so far.
const TO_RADIANS = Math.PI / 180
export function cropPreview(
image: HTMLImageElement,
canvas: HTMLCanvasElement,
crop: PixelCrop,
scale = 1,
rotate = 0,
) {
const ctx = canvas.getContext('2d')
if (!ctx) {
throw new Error('No 2d context')
}
const scaleX = image.naturalWidth / image.width
const scaleY = image.naturalHeight / image.height
const pixelRatio = window.devicePixelRatio || 1
canvas.width = Math.floor(crop.width * pixelRatio * scaleX)
canvas.height = Math.floor(crop.height * pixelRatio * scaleY)
ctx.scale(pixelRatio, pixelRatio)
ctx.imageSmoothingQuality = 'high'
const cropX = crop.x * scaleX
const cropY = crop.y * scaleY
const cropWidth = crop.width * scaleX
const cropHeight = crop.height * scaleY
const rotateRads = rotate * TO_RADIANS
const centerX = image.width / 2
const centerY = image.height / 2
ctx.save()
ctx.translate(centerX, centerY)
ctx.rotate(rotateRads)
ctx.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight)
ctx.restore()
}
Here's a live playground with the problem, just choose an image and apply some rotation: CodeSandbox image rotation
What am I doing wrong here? The bottom image should show exactly what is in the crop area even with rotation applied.