8

我正在尝试在 HTML5 Canvas 的 2d 上下文上使用 fillText() 方法来绘制用阿拉伯语编写的字符串。它工作得很好,直到我在字符串的末尾放了一个标点符号。然后标点符号出现在字符串的错误一侧(在开头,而不是结尾,好像它是 ltr 而不是 rtl 字符串)。我使用了 Context.textAlign 属性,但这似乎只涉及相对于指定位置绘制字符串的方式,而不是文本的实际方向。有谁知道解决这个问题?

谢谢。

更新:我找到的答案是在页面上的画布元素中添加一个“dir”属性。例如,

<canvas dir="rtl">

但是,我仍然不知道如何更改发送到 fillText 的单个字符串的 dir 属性。有任何想法吗?

4

4 回答 4

10

您不需要为每个单独的字符串设置方向。请参阅以下示例,该示例还显示了正确使用隐式双向控制标记以获得正确的显示顺序:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

  <body>
    <canvas id="myCanvas" width="700" dir="rtl" height="250" style="border:1px solid #d3d3d3;">
      Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script type="text/javascript" charset="utf-8">
      var c = document.getElementById("myCanvas");
      var cArabic = c.getContext("2d");
      cArabic.font="25px Arial";

      // Simple Sentence with punctuation.
      var str1 = "این یک آزمایش است.";
      // Few sentences with punctuation and numerals. 
      var str2 = "۱ آزمایش. 2 آزمایش، سه آزمایش & Foo آزمایش!";
      // Needs implicit bidi marks to display correctly.
      var str3 = "آزمایش برای Foo Ltd. و Bar Inc. باشد که آزموده شود.";
      // Implicit bidi marks added; "Foo Ltd.&lrm; و Bar Inc.&lrm;"
      var str4 = "آزمایش برای Foo Ltd.‎ و Bar Inc.‎ باشد که آزموده شود.";

      cArabic.fillText(str1, 600, 60);
      cArabic.fillText(str2, 600, 100);
      cArabic.fillText(str3, 600, 140);
      cArabic.fillText(str4, 600, 180);
    </script>

  </body>
</html>

这是输出: 由 Chrome <code>26.0.1410.64 m</code> 在 MS Windows XP SP3 上呈现

于 2013-04-12T19:57:39.697 回答
3

设置 dir 选项适用于整个画布 - 对于行为不佳的单个字符串,您可以考虑在引号后手动添加 RTL 标记 (U+200F)。

于 2012-05-06T16:21:10.977 回答
3

问题是'.' 字符为'定向中性字符',表示从下一个强定向字符中获取方向,如果后面没有字符,则从容器中获取。在你的情况下,它是后一种。正如已经发现的,一种解决方案是使容器从右到左。但还有其他两种解决方案:

1-在“。”之后放置另一个不可见的从右到左方向性的强字符。幸运的是,unicode 有一个特殊字符,即“从右到左标记”(U+200F)

2-将“从右到左的覆盖字符”(U + 202E)放在文本之前,因此在此标记之后任何中性字符都会获得从右到左的方向。您可以通过添加“弹出方向格式”字符 (U+202C) 来结束覆盖。

我更改了@shervin 的示例代码来演示它。

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

  <body>
    <canvas id="myCanvas" width="700" height="250" style="border:1px solid #d3d3d3;">
      Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script type="text/javascript" charset="utf-8">
      var c = document.getElementById("myCanvas");
      var cArabic = c.getContext("2d");
      cArabic.font="20px Arial";

      //option 1 : adding right-to-left mark at the end to put the '.' between two strong right to left charachters, so it will treated as right to left.
      var str1 = "این یک آزمایش است." + "\u200F";

      //option 2 : adding right-to-left override at the begining of the text so every neutral charachter afterward becomes righ to left.
      var str2;
      str2 = "\u202E";
      str2+= "این یک آزمایش است.";
      //           you might want to finish the override by 'pop directional formatting' charachter
      str2 += "\u202C";

      cArabic.fillText(str1, 200, 30);
      cArabic.fillText(str2, 200, 70);
    </script>

  </body>
</html>

结果图片

还有其他解决方案。您可以在此页面的 unicode 规范中找到它们。它们是在 Chrome 中存在渲染问题的“方向隔离”(U+2067)。和 U+202B 的“方向嵌入”,类似于方向覆盖。

于 2018-04-14T09:48:18.310 回答
0

你可以这样做:
ctx.textAlign="end";

ctx.textAlign="right"

并再次从左到右:
ctx.textAlign="start";

于 2018-01-28T18:14:04.793 回答