javascript - 在 d3.js 中调整图像大小时如何不保留纵横比

标签 javascript d3.js svg

我有以下 HTML:

<div id="MainDiv"></div>

和Javascript代码:

    var cursor;
    var width, height;
    var testSVG = {
        x: 0,
        y: 0,
        id: 0,
        image: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Small_Flag_of_the_United_Nations_ZP.svg/488px-Small_Flag_of_the_United_Nations_ZP.svg.png",
        width: 280,
        height: 140
    };
    var svgContainer = d3.select("#MainDiv").append("svg").attr({
        width: 1920,
        height: 1080,
        version: 1.1,
        xmlns: "http://www.w3.org/2000/svg",
        viewBox: "-40, -40, 2000, 1160",
        "class": "GraphicDesigner"
    });

    createSVG(svgContainer, testSVG);

    function createSVG(container, object) {
        var d = [{
            x: object.x,
            y: object.y,
            moveX: object.x,
            movey: object.y
        }];
        var svgObjectGroup = container.data(d).append("g").attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        }).call(onDragDrop(dragmove, dropHandler))
          .attr("id", object.ID).attr("class", "masterTooltip");
        svgObjectGroup.append("svg").attr({
            width: object.width,
            height: object.height,
            viewBox: "0, 0, " + object.width + ", " + object.height
        }).append("svg:image")
          .attr({
              preserveAspectRatio: "none",
              width: object.width,
              height: object.height,
              "xlink:href": object.image
          });
        var dragSize = 16;
        svgObjectGroup.append("rect").attr({
            x: object.width - dragSize,
            y: object.height - dragSize,
            width: dragSize,
            height: dragSize,
            rx: 0,
            fill: "#FFFFFF",
            stroke: "black",
            "stroke-width": 1,
            cursor: "se-resize",
            "class": "sizers"
        });
    }

    function onDragDrop(dragHandler, dropHandler) {
        var drag = d3.behavior.drag();
        drag.on("drag", dragHandler).on("dragstart", startHandler).on("dragend", dropHandler);
        return drag;
    }

    function startHandler() {
        cursor = "se";
        d3.event.sourceEvent.stopPropagation();
        if (d3.event.sourceEvent.srcElement.attributes.cursor != undefined) cursor = d3.event.sourceEvent.srcElement.attributes.cursor.nodeValue; //Todo. Doesn't work in IE
    }

    function dragmove() {
        if (cursor != null) {
            if (cursor.startsWith("se")) {
                //South-East
                d3.select(this)[0][0].firstChild.height.baseVal.value = d3.select(this)[0][0].firstChild.height.baseVal.value + d3.event.dy;
                d3.select(this)[0][0].firstChild.width.baseVal.value = d3.select(this)[0][0].firstChild.width.baseVal.value + d3.event.dx;
            }
            var sizers = d3.selectAll(".sizers");
            sizers.remove();
            if (d3.select(this)[0][0].firstChild.height.baseVal.value < 1) d3.select(this)[0][0].firstChild.height.baseVal.value = 1;
            if (d3.select(this)[0][0].firstChild.width.baseVal.value < 1) d3.select(this)[0][0].firstChild.width.baseVal.value = 1;
            height = d3.select(this)[0][0].firstChild.height.baseVal.value;
            width = d3.select(this)[0][0].firstChild.width.baseVal.value;
        }
    }

    function dropHandler() {
        d3.selectAll("svg").remove();
        svgContainer = d3.select("#MainDiv").append("svg").attr({
            width: 1920,
            height: 1080,
            version: 1.1,
            xmlns: "http://www.w3.org/2000/svg",
            viewBox: "-40, -40, 2000, 1160",
            "class": "GraphicDesigner"
        });
        d3.select(this).style("cursor", "default");
        testSVG = {
            x: 0,
            y: 0,
            id: 0,
            image: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Small_Flag_of_the_United_Nations_ZP.svg/488px-Small_Flag_of_the_United_Nations_ZP.svg.png",
            width: width,
            height: height
        };
        createSVG(svgContainer, testSVG);
    }

我这里也有一个 jsfiddle:http://jsfiddle.net/Family/zvrfp3oL/

注意:此代码不适用于 Internet Explorer,但适用于 Chrome、Edge 和 Firefox。

如果我尝试通过在右下方的框中单击并拖动来调整图像大小,则在释放鼠标按钮时图像会正确调整大小。但是,有没有一种方法可以在拖动图像时正确显示图像。事实上,当它试图保持纵横比时,它看起来就像 x 和 y 坐标在移动。

最佳答案

您可以通过在调整大小时更改“背景大小”属性来实现此目的。

需要在可调整大小的 div 中创建一个绝对定位的 div,并为其添加拖动行为。

这是一个 jsFiddle .拖动橙色矩形以调整大小。

相关代码如下:

var resizable = d3.select('#resizable');
var resizer = resizable.select('.resizer');

var dragResize = d3.behavior.drag()
 .on('drag', function() {        
    x = d3.mouse(this.parentNode)[0];
    y = d3.mouse(this.parentNode)[1];

    x = Math.max(50, x);
    y = Math.max(50, y);

    resizable
        .style('background-size', x + 'px' + ' ' + y + 'px')
        .style('width', x + 'px')
        .style('height', y + 'px')
    ;

    resizer
        .style('left', x + 'px')
      .style('top', y + 'px')
    ;
})

resizer.call(dragResize);

CSS:

#resizable {
  position: relative;
  width: 200px;    
  height: 200px;
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Small_Flag_of_the_United_Nations_ZP.svg/488px-Small_Flag_of_the_United_Nations_ZP.svg.png") ;
  background-size:cover;
  background-repeat:no-repeat;
  // background-position:center;
}

#resizable .resizer {
  position: absolute;
  width: 10px;
  height: 10px;
  bottom: 0;
  right: -10px;
  background: orange;
  opacity: .5;
  cursor: pointer;
}

HTML:

<div id="resizable">
  <div class="resizer"></div>
</div>

关于javascript - 在 d3.js 中调整图像大小时如何不保留纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34905045/

相关文章:

javascript - 在 yeoman 生成器中对单个方法进行单元测试的推荐方法是什么?

JavaScript scrollTop 滚动到错误的 div

javascript - jQuery 表追加问题

javascript - JSON 到 Javascript 层次结构(数组?)

css - 复杂 SVG 中的外部阴影 [jVectorMap Countries]

html - Safari 不尊重应用于 foreignObject 的缩放

javascript - 随机播放一组图像jquery

javascript - 如何使用D3 Axis 命令正确调换X轴和Y轴?

javascript - 使用 D3.js 的响应式词云

selenium - 如何通过 Java 使用 XPath 和 Selenium WebDriver 单击 SVG 元素