Scale rotated image to fill HTML5 Canvas using JavaScript trigonometry?

前端 未结 1 957
忘了有多久
忘了有多久 2021-01-24 02:45

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 u

相关标签:
1条回答
  • 2021-01-24 03:14

    +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.

    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 degrees = 0
    
      loop()
    
      function loop() {
        degrees += .5
        drawBestFit(context, degrees * Math.PI / 180, image)
        requestAnimationFrame(loop)
      }
    
      function drawBestFit(ctx, angle, image) {
        
        var dist = Math.sqrt(Math.pow(canvas.width, 2) + Math.pow(canvas.height, 2))
        var diagAngle = Math.asin(canvas.height / dist)
    
        var a1 = ((angle % (Math.PI * 2)) + Math.PI * 4) % (Math.PI * 2)
        if (a1 > Math.PI)
          a1 -= Math.PI
        if (a1 > Math.PI / 2 && a1 <= Math.PI)
          a1 = (Math.PI / 2) - (a1 - (Math.PI / 2))
        
        var ang1 = Math.PI / 2 - diagAngle - Math.abs(a1)
        var ang2 = Math.abs(diagAngle - Math.abs(a1))
        
        var scale1 = Math.cos(ang1) * dist / image.height
        var scale2 = Math.cos(ang2) * dist / image.width
        
        var scale = Math.max(scale1, scale2)
        
        var dx = Math.cos(angle) * scale
        var dy = Math.sin(angle) * scale
        ctx.setTransform(dx, dy, -dy, dx, canvas.width / 2, canvas.height / 2)
        
        ctx.drawImage(image, -image.width / 2, -image.height / 2, image.width, image.height)
        
        ctx.setTransform(1, 0, 0, 1, 0, 0) // reset transformations when done
    
      }
    
    }
    <canvas width="350" height="200" style="border: solid 1px black"></canvas>

    0 讨论(0)
提交回复
热议问题