将SVG图像元素定位在SVG html项目中

时间:2016-11-14 12:28:16

标签: javascript image svg

为了方便起见,我即将编写一些包含SVG的JavaScript。此代码可以采用HTML页面的SVG部分并动态插入SVG项目。这对于矩形和圆形以及这些形状非常有效,但它不适用于图像:每当我创建图像项时,图像的Y位置都会偏离。 X很好:​​X值为零会使图像与SVG画布左对齐。但这很奇怪:我要求图像的负Y值与SVG.canvas的顶部对齐。与原始形状相比,如果我为图像指定Y为零,则这些图像在我的SVG画布中垂直居中。为什么会这样?我错过了什么?

我的代码的基本方面:

function __makeSVG(tag, attrs)
{
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs)
        el.setAttribute(k, attrs[k]);
    return el;
}

function createImageXY(x, y, url) {
    var style = {};
    style["x"] = x;
    style["y"] = y;
    style["width"] = "100%";
    style["height"] = "100%";
    style["visibility"] = "visible";
    var svgItem = __makeSVG('image', style);
    svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
    main.appendChild(svgItem);
}

HTML中的SVG画布创建如下:

<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
>
</svg>

更奇怪的是:如果我缩放图像,垂直位置也会缩放。

我想拥有像矩形和圆圈这样的绝对定位。位置(100,100)应该将图像定位到精确(100,100)而不是其他位置。我错过了什么?我怎么能做到这一点?

1 个答案:

答案 0 :(得分:1)

我猜测你使用的图像比它高吗?喜欢这个例子吗?

&#13;
&#13;
var main = document.getElementById("viewport");


function __makeSVG(tag, attrs)
{
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs)
        el.setAttribute(k, attrs[k]);
    return el;
}

function createImageXY(x, y, url) {
    var style = {};
    style["x"] = x;
    style["y"] = y;
    style["width"] = "100%";
    style["height"] = "100%";
    style["visibility"] = "visible";
    var svgItem = __makeSVG('image', style);
    svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
    main.appendChild(svgItem);
}

createImageXY(0, 0, "https://placekitten.com/400/200");
&#13;
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
&#13;
&#13;
&#13;

为SVG图像元素指定width="100%"height="100%"时,您并未说&#34;在图像的自然宽度和高度&#34;处绘制图像。你也不是说&#34;以与<svg>&#34;相同的宽度和高度绘制它。

你所说的是&#34;以正常的宽高比绘制图像,但按比例缩放以适合与<svg>&#34;相同宽度和高度的框内。

因此,在上面的示例中,400x200图像正在按比例放大,以便整齐地适合1200x800 <svg>。当您这样做时,图像实际上是以1200x600绘制的。这是最大的尺寸,仍然适合SVG。

此外,默认情况下,图像会在&#34; viewport&#34;内部居中。这意味着有200像素(800-600)的空白空间分布在缩放图像的上方和下方。

解决方案1:拉伸图片

如果您希望图像与SVG的宽度和高度完全相同。然后你可以设置preserveAspectRatio="none",这将使它垂直和水平拉伸到与SVG相同的大小。

&#13;
&#13;
var main = document.getElementById("viewport");


function __makeSVG(tag, attrs)
{
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs)
        el.setAttribute(k, attrs[k]);
    return el;
}

function createImageXY(x, y, url) {
    var style = {};
    style["x"] = x;
    style["y"] = y;
    style["width"] = "100%";
    style["height"] = "100%";
    style["visibility"] = "visible";
    style["preserveAspectRatio"] = "none";
    var svgItem = __makeSVG('image', style);
    svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
    main.appendChild(svgItem);
}

createImageXY(100, 100, "https://placekitten.com/400/200");
&#13;
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
&#13;
&#13;
&#13;

解决方案2:位于图像视口左上角的位置,而不是居中

您可以保留缩放以保留纵横比,但可以通过设置preserveAspectRatio="xMinYMin"来禁用居中行为。该值告诉它将图像的左上角定位在您指定的xy坐标处。

&#13;
&#13;
var main = document.getElementById("viewport");


function __makeSVG(tag, attrs)
{
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs)
        el.setAttribute(k, attrs[k]);
    return el;
}

function createImageXY(x, y, url) {
    var style = {};
    style["x"] = x;
    style["y"] = y;
    style["width"] = "100%";
    style["height"] = "100%";
    style["visibility"] = "visible";
    style["preserveAspectRatio"] = "xMinYMin";
    var svgItem = __makeSVG('image', style);
    svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
    main.appendChild(svgItem);
}

createImageXY(100, 100, "https://placekitten.com/400/200");
&#13;
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
&#13;
&#13;
&#13;

解决方案3:给它一个实际尺寸而不是百分比尺寸

指定适当的宽度和高度,而不是使用百分比。但请记住,如果您指定的宽度和高度具有与图像不同的宽高比,您仍会看到相同的问题。

&#13;
&#13;
var main = document.getElementById("viewport");


function __makeSVG(tag, attrs)
{
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs)
        el.setAttribute(k, attrs[k]);
    return el;
}

function createImageXY(x, y, url) {
    var style = {};
    style["x"] = x;
    style["y"] = y;
    style["width"] = "600";
    style["height"] = "300";
    style["visibility"] = "visible";
    var svgItem = __makeSVG('image', style);
    svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
    main.appendChild(svgItem);
}

createImageXY(100, 100, "https://placekitten.com/400/200");
&#13;
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
&#13;
&#13;
&#13;