MattDionis
MattDionis

Reputation: 3616

Add drop-shadow to svg image in D3

I'm attempting to add a drop-shadow to an svg image with D3. My code is below and an example block is posted here:

http://blockbuilder.org/anonymous/0751a819af7570b767ff

var imgurl = 'http://www.logo-designer.co/wp-content/uploads/2015/08/2015-Penn-State-University-logo-design-4.png';

var margin = {
  top: 20,
  right: 10,
  bottom: 20,
  left: 10
};

var width = 960 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;

var svg = d3.select('body').append('svg')
  .attr('width', width + margin.left + margin.right)
  .attr('height', height + margin.top + margin.bottom)
  .append('g')
  .attr('transform', "translate(" + margin.left + "," + margin.top + ")");

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

var clipPath = defs.append('clipPath')
  .attr('id', 'clip-circle')
  .append('circle')
  .attr('r', 140)
  .attr('cy', height / 2 - 10)
  .attr('cx', width / 2 - 10);

var filter = defs.append('filter')
  .attr('id', 'drop-shadow')
  .attr('height', '130%');

filter.append('feGaussianBlur')
  .attr('in', 'SourceAlpha')
  .attr('stdDeviation', 5)
  .attr('result', 'blur');

filter.append('feOffset')
  .attr('in', 'blur')
  .attr('dx', 5)
  .attr('dy', 5)
  .attr('result', 'offsetBlur');

var feMerge = filter.append('feMerge');

feMerge.append('feMergeNode')
  .attr('in', 'offsetBlur')
feMerge.append('feMergeNode')
  .attr('in', 'SourceGraphic');

svg.append('image')
  .attr('x', width / 2 - 260)
  .attr('y', height / 2 - 204)
  .attr('height', 408)
  .attr('width', 520)
  .attr('xlink:href', imgurl)
  .attr('filter', 'url(#drop-shadow)')
  .attr('clip-path', 'url(#clip-circle)');

I have successfully created a circular image with the above code, but cannot seem to get the drop-shadow to appear. Ideally I would like this drop-shadow to completely surround the circular image, but first I need to get it to appear at all.

UPDATE: If I remove the below line of code I see the drop-shadow, but it appears around the original image. My aim is to make this drop-shadow appear around the circular image that results from clip-path:

  .attr('clip-path', 'url(#clip-circle)')

Upvotes: 1

Views: 1778

Answers (1)

Robert Longson
Robert Longson

Reputation: 124299

Apply the shadow to a parent element so it doesn't get clipped.

    var imgurl = 'http://www.logo-designer.co/wp-content/uploads/2015/08/2015-Penn-State-University-logo-design-4.png';

    var margin = {
      top: 20,
      right: 10,
      bottom: 20,
      left: 10
    };

    var width = 960 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;

    var svg = d3.select('body').append('svg')
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom)
      .append('g')
      .attr('transform', "translate(" + margin.left + "," + margin.top + ")");

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

    var clipPath = defs.append('clipPath')
      .attr('id', 'clip-circle')
      .append('circle')
      .attr('r', 140)
      .attr('cy', height / 2 - 10)
      .attr('cx', width / 2 - 10);

    var filter = defs.append('filter')
      .attr('id', 'drop-shadow')
      .attr('height', '130%');

    filter.append('feGaussianBlur')
      .attr('in', 'SourceAlpha')
      .attr('stdDeviation', 5)
      .attr('result', 'blur');

    filter.append('feOffset')
      .attr('in', 'blur')
      .attr('dx', 5)
      .attr('dy', 5)
      .attr('result', 'offsetBlur');

    var feMerge = filter.append('feMerge');

    feMerge.append('feMergeNode')
      .attr('in', 'offsetBlur')
    feMerge.append('feMergeNode')
      .attr('in', 'SourceGraphic');

    var g = svg.append('g')
      .attr('filter', 'url(#drop-shadow)');

    g.append('image')
      .attr('x', width / 2 - 260)
      .attr('y', height / 2 - 204)
      .attr('height', 408)
      .attr('width', 520)
      .attr('xlink:href', imgurl)
      .attr('clip-path', 'url(#clip-circle)');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body></body>

Upvotes: 1

Related Questions