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

时间:2016-01-20 16:14:13

标签: 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坐标正在移动。

1 个答案:

答案 0 :(得分:4)

您可以通过更改&#39;背景大小&#39;来实现这一目标。调整大小时的属性。

需要在可调整大小的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>