草庐IT

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

coder 2023-08-07 原文

我正在运行 firefox 3.5.6。

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

这是我得到的:

上面的图片是我在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 - canvas 上的 drawImage 在 firefox 中有奇怪的长宽比和其他问题的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  4. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  5. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  6. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  7. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  8. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  9. ruby - ruby 中有 each_if 吗? - 2

    假设我在Ruby中有这个each循环。@list.each{|i|putsiifi>10breakend}我想循环遍历列表直到满足条件。这让我感到“不像Ruby”,因为我是Ruby的新手,是否有Ruby方法可以做到这一点? 最佳答案 您可以使用Enumerable#detect或Enumerable#take_while,取决于您想要的结果。@list.detect{|i|putsii>10}#Returnsthefirstelementgreaterthan10,ornil.正如其他人所指出的,更好的风格是先进行子选择,然后再对其

  10. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

随机推荐