24

为了好玩,我想看看我在为 RIA 实现 SVG 浏览器客户端方面能走多远,我在业余时间搞砸了。

但是遇到了似乎是一个巨大的绊脚石。没有自动换行!!

有谁知道任何解决方法(我在想某种 JavaScript 或我不知道的特殊标签)?

如果不是,我将不得不走 xhtml 路线并开始在我的 SVG 中添加 HTML 元素(哎哟),或者在 SVG 1.2 准备好十年后再次回来。

4

8 回答 8

16

还有foreignObject标签。然后,您可以将 HTML 嵌入到 SVG 中,这提供了最大的灵活性。HTML 非常适合文档布局,并且已经被无限支持以支持应用程序布局、绘图以及我们开发人员想要的一切。但它的优势在于自动换行和文档布局。让 HTML 做它最擅长的事情,让 SVG 做它最擅长的事情。

http://www.w3.org/TR/SVG/extend.html

这适用于大多数浏览器 FireFox、Opera、Webkit,除了 IE(从 IE11 开始)。:-( 网络故事不是吗?

于 2011-03-19T15:14:27.313 回答
14

这个 SVG 的东西很莫名其妙,不是吗?

值得庆幸的是,您可以获得一些不错的结果,但它比使用 HTML 5 需要更多的工作。

这是我的 ASP.Net / SVG 应用程序的屏幕截图,其中包含一些“伪造”的自动换行。

在此处输入图像描述

以下函数将为您创建一个 SVG文本元素,分成tspan片段,其中每行的长度不超过 20 个字符。

<text x="600" y="400" font-size="12" fill="#FFFFFF" text-anchor="middle">
    <tspan x="600" y="400">Here a realy long </tspan>
    <tspan x="600" y="416">title which needs </tspan>
    <tspan x="600" y="432">wrapping </tspan>
</text>

它并不完美,但它简单、快速,用户永远不会知道其中的区别。

我的createSVGtext() JavaScript 函数采用三个参数:x 位置、y 位置和要显示的文本。字体、每行最大字符数和文本颜色都在我的函数中进行了硬编码,但这很容易更改。

要显示上面屏幕截图中显示的右侧标签,您可以使用以下方法调用该函数:

var svgText = createSVGtext("Here a realy long title which needs wrapping", 600, 400);
$('svg').append(svgText);

这是 JavaScript 函数:

function createSVGtext(caption, x, y) {
    //  This function attempts to create a new svg "text" element, chopping 
    //  it up into "tspan" pieces, if the caption is too long
    //
    var svgText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    svgText.setAttributeNS(null, 'x', x);
    svgText.setAttributeNS(null, 'y', y);
    svgText.setAttributeNS(null, 'font-size', 12);
    svgText.setAttributeNS(null, 'fill', '#FFFFFF');         //  White text
    svgText.setAttributeNS(null, 'text-anchor', 'middle');   //  Center the text

    //  The following two variables should really be passed as parameters
    var MAXIMUM_CHARS_PER_LINE = 20;
    var LINE_HEIGHT = 16;

    var words = caption.split(" ");
    var line = "";

    for (var n = 0; n < words.length; n++) {
        var testLine = line + words[n] + " ";
        if (testLine.length > MAXIMUM_CHARS_PER_LINE)
        {
            //  Add a new <tspan> element
            var svgTSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
            svgTSpan.setAttributeNS(null, 'x', x);
            svgTSpan.setAttributeNS(null, 'y', y);

            var tSpanTextNode = document.createTextNode(line);
            svgTSpan.appendChild(tSpanTextNode);
            svgText.appendChild(svgTSpan);

            line = words[n] + " ";
            y += LINE_HEIGHT;
        }
        else {
            line = testLine;
        }
    }

    var svgTSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
    svgTSpan.setAttributeNS(null, 'x', x);
    svgTSpan.setAttributeNS(null, 'y', y);

    var tSpanTextNode = document.createTextNode(line);
    svgTSpan.appendChild(tSpanTextNode);

    svgText.appendChild(svgTSpan);

    return svgText;
}

自动换行的逻辑基于这个 HTML5 Canvas 教程

希望这个对你有帮助 !

麦克风

http://www.MikesKnowledgeBase.com

更新

一件事我忘了提。

我上面显示的那个“工作流程图”屏幕最初只是使用 HTML 5 canvas编写的。它工作得很好,图标可以拖动,当你点击它们时会出现弹出菜单,甚至 IE8 似乎也很满意。

但是我发现,如果图表变得“太大”(例如 4000 x 4000 像素),那么在所有浏览器中都将无法初始化,什么都不会出现 -但是- 就 JavaScript 代码而言,一切正常。

因此,即使进行了错误检查,我的图表仍然显示为空白,并且我无法检测到何时发生此显示停止问题。

var canvasSupported = !!c.getContext;
if (!canvasSupported) {
    //  The user's browser doesn't support HTML 5 <Canvas> controls.
    prompt("Workflow", "Your browser doesn't support drawing on HTML 5 canvases.");
    return;
}

var context = c.getContext("2d");
if (context == null) {
    //  The user's browser doesn't support HTML 5 <Canvas> controls.
    prompt("Workflow", "The canvas isn't drawable.");
    return;
}

//  With larger diagrams, the error-checking above failed to notice that
//  the canvas wasn't being drawn.

所以,这就是为什么我不得不重写 JavaScript 代码来改用 SVG。它似乎可以更好地处理更大的图表。

于 2013-07-25T08:35:56.713 回答
11

SVGT 1.2 引入了 textArea 元素http://www.w3.org/TR/SVGTiny12/text.html#TextInAnArea,但目前它仅被 Opera 10 实验性支持。我不知道其他浏览器是否会计划实现它,尽管我希望他们会。

于 2009-02-18T14:28:39.313 回答
10

根据此文档,似乎tspan可以给人一种自动换行的错觉:

tspan 标记与文本标记相同,但可以嵌套在文本标记内部和自身内部。再加上 'dy' 属性,这允许在 SVG 1.1 中出现自动换行的错觉。请注意,“dy”相对于最后绘制的字形(字符)。

于 2009-01-24T09:52:42.010 回答
2

svg.js库有一个svg.textflow.js插件。它不是超快,但它可以解决问题。它甚至将溢出的文本存储在数据属性中,因此您可以使用它来创建连续流动的列。这里是文本流示例页面

于 2013-04-05T08:47:56.033 回答
0

另一种方法是使用 Andreas Neuman 的文本框对象。

于 2009-01-28T20:43:54.663 回答
0

这些天来,flowPara 可以进行自动换行,但我还没有找到合适支持它的浏览器。

于 2011-02-19T04:14:02.350 回答
0

我一直在寻找一个关于在 svg 中换行这么几个小时(或很多天)的解决方案。如果您可以在您的应用程序中,编辑您的代码以放入一些 tspan 或任何其他方法,进入其中。

文本换行将在 1.2 版本中实现,但除了 opera,还没有浏览器完全实现它(4 年,规范在 W3 上......)。

因为我必须使用一些对齐设置,所以我不能使用许多论坛可以提供的任何代码(没有异物,没有 carto 脚本或任何东西)。

如果我发布此消息,这只是为了在谷歌搜索自动换行 svg 时对其他人有用,因为此帖子位于最佳结果,并且在许多情况下,此帖子无济于事。

这是一个很酷、简单且轻便的解决方案: http: //dev.w3.org/SVG/profiles/1.1F2/test/svg/text-dom-01-f.svg

于 2012-07-16T16:28:32.590 回答