Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

174
Visualizações
How to copy image rotation transform on to canvas with drawImage

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.

Wrongly transformed crop preview

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Here is your updated function


export async 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()

  // 5) Move the crop origin to the canvas origin (0,0)
  ctx.translate(-cropX, -cropY) 
  // 4) Move the origin to the center of the original position
  ctx.translate(centerX, centerY) 
  // 3) Rotate around the origin
  ctx.rotate(rotateRads) 
  // 2) Scaled the image
  ctx.scale(scale, scale) 
  // 1) Move the center of the image to the origin (0,0)
  ctx.translate(-centerX, -centerY) 
  ctx.drawImage(
    image,
    0,
    0,
    image.width,
    image.height,
    0,
    0,
    image.width,
    image.height,
  )

  ctx.restore()
}

Instead of trying to figure out how to crop you can simply let the canvas to crop it.

The transfromations are applied in the reverse order as they appear, so what I am doing is

  1. Move the center of the image to the origin (0,0)
  2. Scaled the image
  3. Rotate around the origin
  4. Move the origin to the center of the original position
  5. Move the crop origin to the canvas origin (0,0)

enter image description here

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda