From 8c79d9672eb31e50234545fd3742716dbb18b0f3 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Sun, 10 Mar 2013 19:56:53 -0700 Subject: [PATCH] Alternate SVG sprite technique for operations (fixes #956) --- js/id/svg/surface.js | 69 +++++++++++++++++++++++++++++------------ js/id/ui/radial_menu.js | 13 +++----- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/js/id/svg/surface.js b/js/id/svg/surface.js index 9f671eb11..44f8a9866 100644 --- a/js/id/svg/surface.js +++ b/js/id/svg/surface.js @@ -1,4 +1,26 @@ iD.svg.Surface = function() { + function findStylesheet(name) { + return _.find(document.styleSheets, function(stylesheet) { + return stylesheet.href.indexOf(name) > 0; + }); + } + + function sprites(stylesheetName, selectorRegexp) { + var sprites = []; + + _.forEach(findStylesheet(stylesheetName).cssRules, function(rule) { + var klass = rule.selectorText, + match = klass && klass.match(selectorRegexp); + if (match) { + var id = match[1]; + match = rule.style.backgroundPosition.match(/(-?\d+)px (-?\d+)px/); + sprites.push({id: id, x: match[1], y: match[2]}); + } + }); + + return sprites; + } + return function drawSurface(selection) { var defs = selection.append('defs'); @@ -52,16 +74,31 @@ iD.svg.Surface = function() { }) .attr('xlink:href', function(d) { return 'img/pattern/' + d[1] + '.png'; }); - defs.append('clipPath') - .attr('id', 'clip-square-12') + defs.selectAll() + .data([12, 20]) + .enter().append('clipPath') + .attr('id', function(d) { return 'clip-square-' + d; }) .append('rect') + .attr('x', 0) + .attr('y', 0) + .attr('width', function(d) { return d; }) + .attr('height', function(d) { return d; }); + + defs.append('image') .attr({ - x: 0, - y: 0, - width: 12, - height: 12 + id: 'sprite', + width: 420, + height: 200, + 'xlink:href': 'img/sprite.png' }); + defs.selectAll() + .data(sprites("app.css", /^\.(icon-operation-[a-z0-9-]+)$/)) + .enter().append('use') + .attr('id', function(d) { return d.id; }) + .attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }) + .attr('xlink:href', '#sprite'); + defs.append('image') .attr({ id: 'maki-sprite', @@ -70,20 +107,12 @@ iD.svg.Surface = function() { 'xlink:href': 'img/maki.png' }); - _.forEach(_.find(document.styleSheets, function(stylesheet) { - return stylesheet.href.indexOf("maki.css") > 0; - }).cssRules, function(rule) { - var klass = rule.selectorText, - match = klass.match(/^\.(maki-[a-z0-9-]+-12)$/); - if (match) { - var id = match[1]; - match = rule.style.backgroundPosition.match(/(-?\d+)px (-?\d+)px/); - defs.append('use') - .attr('id', id) - .attr('transform', "translate(" + match[1] + "," + match[2] + ")") - .attr('xlink:href', '#maki-sprite'); - } - }); + defs.selectAll() + .data(sprites("maki.css", /^\.(maki-[a-z0-9-]+-12)$/)) + .enter().append('use') + .attr('id', function(d) { return d.id; }) + .attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }) + .attr('xlink:href', '#maki-sprite'); var layers = selection.selectAll('.layer') .data(['fill', 'shadow', 'casing', 'stroke', 'text', 'hit', 'halo', 'label']); diff --git a/js/id/ui/radial_menu.js b/js/id/ui/radial_menu.js index caf259bd4..4f7d5a7b5 100644 --- a/js/id/ui/radial_menu.js +++ b/js/id/ui/radial_menu.js @@ -52,15 +52,10 @@ iD.ui.RadialMenu = function(operations) { .on('mouseover', mouseover) .on('mouseout', mouseout); - var image = button.append('foreignObject') - .style('pointer-events', 'none') - .attr('width', 20) - .attr('height', 20) - .attr('x', -10) - .attr('y', -10); - - image.append('xhtml:span') - .attr('class', function(d) { return 'icon icon-operation icon-operation-' + d.id; }); + button.append('use') + .attr('transform', 'translate(-10, -10)') + .attr('clip-path', 'url(#clip-square-20)') + .attr('xlink:href', function(d) { return '#icon-operation-' + d.id; }); var tooltip = menu.append('foreignObject') .style('display', 'none')