繁体   English   中英

d3.js中的缩放,遮罩,不透明度问题

[英]Scaling, masking, opacity issues in d3.js

桌面-大约501-1200px 在此处输入图片说明

手机-大约350-500px

在此处输入图片说明


在此处输入图片说明

我建立了一个面具,上面有一个圆形的切口,它会长大,收缩并带有标签。 但是我在尝试使其正确缩放方面遇到问题。

我已经尝试过使用视图框重新缩放功能-但是它不起作用,并且调整大小会导致我无法修复的不透明蒙版错误。

使用ViewBox根据窗口大小调整svg的大小

//最新的js小提琴http://jsfiddle.net/NYEaX/1563/

$(document).ready(function() {


  function maskMaker(el) {

    var backcolor = $(el).data("color");
    var backopacity = $(el).data("opacity");

    var height = $(el).data("height");
    var width = $(el).data("width");

    var width = 1120;
    var height = 500;

    var labelName = $(el).data("label-name");
    var bubbleValue = $(el).data("bubble-value");
    var displaceLeft = $(el).data("displace-left");
    var displaceTop = $(el).data("displace-top");

    var data = [{
      "label": labelName,
      "x": displaceLeft,
      "y": displaceTop,
      "value": bubbleValue
    }];

    console.log("MASK data", data);


    // Set the main elements for the series chart
    var svgroot = d3.select($(el)[0])
      .append("svg")
      .attr("viewBox", "0 0 " + width + " " + height)
      /*
                  .attr("width", "100%")
                  .attr("height", "100%")*/
      .attr("width", width)
      .attr("height", height)
      .attr("preserveAspectRatio", "xMidYMid meet");

    // filters go in defs element
    var defs = svgroot.append("defs");

    var mask = defs.append("mask")
      .attr("id", "myMask");

    mask.append("rect")
      .attr("x", 0)
      .attr("y", 0)
      .attr("width", "100%")
      .attr("height", "100%")
      .style("fill", "white")
      .style("opacity", backopacity);


    var invisiblebubble = mask.append("circle")
      .data(data);


    //create a fixed bubble first                  
    invisiblebubble
      .attr("cx", "50%")
      .attr("cy", "50%")
      .attr("r", function(d) {
        return d.value - 20;
      });


    //now mask the fixed circle     
    var masker = defs.append(function() {
        return mask.node().cloneNode(true)
      })
      .attr("id", "myMaskForPointer")
      .select("rect")
      .style("opacity", 0.8);

    invisiblebubble
      .attr("r", 10);

    //animate this circle
    invisiblebubble
      .attr("cx", "50%")
      .attr("cy", "50%")
      .transition()
      .duration(1800)
      .attr("r", 10)
      .transition()
      .duration(900)
      .attr("r", function(d) {
        return d.value;
      });


    //apply the rest of the chart elements 
    var svg = svgroot
      .attr("class", "series")
      .append("g")
      .attr("transform", "translate(0,0)")


    var rect = svg
      .append("rect")
      .attr("x", 0)
      .attr("y", 0)
      .attr("width", "100%")
      .attr("height", "100%")
      .attr("mask", "url(#myMask)")
      .style("fill", backcolor);


    /*
                      //__labels 
                      var centrallabel = svgroot.append("g")
                        .attr("class", "centrallabel")
                        .data(data);

                  centrallabel    
                        .append("text")
                        .attr("text-anchor", "middle")
                        .attr("x", 550)
                        .attr("y", 250 + 10)
                        .text(function(d) {
                          return "200";
                        })
                        */


    function addLabel() {

      //__labels 
      var labels = svgroot.append("g")
        .attr("class", "labels")

      //__ enter
      var labels = labels.selectAll("text")
        .data(data);

      labels.enter()
        .append("text")
        .attr("text-anchor", "middle")

      //__ update
      //labels

      .attr("x", function(d) {
          return d.x;
        })
        .attr("y", function(d) {
          return d.y - 10;
        })
        .text(function(d) {
          return d.label;
        })
        .each(function(d) {
          var bbox = this.getBBox();
          d.sx = d.x - bbox.width / 2 - 2;
          d.ox = d.x + bbox.width / 2 + 2;
          d.sy = d.oy = d.y + 5;
          d.cx = 550;
          d.cy = 250;
        })
        .transition()
        .duration(300)

      labels
        .transition()
        .duration(300)

      //__ exit
      labels.exit().remove();
      //__labels                     
    }


    function addPointer() {
      //__pointers
      var pointers = svgroot.append("g")
        .attr("class", "pointers");


      var dots = defs.append("marker")
        .attr("id", "circ")
        .attr("markerWidth", 6)
        .attr("markerHeight", 6)
        .attr("refX", 3)
        .attr("refY", 3);


      var pointers = pointers.selectAll("path.pointer")
        .data(data);

      //__ enter
      pointers.enter()
        .append("path")
        .attr("class", "pointer")
        .style("fill", "none")
        .attr("marker-end", "url(#circ)")
        .attr("mask", "url(#myMaskForPointer)")

      //__ update
      //pointers
      .attr("d", function(d) {
          if (d.cx > d.ox) {
            return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
          } else {
            return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
          }
        })
        .transition()
        .duration(300)

      pointers
        .transition()
        .duration(300)

      //__ exit
      pointers.exit().remove();
      //__pointers 
    }

    //delay for the mask
    setTimeout(function() {
      addLabel();
      addPointer();
    }, 1000);

  }


function resizeHandling(el){

  function maskResizer(width, height) {
    $(el).find('.series').attr("width", width);
    $(el).find('.series').attr("height", height);
    $(el).find('.series').attr("viewBox", "0 0 " + width + " " + height);
  }


  $(window).resize(function() {
    var paneWidth = $(el).width();
    var paneHeight = $(el).height();
    console.log("paneHeight", paneHeight);
    console.log("paneWidth", paneWidth);
    maskResizer(paneWidth, paneHeight);
  });
}
  //var el = $(".mask"); //selector

  $('[data-role="maskmaker"]').each(function(index) {
    console.log("test")
    maskMaker(this);
    resizeHandling(this);
  });


});

