|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<title>drop shadow buttons</title> |
|
<style> |
|
text { |
|
-webkit-user-select: none; /* webkit (safari, chrome) browsers */ |
|
-moz-user-select: none; /* mozilla browsers */ |
|
-khtml-user-select: none; /* webkit (konqueror) browsers */ |
|
-ms-user-select: none; /* IE10+ */ |
|
user-select: none; |
|
} |
|
</style> |
|
<body> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script> |
|
|
|
var width = 960, height = 500; |
|
|
|
var padding = 5, radius = 3; |
|
|
|
var svg = d3.select('body').append('svg') |
|
.attr('width', width) |
|
.attr('height', height) |
|
|
|
var g0 = svg.append('g') |
|
.attr('class', 'button') |
|
.attr('transform', 'translate(' + [width / 4, height / 4] +')') |
|
|
|
addButton(g0, 'Hello, world!'); |
|
|
|
var g1 = svg.append('g') |
|
.attr('class', 'button') |
|
.attr('transform', 'translate(' + [width / 2, height / 2] +')') |
|
|
|
addButton(g1, "I'm here too!"); |
|
|
|
// Add drop shadow to the rect |
|
var rect = g0.select('rect'); |
|
defineShadow(g0); |
|
rect.attr('filter', 'url(#dropShadow)') |
|
|
|
g1.select('rect').attr('filter', 'url(#dropShadow)') |
|
|
|
function toggleShadow() { |
|
var rect = d3.select(this); |
|
rect.attr('filter', function() { return (rect.attr('filter')) ? null : 'url(#dropShadow)'; }) |
|
} |
|
|
|
function defineShadow(g) { |
|
var defs = g.append('defs') |
|
var shadow = defs.append('filter') |
|
.attr('id', 'dropShadow') |
|
.attr('x', + rect.attr('x') - padding) |
|
.attr('y', + rect.attr('y') - padding) |
|
.attr('width', + rect.attr('width') + 10 * padding) |
|
.attr('height', + rect.attr('height') + 10 * padding) |
|
|
|
shadow.append('feGaussianBlur') |
|
.attr('in', 'SourceAlpha') |
|
.attr('stdDeviation', '5') |
|
|
|
shadow.append('feOffset') |
|
.attr('dx', '2') |
|
.attr('dy', '4') |
|
|
|
var merge = shadow.append('feMerge') |
|
|
|
merge.append('feMergeNode') |
|
merge.append('feMergeNode').attr('in', 'SourceGraphic'); |
|
} |
|
|
|
function addButton(g, label) { |
|
// Button text |
|
var text = g.append('text') |
|
.style('font-size', '24px') |
|
.style('pointer-events', 'none') |
|
.text(label); |
|
|
|
// Button based on text dimensions |
|
var bbox = text.node().getBBox(); |
|
var rect = g.insert('rect', 'text') |
|
.attr("x", bbox.x - padding) |
|
.attr("y", bbox.y - padding) |
|
.attr("width", bbox.width + 2 * padding) |
|
.attr("height", bbox.height + 2 * padding) |
|
.attr('rx', radius) |
|
.attr('ry', radius) |
|
.style('fill', '#aaa') |
|
.style('stroke', '#000') |
|
.on('click', toggleShadow) |
|
} |
|
|
|
</script> |