在d3 translate事件结束时使用getCtm()

时间:2017-01-15 09:09:12

标签: javascript d3.js svg leaflet

我有以下功能可以沿预定义的SVG路径转换一组圆形对象。每this post,我试图使用getCTM()函数捕获每个转换在每个相应元素上运行后的每个圆元素的新位置。但是,当执行以下代码时,它不会在每次转换后返回更新的转换。当我查看getCTM()函数为每个元素返回的矩阵值时,它们是:

SVGMatrix {a:1,b:0,c:0,d:1,e:0,f:0}

每个圆圈都顺着SVG路径移动,但我无法弄清楚为什么变换值不会使用下面的代码在SVGMatrix中返回。以下是绑定到每个圆圈的数据示例:

trip_headsign : " Ashmont" trip_id : " 31562570" TRIP_NAME : " 11:05 pm从Alewife到Ashmont - Outbound" vehicle_lat : 42.33035301964327 vehicle_lon : -71.0570772306528 停止 : 阵列[5] 0 : 阵列[6] 0 : " 130" 1 : " 70085" 2 : 124 3 : 数组1 4 : 124 五 : 0

    var map = L.map('map').setView([42.365, -71.10], 12),
        svg = d3.select(map.getPanes().overlayPane).append("svg"),
        ashmontG = svg.append("g").attr("class", "leaflet-zoom-hide"),
        inboundG = svg.append("g").attr("class", "leaflet-zoom-hide");

    var transform = d3.geo.transform({point: projectPoint}),
        path = d3.geo.path().projection(transform);

    var track = d3.svg.line()
        .interpolate("linear")
        .x(function(d) {
        return applyLatLngToLayer(d).x
        })
        .y(function(d) {
        return applyLatLngToLayer(d).y
        });

    var ashmontPath = ashmontG.selectAll("path")
        .data([ashmont.features])
        .enter()
        .append("path")
        .style("fill", "none")
        .style("stroke", "black")
        .style("stroke-width", 2)
        .style("opacity", 0.1)
        .attr("d", track)

    var trains = inboundG.selectAll("circle")
    .data(a_live_trains)
    .enter()
    .append("circle")
    .attr("r", 6)
    .style("fill", "blue")
    .attr("class", "train");

        d3.selectAll(".train").each(function(d) {

            //the convertCoords function takes a lat/lng pair bound to the circle element and returns the coordinates in pixels using the leaflet latlngtolayerpoint function

            var x = convertCoords(d).x, 
                y = convertCoords(d).y;

            console.log(x, y);

            for(j=0; j<d.stops.length; j++){

                var matrix, xn, xy;

               d3.select(this).transition()
                .duration(d.stops[j][4]*50)
                .delay(d.stops[j][5]*50)
                .attrTween("transform", pathMove(d.stops[j][3]))
                .each("end", ctm(this))

                function ctm(x) {

                   console.log(x);
                   matrix = x.getCTM();

                    xn = matrix.e + x*matrix.a + y*matrix.c,
                    yn = matrix.f + x*matrix.b + y*matrix.d;

                    console.log(xn, yn)
                }

            }
        })

    function pathMove(path) {
        return function (d, i, a) {
            return function(t) {
                var length = path.node().getTotalLength();
                var p = path.node().getPointAtLength(t*length);
                //var ptoPoint = map.layerPointToLatLng(new L.Point(p.x, p.y

                return "translate(" + p.x + "," + p.y + ")";

            }
        }
    }

    moveTrains();

    map.on("viewreset", reset);

    reset();

    function reset() {

        svg.attr("width", bottomRight[0] - topLeft[0] + padding)
            .attr("height", bottomRight[1] - topLeft[1] + padding)
            .style("left", (topLeft[0]-(padding/2)) + "px")
            .style("top", (topLeft[1]-(padding/2)) + "px");

        ashmontG.attr("transform", "translate(" + (-topLeft[0] + (padding/2)) + "," 
                                          + (-topLeft[1] + (padding/2)) + ")");
        inboundG.attr("transform", "translate(" + (-topLeft[0] + (padding/2)) + "," 
                                          + (-topLeft[1] + (padding/2)) + ")");

        ashmontPath.attr("d", track);}

    function projectPoint(x, y) {
        var point = map.latLngToLayerPoint(new L.LatLng(y, x))
        //var point = latLngToPoint(new L.LatLng(y, x));
        this.stream.point(point.x, point.y)
    }

1 个答案:

答案 0 :(得分:0)

如下所示编写代码将返回预转换svg矩阵。我相信这是因为“这个&#39;正在变换前选择每个圆形对象的关键字,并将预变换SVG位置传递给ctm函数。另外,在调用pathMove函数之前,ctm函数正在执行。

            d3.select(this).transition()
            .duration(d.stops[j][4]*50)
            .delay(d.stops[j][5]*50)
            .attrTween("transform", pathMove(d.stops[j][3]))
            .each("end", ctm(this))

            function ctm(x) {

               console.log(x);
               matrix = x.getCTM();

使用上面提供的example标记轻微修改代码可以正常执行。我相信这是因为这个&#39;这个&#39;关键字在ctm函数中被称为第二次转换后。在调用pathMove函数后,每次以这种方式编写都会抓取SVGmatrix。

                d3.select(this).transition()
                .duration(d.stops[j][4]*50)
                .delay(d.stops[j][5]*50)
                .attrTween("transform", pathMove(d.stops[j][3]))
                .each("end", ctm);

                function ctm(x) {

                   console.log(this);
                   matrix = this.getCTM();