我想出了一种在发生调整大小时缩放和重绘元素的解决方案。

      function maskMaker(el){

        var backcolor = $(el).data("color");
        var backopacity = $(el).data("opacity");

        //var height = $(el).data("height");
        //var width = $(el).data("width");

        var width = $(el).parent().width();
        var height = $(el).parent().height();

        var labelName = $(el).data("label-name");
        var bubbleValue = $(el).data("bubble-value");
        var displaceLeft = $(el).data("displace-left");
        var displaceTop = $(el).data("displace-top");

        var centralLabel = $(el).data("central-label");

        var data = [{
          "label": labelName,
          "centralLabel" : centralLabel,
          "xPer": displaceLeft,
          "yPer": displaceTop,
          "value": bubbleValue
        }];

        console.log("MASK data", data);

        //width="100%" height="100%" viewBox="0 0 1120 500" preserveAspectRatio="none"

        // Set the main elements for the series chart
        var svgroot = d3.select($(el)[0])
            .append("svg")
            .attr("viewBox", "0 0 "+width+" "+height)
            .attr("width", "100%")
            .attr("height", "100%")
            .attr("preserveAspectRatio", "none");

        // filters go in defs element
        var defs = svgroot.append("defs");

        var mask = defs.append("mask")
                     .attr("id", "myMask");

        mask.append("rect")
          .attr("x", 0)
          .attr("y", 0)
          .attr("width", "100%")
          .attr("height", "100%")
          .style("fill", "white")
          .style("opacity", 1);


        var invisiblebubble = mask.append("circle")
          .data(data);


        //create a fixed bubble first                  
          invisiblebubble
            .attr("cx", "50%")
            .attr("cy", "50%")
            .attr("r", function(d) {
              return d.value-20;
            });            


         //now mask the fixed circle     
          var masker = defs.append(function() { 
            return mask.node().cloneNode(true)
          })
            .attr("id", "myMaskForPointer")
            .select("rect")
            .style("fill", "white")
            .style("opacity", 1);

          invisiblebubble
            .attr("r", 10);


         //apply the rest of the chart elements 
          var svg = svgroot
            .attr("class", "series")
            .append("g")
            .attr("transform", "translate(0,0)")


          var rect = svg
            .append("rect")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", "100%")
            .attr("height", "100%")
            .attr("mask", "url(#myMask)")
            .style("fill", backcolor)
            .style("opacity", backopacity);


         //animate this circle

          invisiblebubble
            .attr("cx", "50%")
            .attr("cy", "50%")
            .transition()
            .duration(1800)
            .attr("r", 10)
            .transition()
            .duration(900)
            .attr("r", function(d) {
              return d.value;
            });



            if(centralLabel){
                //__labels 
               var centrallabel = svgroot.append("g")
                .attr("class", "centrallabel")
                .data(data);

                centrallabel    
                      .append("text")
                      .attr("text-anchor", "middle")
                      .attr("x", "50%")
                      .attr("y", "51%")
                      .text(function(d) {
                        return d.centralLabel;
                      });                     
            }



            var dots = defs.append("marker")
                  .attr("id", "circ")
                  .attr("markerWidth", 6)
                  .attr("markerHeight", 6)
                  .attr("refX", 3)
                  .attr("refY", 3);  


            function addLabel(){


              var width = $(el).parent().width();
              var height = $(el).parent().height();

              //__labels 
              var labels = svgroot.append("g")
                .attr("class", "labels")

              //__ enter
              var labels = labels.selectAll("text")
                .data(data);

              labels.enter()
                .append("text")
                .attr("text-anchor", "middle")

              //__ update
              //labels

                .attr("x", function(d) {
                  console.log("d.x", d.xPer);
                  return d.xPer +"%";
                })
                .attr("y", function(d) {
                  return d.yPer +"%";
                })
                .text(function(d) {
                  return d.label;
                })
                .each(function(d) {
                  var bbox = this.getBBox();
                  d.sx = (d.xPer/100 * width) - bbox.width / 2 - 2;
                  d.ox = (d.xPer/100 * width) + bbox.width / 2 + 2;
                  d.sy = d.oy = (d.yPer/100 * height) + 5;
                  d.cx = 550;
                  d.cy = 250;
                })
                .transition()
                .duration(300)

              labels
                .transition()
                .duration(300)

              //__ exit
              labels.exit().remove();
              //__labels                     
            }

            function addPointer(){


              //__pointers
              var pointers = svgroot.append("g")
                .attr("class", "pointers");


              var pointers = pointers.selectAll("path.pointer")
                .data(data);

              //__ enter
              pointers.enter()
                .append("path")
                .attr("class", "pointer")
                .style("fill", "none")
                .attr("marker-end", "url(#circ)")
                .attr("mask", "url(#myMaskForPointer)")

              //__ update
              //pointers
                .attr("d", function(d) {
                  if (d.cx > d.ox) {
                    return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
                  } else {
                    return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
                  }
                })
                .transition()
                .duration(300)

              pointers
                .transition()
                .duration(300)

              //__ exit
              pointers.exit().remove();
              //__pointers 
            }

            //delay for the mask
            setTimeout(function(){ 
              addLabel();
              addPointer();
              resetMask();
            }, 1000); 



            //throttle
            var rtime;
            var timeout = false;
            var delta = 200;
            $(window).resize(function() {
                rtime = new Date();
                if (timeout === false) {
                    timeout = true;
                    setTimeout(resizeend, delta);
                }
            });

            function resizeend() {
                if (new Date() - rtime < delta) {
                    setTimeout(resizeend, delta);
                } else {
                    timeout = false;
                    //alert('Done resizing');
                    resetMask();
                }               
            }
            //throttle


            function resetMask(){
              console.log("redraw");

                var width = $(el).parent().width();
                var height = $(el).parent().height();

                svgroot
                  .attr("viewBox", "0 0 "+width+" "+height);


                  var ratio = 1;

                  if(width <= 501){
                      ratio = 0.5;
                  }

                  invisiblebubble
                          .attr("cx", "50%")
                          .attr("cy", "50%")
                          .transition()
                          .duration(400)
                          .attr("r", function(d) {
                            return d.value * ratio;
                          });

                 svgroot.selectAll("g.labels").remove();
                 svgroot.selectAll("g.pointers").remove();

                  addLabel();
                  addPointer();

            }

      }

      maskMaker($this);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM