Below is the code I am currently using. With 0
rotation, the image is correctly scaled to fill the canvas. (similar to background-size: cover
, except using JavaScript on a Canvas)
I'm trying to add a rotate feature, with the following features.
Keep image centered while rotating. I tried using
width / 2
intranslate
, and then the opposite indrawImage
, but as you can see the image did not stay centered. I'm not sure if this is a conflict with my earlierx
andy
centering code, or if trigonometry is required here?Automatically scale the image further to cover the canvas. These are arbitrary rotations, not 90 degree increments. I don't want to crop any more of the image than necessary to fill the canvas corners. This is much more complex trigonometry than I am used to dealing with.
I think this can be done with Math.sin
and Math.cos
, but it's been a very long time since I've used them. I'm especially uncertain about how to achieve #2. Any help would be appreciated.
var canvas = document.querySelector('canvas')
var context = canvas.getContext('2d')
var image = new Image()
image.src = 'http://i.stack.imgur.com/7FsbT.jpg'
image.onload = function () {
var maxScaleX = canvas.width / image.width
var maxScaleY = canvas.height / image.height
scale = maxScaleX > maxScaleY ? maxScaleX : maxScaleY
var width = image.width * scale
var height = image.height * scale
var x = (width - canvas.width) / -2
var y = (height - canvas.height) / -2
var degrees = 30
context.setTransform(1, 0, 0, 1, 0, 0) // reset previous translate and/or rotate
context.translate(width / 2, height / 2)
context.rotate(degrees * Math.PI / 180)
context.drawImage(image, x - width / 2, y - height / 2, width, height)
}
<canvas width="350" height="150" style="border: solid 1px black"></canvas>
+1 to Blindman67's answer for this to work.
I shortened the code and simplified for my use case. You should be able to just include
function drawBestFit()
into your app and use it to fill any canvas with any loaded image.For a better understanding of how this works, view Blindman67's original answer - especially the demonstration snippet at the bottom.