Skip to content

Instantly share code, notes, and snippets.

@dimitardanailov
Last active January 31, 2017 17:56
Show Gist options
  • Save dimitardanailov/240cc0689604e22570e8ce22aa8a7e7e to your computer and use it in GitHub Desktop.
Save dimitardanailov/240cc0689604e22570e8ce22aa8a7e7e to your computer and use it in GitHub Desktop.
Drop shadow
license: gpl-3.0

This is an example to demonstrate drop shadow

<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
.container {
display: flex;
flex-direction: row;
}
.inputs {
display: flex;
flex-direction: column;
width 30%;
}
button,
select,
input {
margin-bottom: 10px;
}
svg {
font-family: "Helvetica Neue", Helvetica;
}
line {
shape-rendering: crispEdges;
vector-effect: non-scaling-stroke;
stroke: #890000;
stroke-width: 2px;
}
circle {
shape-rendering: crispEdges;
vector-effect: non-scaling-stroke;
fill: #890000;
}
circle:hover {
cursor: pointer;
}
</style>
<body>
<div class="container">
<div class="inputs">
<label>stdDeviation:</label>
<input type="number" id="stdDeviation" value="2">
<label>dx: </label>
<input type="number" id="dx" value="0">
<label>dy: </label>
<input type="number" id="dy" value="0">
<label>slope: </label>
<input type="text" id="slope" value="0.5">
<label>type: </label>
<select id="type">
<option value="linear" selected="selected">linear</option>
<option value="gamma">gamma</option>
<option value="discrete">discrete</option>
<option value="table">table</option>
<option value="identity">identity</option>
</select>
<button id="addDropShadow">Add a new drop shadow</button>
<button id="resetDropShadow">Clear all drop shadows</button>
</div>
<div id="svgContainer" />
</div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var id = 0;
var activeDropShadow;
var width = 960,
height = 500;
var dropShadow = {
'stdDeviation': 2,
'dx': 0,
'dy': 0,
'slope': 0.5,
'type': 'linear'
};
var inputs = {
'stdDeviation': d3.select('#stdDeviation'),
'dx': d3.select('#dx'),
'dy': d3.select('#dy'),
'slope': d3.select('#slope'),
'type': d3.select('#type')
};
var svg = d3.select('#svgContainer').append('svg');
svg.attr('width', width);
svg.attr('height', height);
// Drop shadow
addDrawDropShadow();
d3.select('#addDropShadow').on('click', updateDropShadowValues);
d3.select('#resetDropShadow').on('click', resetDropShadow);
//The data for our lines and endpoints
var data = [
{
'x1': 350,
'y1': 15,
'x2': 250,
'y2': 33,
'solid': true
},
{
'x1': 420,
'y1': 420,
'x2': 250,
'y2': 333,
'solid': false
},
{
'x1': 140,
'y1': 120,
'x2': 220,
'y2': 220,
'solid': true
},
{
'x1': 180,
'y1': 55,
'x2': 330,
'y2': 320,
'solid': false
},
{
'x1': 200,
'y1': 260,
'x2': 150,
'y2': 180,
'solid': true
}
];
// Generating the svg lines attributes
var lineAttributes = {
'x1': function(d) {
return d.x1;
},
'y1': function(d) {
return d.y1;
},
'x2': function(d) {
return d.x2;
},
'y2': function(d) {
return d.y2;
},
'stroke-dasharray': function(d) {
return d.solid ? 0 : 5;
}
};
// Pointer to the d3 lines
var lines = svg
.selectAll('line')
.data(data)
.enter()
.append('line')
.attr(lineAttributes);
var topEndPoints = data.map(function(line, i) {
return {
'x': line.x1,
'y': line.y1,
'marker': 'marker-start',
'lineIndex': i
};
});
var bottomEndPoints = data.map(function(line, i) {
return {
'x': line.x2,
'y': line.y2,
'marker': 'marker-end',
'lineIndex': i
};
});
var endPointsData = topEndPoints.concat(bottomEndPoints);
// Generating the svg circle attributes
var endPointsAttributtes = {
'r': 7,
'cx': function(d) {
return d.x;
},
'cy': function(d) {
return d.y;
}
};
// Pointer to d3 circles
var endPoints = svg
.selectAll('circle')
.data(endPointsData)
.enter()
.append('circle')
.attr(endPointsAttributtes);
/**
* @see http://stackoverflow.com/questions/14865915/how-to-lower-the-opacity-of-the-alpha-layer-in-an-svg-filter/14871278#14871278
*/
function addDrawDropShadow() {
activeDropShadow = 'dropshadow-' + id;
id++;
var filter = svg.append('defs')
.append('filter')
.attr('id', activeDropShadow)
// x, y, width and height represent values in the current coordinate system that results
// from taking the current user coordinate system in place at the time when the
// <filter> element is referenced
// (i.e., the user coordinate system for the element referencing the <filter> element via a filter attribute).
.attr('filterUnits','userSpaceOnUse');
filter.append('feGaussianBlur')
.attr('in', 'SourceAlpha')
.attr('stdDeviation', parseInt(dropShadow.stdDeviation));
filter.append('feOffset')
.attr('dx', parseInt(dropShadow.dx))
.attr('dy', parseInt(dropShadow.dy));
var feComponentTransfer = filter.append('feComponentTransfer');
feComponentTransfer
.append('feFuncA')
.attr('type', dropShadow.type)
.attr('slope', parseFloat(dropShadow.slope));
var feMerge = filter.append('feMerge');
feMerge.append('feMergeNode');
feMerge.append('feMergeNode').attr('in', 'SourceGraphic');
}
function applyDropShadow() {
svg.selectAll('line')
.attr('filter', 'url(#' + activeDropShadow + ')' );
svg.selectAll('circle')
.attr('filter', 'url(#' + activeDropShadow + ')' );
}
function resetDropShadow() {
svg.selectAll('line')
.attr('filter', null);
svg.selectAll('circle')
.attr('filter', null);
}
function updateDropShadowValues() {
var keys = Object.keys(inputs);
keys.forEach(function(key) {
dropShadow[key] = inputs[key].property('value');
});
svg.selectAll('defs').remove();
addDrawDropShadow();
applyDropShadow();
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment