【问题标题】:Scale rotated image to fill HTML5 Canvas using JavaScript trigonometry?使用 JavaScript 三角法缩放旋转图像以填充 HTML5 Canvas?
【发布时间】:2016-05-22 15:21:57
【问题描述】:

下面是我目前使用的代码。使用0 旋转,图像被正确缩放以填充画布。 (类似于background-size: cover,除了在 Canvas 上使用 JavaScript)

我正在尝试添加旋转功能,具有以下功能。

  1. 旋转时保持图像居中。我尝试在translate 中使用width / 2,然后在drawImage 中使用相反的方法,但是您可以看到图像没有居中。我不确定这是否与我之前的 xy 居中代码冲突,或者这里是否需要三角函数?

  2. 自动进一步缩放图像以覆盖画布。这些是任意旋转,而不是 90 度增量。除了填充画布角落所需的图像外,我不想再裁剪任何图像。这比我习惯处理的三角函数复杂得多。

我认为这可以通过Math.sinMath.cos 完成,但是我已经很久没有使用它们了。我特别不确定如何实现#2。任何帮助,将不胜感激。

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>

【问题讨论】:

标签: html canvas rotation trigonometry cover


【解决方案1】:

+1 to Blindman67's answer 让它工作。

我缩短了代码并简化了我的用例。您应该能够将function drawBestFit() 包含到您的应用程序中,并使用它来用任何加载的图像填充任何画布。

要更好地了解其工作原理,请查看Blindman67's original answer - 尤其是底部的演示 sn-p。

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

  }

}
&lt;canvas width="350" height="200" style="border: solid 1px black"&gt;&lt;/canvas&gt;

【讨论】:

猜你喜欢
  • 2012-02-27
  • 1970-01-01
  • 2022-01-10
  • 2011-05-15
  • 2012-05-18
  • 2014-12-05
  • 2012-03-22
  • 1970-01-01
  • 2013-06-30
相关资源
最近更新 更多