How to fill an image inside my svg circles in d3.js

后端 未结 2 1798
忘掉有多难
忘掉有多难 2021-02-10 04:31

This is my piece of code filling circles in my svg.

   var svgContainer = d3.select(\"body\").append(\"svg\")
                                 .attr(\"width\",          


        
相关标签:
2条回答
  • 2021-02-10 05:27

    Creating pattern from image uses too much of memory and using multiple images will create a serious performance issue. So to avoid that we can use clip-path over image.

    Like this:

    var config = {
      "avatar_size": 100
    }
    
    var body = d3.select("body");
    var svg = body.append("svg")
      .attr("width", 500)
      .attr("height", 500);
    
    var defs = svg.append('svg:defs');
    
    data = [{
      posx: 100,
      posy: 100,
      img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/pencil-gear-128.png",
    }, {
      posx: 200,
      posy: 200,
      img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/gear-clock-128.png"
    }, {
      posx: 300,
      posy: 300,
      img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/magnifier-data-128.png"
    }];
    
    
    svg .append('clipPath')
       .attr('id','clipObj')  
            .append('circle')
             .attr('cx',config.avatar_size/2)
              .attr('cy',config.avatar_size/2)
             .attr('r',config.avatar_size/2);
    
    data.forEach(function(d,i){
      svg.append('image')
         .attr('xlink:href',d.img)
         .attr('width',config.avatar_size)
         .attr('height',config.avatar_size)
     .attr('transform','translate('+parseInt(d.posx+config.avatar_size/2)+','+parseInt(d.posy+config.avatar_size/2)+')')
         .attr('clip-path','url(#clipObj)');
    });
    

    Also we can easily replace the clipping area with new one as we want. Here is the link of Code pen : http://codepen.io/anon/pen/VagxKp?editors=0010

    0 讨论(0)
  • 2021-02-10 05:28

    Imagine you have a dataset like this:

    data = [{
      posx: 100,
      posy: 100,
      img: "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png",
    
    }, {
      posx: 200,
      posy: 200,
    
      img: "https://cdn1.iconfinder.com/data/icons/social-media-set/24/Reverbnation-128.png"
    }, {
      posx: 300,
      posy: 300,
    
      img: "https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-128.png"
    }]
    

    Make defs like this in svg like this:

    var defs = svg.append('svg:defs');
    

    Iterate over all the data and make as many defs with image and circle. Inside circles's fill pass the def's id like this .style("fill", "url(#grump_avatar" + i + ")");

    data.forEach(function(d, i) {
      defs.append("svg:pattern")
        .attr("id", "grump_avatar" + i)
        .attr("width", config.avatar_size) 
        .attr("height", config.avatar_size)
        .attr("patternUnits", "userSpaceOnUse")
        .append("svg:image")
        .attr("xlink:href", d.img)
        .attr("width", config.avatar_size)
        .attr("height", config.avatar_size)
        .attr("x", 0)
        .attr("y", 0);
    
      var circle = svg.append("circle")
        .attr("transform", "translate(" + d.posx + "," + d.posy + ")")
        .attr("cx", config.avatar_size / 2)
        .attr("cy", config.avatar_size / 2)
        .attr("r", config.avatar_size / 2)
        .style("fill", "#fff")
        .style("fill", "url(#grump_avatar" + i + ")");
    
    })
    

    working code here

    Inspired from this SO answer

    0 讨论(0)
提交回复
热议问题