【问题标题】:strange canvas rotate in OperaOpera中奇怪的画布旋转
【发布时间】:2012-10-11 21:31:29
【问题描述】:

我用画布写了简单的绘图:

var angle = 20
var k = Math.sin(Math.PI / 180 * angle)
var scaleY = 0.5
var radius = 55
var pushBy = {x: 60, y: 60}

var drawArc = function (context) {
  context.setTransform(1, -k, 0, scaleY, pushBy.x, pushBy.y)
  context.beginPath()
  context.arc(0, 0, radius, 0, Math.PI * 2)
  context.stroke()
}

var canvas = $('canvas')
var context = canvas.getContext('2d')

drawArc(context)

实际上,它完全符合我的需要:它绘制了一个旋转了 20 度的扁平椭圆,但是……在 Opera 中没有。我也试过明确的rotate,它也不起作用。在 Chrome 和 FF 中一切正常。 难道我做错了什么?有什么解决方法吗?

【问题讨论】:

  • 您在 Opera 中看到了什么?什么都没有?您的示例完全没有分号。你的实际测试文件是这样吗?
  • Opera 只是将圆拉伸成椭圆,而不会使它倾斜。缺少的分号绝对不是问题 - 尽管这也不是好的做法......;)
  • @Steve,我从不在 Javascript 中添加分号,因为它们不是必需的。这是an article on this
  • 这是一个非常糟糕的论点,我真的不推荐它,行业也不推荐。 Counter article
  • 好吧,我不认为这是一个论点。我写代码,它是有效的,每个遵循解析规则的解析器都可以处理它。这种风格不会引入任何歧义。它只是让代码从不必要的部分变得更清晰。

标签: javascript canvas html5-canvas opera


【解决方案1】:

它看起来像 Opera 中的一个错误。如果你看一下我的http://jsfiddle.net/a6anq/5/,网格在 Chrome 和 Opera 中都能正确翻译,但椭圆形不是。运行 arc() 时,Opera 似乎没有考虑转换。

【讨论】:

  • 非常感谢,我现在检查一下arcTo() 的工作原理。
【解决方案2】:

我的第一种方法是使用arcTo() 绘制四个弧线,我错误地认为这是通用解决方法 =) 这是代码

var drawArcWith4ArcTo = function (context) {
  context.setTransform(1, -k, 0, scaleY, pushBy.x, pushBy.y)
  context.beginPath()
  context.moveTo(-radius, 0)
  context.lineTo(-radius, 0)
  context.arcTo(-radius, radius, 0, radius, radius)
  context.arcTo(radius, radius, radius, 0, radius)
  context.arcTo(radius, -radius, 0, -radius, radius)
  context.arcTo(-radius, -radius, -radius, 0, radius)
  context.stroke()
}

但它无法在 Opera 中运行,原因有两个:

  • Opera 的 arcTo() 需要稍微不同的点作为参数 =)
  • 它仍然没有将转换矩阵应用于结果路径。

所以我不得不使用一种解决方法,使用 4 条贝塞尔曲线绘制一个圆:

var drawArcWith4BezierCurves = function () {
  var kappa = 4 * (Math.sqrt(2) - 1) / 3

  return function (context) {
    context.setTransform(1, -k, 0, scaleY, pushBy.x, pushBy.y)
    context.beginPath()
    context.moveTo(-radius, 0)
    context.bezierCurveTo(
      -radius, radius * kappa,
      -radius * kappa, radius,
      0, radius
    )
    context.bezierCurveTo(
      radius * kappa, radius,
      radius, radius * kappa,
      radius, 0
    )
    context.bezierCurveTo(
      radius, -radius * kappa,
      radius * kappa, -radius,
      0, -radius
    )
    context.bezierCurveTo(
      -radius * kappa, -radius,
      -radius, -radius * kappa,
      -radius, 0
    )
    context.stroke()
  }
}

if (Prototype.Browser.Opera)
  drawArc = drawArcWith4BezierCurves()

两个音符:

  • 生成的路径是近似值,而不是绝对圆(怀疑您是否会注意到这一点 =)
  • 该示例使用了一点 Prototype.js,但很容易猜到我的意思。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多