javascript - canvas 上的 drawImage 在 firefox 中有奇怪的长宽比和其他问题

标签 javascript firefox html canvas

我正在运行 firefox 3.5.6。

我想在 Canvas 上显示一张图片并在上面画几条线。它需要在 firefox 和 internet explorer 中正常显示(使用 excanvas)。

这是我得到的:

alt text

上面的图片是我在IE8里看到的,下面是我在firefox里看到的

就 Canvas 尺寸错误而言,IE 似乎有点乱,但 Firefox 快疯了!这个宽高比有什么用?为什么我的弧线的后半部分没有出现? 此外,有时 firefox 完全不显示任何内容。

Here is my code by the way.

最佳答案

宽高比问题

如果您没有在 canvas 元素上设置宽度,它默认为 300x150。在您的 CSS 中,您将样式设置为 94x120,因此它将图像缩放到该大小。要修复它,您需要在 HTML 中或使用 JavaScript 设置宽度和高度。

在 HTML 中:

<canvas id="c" width="94" height="120">Ugh, this just ain't gonna work</canvas>

在 JavaScript 中(使用 jQuery):

$('canvas').attr('width', '94').attr('height', '120');

Internet Explorer 的大小不正确

将尺寸添加到 Canvas 元素应该也能解决这个问题。由于 IE 使用 VML 而不是 Canvas 来呈现图像,因此 Canvas 的 CSS 规则将不适用。 excanvas 应该看到指定的大小并在 IE 中应用它。

缺少弧线的后半部分

当振幅为负时,simpleArc 函数在 Firefox 中不起作用。问题是负幅度会导致圆弧的负半径,根据 canvas spec 这是非法的.它实际上应该抛出一个 INDEX_SIZE_ERR 异常,但 Firefox 似乎忽略了这个调用。

有两种可能的解决方案(基本上;有几种方法可以实现):当您传递负振幅时,要么计算弧的参数,同时考虑负半径(具有不同的中心点和 Angular ,等),或更改符号并使用变换来旋转圆弧。我像这样实现了第二个解决方案:

ctx.simpleArc = function(x,y, length, amplitude) {
    var rotate = false;

    // Check whether we need to rotate the image
    if (amplitude < 0) {
        rotate = true;
        amplitude = -amplitude;
    }
    var radius = amplitude/2+ length*length/(8*amplitude);
    var outerAngle = Math.asin((radius-amplitude)/radius);
    var innerAngle = Math.PI - 2*outerAngle;

    // The translate/rotate/translate steps could be combined into one matrix
    // transformation, but I think this is clearer and less error-prone.
    if (rotate) {
        this.save(); // So we can easily undo the transformation
        this.translate(x + length, y);
        this.rotate(Math.PI);
        this.translate(-length, -y);
    }
    this.arc(x+length/2, y+(radius-amplitude), radius, -(outerAngle+innerAngle), -outerAngle, false);

    // Reset the transformation matrix to its original value
    if (rotate) {
        this.restore();
    }
    return this;
}

Firefox 不显示任何内容

在您的代码中,您创建图像并设置源,但在其余代码执行之前可能不会加载它。图像异步加载,当您将图像绘制到 Canvas 上时,它不会等待完成。您将需要调用使用来自 onload 事件的图像的代码。

var img = $('<img>');
img[0].onload = function() {
    ctx.drawImage(img[0], 0, 0);
    ctx.strokeStyle = "blue";
    ctx.simpleStroke(function(ctx) { ctx.simpleArc(0, 70, img_w/2, 3)});
    ctx.simpleStroke(function(ctx) { ctx.simpleArc(img_w / 2, 70, img_w/2, -3)});
};

// I moved this so it happens after you set the `onload` event, because I
// think IE won't call `onload` if it happens to already be loaded.
img.attr('src', 'shortcylinder.png');

您还可以预加载所有需要的图像,而不是在需要时创建它们。在加载所有图像之前,您仍然需要阻止代码运行。

关于javascript - canvas 上的 drawImage 在 firefox 中有奇怪的长宽比和其他问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1931166/

相关文章:

javascript - Chrome 扩展程序内容脚本未触发代码

javascript - 恶意javascript注入(inject)(Hostads.cn)

javascript - 为什么指定其他类型时 GooglePlacesAPI 自动完成会返回场所?

firefox - 如何在浏览器中访问一个IP地址的子域?

html - 您可以在 <section role ="main"> 元素中使用 <aside> 元素吗?

javascript - ESLint JSDoc 回调错误

css - iframe 高度仅在 Firefox 中无法正确显示

firefox - 将自签名 ssl 证书 .pem 导入到 firefox

javascript - Bootstrap 导航栏中的链接

javascript - 动态调整水平 <li> 元素的大小以保持在一行中