d3.js實現svg縮放功能

本文代碼轉載自Stack Overflow,經過d3.js實現縮放很簡單,可是滾輪和按鈕可以完美縮放就不那麼容易了,若是有對d3感興趣的小夥伴能夠參考下面代碼。css

JSFiddle地址: Demo onlinehtml

看本帖前最好掌握以下技術:html5

  • js/css 基本知識jquery

  • d3.js 語法比較相似jqueryapp

  • html5 svg 畫圖標籤dom

d3.behavior.zoom()

該行爲會自動在容器元素中建立事件監聽器來處理元素的縮放和平移動做,可支持鼠標事件和觸摸事件。
構造一個新的縮放行爲。構造以後,能夠經過selection.call()將此行爲應用於選擇器:svg

var zoom = d3.behavior.zoom();
selection.call(zoom);

全部註冊的監聽器都使用 "zoom" 命名空間, 故以下能夠移除縮放行爲:this

selection.on(".zoom", null);

zoom(selection)

應用縮放行爲到指定的選擇器 selection,註冊所需的事件監聽器,支持縮放和拖拽行爲。.net

zoom.translate([translate])

指定當前的縮放平移向量爲translate;若是未指定translate,返回當前平移向量,默認:[0, 0]。code

zoom.scale([scale])

指定當前的縮放比例,若是未指定scale,則返回當前的縮放比例,默認爲1


index.html

<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom + Pan</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>

.overlay {
  fill: none;
  pointer-events: all;
}
button {
  padding: 10px 20px;
}

</style>
<body>
<button id="zoom_in">+</button>
<button id="zoom_out">-</button>
<script>
var width = 960,
    height = 500;

var randomX = d3.random.normal(width / 2, 80),
    randomY = d3.random.normal(height / 2, 80);

var data = d3.range(2000).map(function() {
    return [randomX(), randomY() ];
});

var zoom = d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoomed);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .call(zoom)
  .append("g");

svg.append("rect")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height);

svg.selectAll("circle")
    .data(data)
  .enter().append("circle")
    .attr("r", 2.5)
    .attr("transform", function(d) { return "translate(" + d + ")"; });

function zoomed() {
    svg.attr("transform",
        "translate(" + zoom.translate() + ")" +
        "scale(" + zoom.scale() + ")"
    );
}

function interpolateZoom (translate, scale) {
    var self = this;
    return d3.transition().duration(350).tween("zoom", function () {
        var iTranslate = d3.interpolate(zoom.translate(), translate),
            iScale = d3.interpolate(zoom.scale(), scale);
        return function (t) {
            zoom
                .scale(iScale(t))
                .translate(iTranslate(t));
            zoomed();
        };
    });
}

function zoomClick() {
    var clicked = d3.event.target,
        direction = 1,
        factor = 0.2,
        target_zoom = 1,
        center = [width / 2, height / 2],
        extent = zoom.scaleExtent(),
        translate = zoom.translate(),
        translate0 = [],
        l = [],
        view = {x: translate[0], y: translate[1], k: zoom.scale()};

    d3.event.preventDefault();
    direction = (this.id === 'zoom_in') ? 1 : -1;
    target_zoom = zoom.scale() * (1 + factor * direction);

    if (target_zoom < extent[0] || target_zoom > extent[1]) { return false; }

    translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
    view.k = target_zoom;
    l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];

    view.x += center[0] - l[0];
    view.y += center[1] - l[1];

    interpolateZoom([view.x, view.y], view.k);
}

d3.selectAll('button').on('click', zoomClick);

</script>
相關文章
相關標籤/搜索