Use SVG mask to allow transparent background behind text and improve rendering of fade cap

This commit is contained in:
David Evans 2017-11-05 21:57:59 +00:00
parent 0fd7d84958
commit 5b6cbd518e
5 changed files with 45 additions and 36 deletions

View File

@ -111,15 +111,18 @@ define([
}); });
this.defs = svg.make('defs'); this.defs = svg.make('defs');
this.agentLines = svg.make('g'); this.mask = svg.make('mask', {
this.mask = svg.make('g'); 'id': 'lineMask',
'maskUnits': 'userSpaceOnUse',
});
this.maskReveal = svg.make('rect', {'fill': '#FFFFFF'});
this.agentLines = svg.make('g', {'mask': 'url(#lineMask)'});
this.blocks = svg.make('g'); this.blocks = svg.make('g');
this.sections = svg.make('g'); this.sections = svg.make('g');
this.actionShapes = svg.make('g'); this.actionShapes = svg.make('g');
this.actionLabels = svg.make('g'); this.actionLabels = svg.make('g');
this.base.appendChild(this.defs); this.base.appendChild(this.defs);
this.base.appendChild(this.agentLines); this.base.appendChild(this.agentLines);
this.base.appendChild(this.mask);
this.base.appendChild(this.blocks); this.base.appendChild(this.blocks);
this.base.appendChild(this.sections); this.base.appendChild(this.sections);
this.base.appendChild(this.actionShapes); this.base.appendChild(this.actionShapes);
@ -323,7 +326,7 @@ define([
x: agentInfoL.x + modeRender.width, x: agentInfoL.x + modeRender.width,
y: this.currentY, y: this.currentY,
padding: config.section.label.padding, padding: config.section.label.padding,
boxAttrs: config.section.label.maskAttrs, boxAttrs: {'fill': '#000000'},
labelAttrs: config.section.label.labelAttrs, labelAttrs: config.section.label.labelAttrs,
boxLayer: this.mask, boxLayer: this.mask,
labelLayer: this.actionLabels, labelLayer: this.actionLabels,
@ -501,6 +504,11 @@ define([
const y0 = titleY - margin; const y0 = titleY - margin;
const y1 = stagesHeight + margin; const y1 = stagesHeight + margin;
this.maskReveal.setAttribute('x', x0);
this.maskReveal.setAttribute('y', y0);
this.maskReveal.setAttribute('width', x1 - x0);
this.maskReveal.setAttribute('height', y1 - y0);
this.base.setAttribute('viewBox', ( this.base.setAttribute('viewBox', (
x0 + ' ' + y0 + ' ' + x0 + ' ' + y0 + ' ' +
(x1 - x0) + ' ' + (y1 - y0) (x1 - x0) + ' ' + (y1 - y0)
@ -522,12 +530,14 @@ define([
_reset() { _reset() {
this.knownDefs.clear(); this.knownDefs.clear();
svg.empty(this.defs); svg.empty(this.defs);
svg.empty(this.agentLines);
svg.empty(this.mask); svg.empty(this.mask);
svg.empty(this.agentLines);
svg.empty(this.blocks); svg.empty(this.blocks);
svg.empty(this.sections); svg.empty(this.sections);
svg.empty(this.actionShapes); svg.empty(this.actionShapes);
svg.empty(this.actionLabels); svg.empty(this.actionLabels);
this.mask.appendChild(this.maskReveal);
this.defs.appendChild(this.mask);
this.components.forEach((component) => { this.components.forEach((component) => {
component.resetState(this.state); component.resetState(this.state);
}); });

View File

@ -166,27 +166,27 @@ define([
'y2': isBegin ? '0%' : '100%', 'y2': isBegin ? '0%' : '100%',
}); });
grad.appendChild(svg.make('stop', { grad.appendChild(svg.make('stop', {
'offset': '0%', 'offset': (100 * 1 / 12) + '%',
'stop-color': config.colVisible, 'stop-color': '#FFFFFF',
})); }));
grad.appendChild(svg.make('stop', { grad.appendChild(svg.make('stop', {
'offset': '100%', 'offset': (100 * 11 / 12) + '%',
'stop-color': config.colHidden, 'stop-color': '#000000',
})); }));
return grad; return grad;
}); });
env.shapeLayer.appendChild(svg.make('line', Object.assign({ env.maskLayer.appendChild(svg.make('rect', {
'x1': x, 'x': x - config.width / 2,
'y1': y, 'y': y - config.height * 0.1,
'x2': x + 0.0001, // Chrome bug 'width': config.width,
'y2': y + config.height, 'height': config.height * 1.2,
'stroke': 'url(#' + gradID + ')', 'fill': 'url(#' + gradID + ')',
}, config.attrs))); }));
return { return {
lineTop: 0, lineTop: config.height,
lineBottom: config.height, lineBottom: 0,
height: config.height, height: config.height,
}; };
} }

View File

@ -97,7 +97,7 @@ define([
x: x0 - config.mask.padding.left, x: x0 - config.mask.padding.left,
y: y0 - height + config.label.margin.top, y: y0 - height + config.label.margin.top,
padding: config.mask.padding, padding: config.mask.padding,
boxAttrs: config.mask.maskAttrs, boxAttrs: {'fill': '#000000'},
labelAttrs: config.label.loopbackAttrs, labelAttrs: config.label.loopbackAttrs,
boxLayer: env.maskLayer, boxLayer: env.maskLayer,
labelLayer: env.labelLayer, labelLayer: env.labelLayer,
@ -171,7 +171,7 @@ define([
x: (x0 + x1) / 2, x: (x0 + x1) / 2,
y: y - height + config.label.margin.top, y: y - height + config.label.margin.top,
padding: config.mask.padding, padding: config.mask.padding,
boxAttrs: config.mask.maskAttrs, boxAttrs: {'fill': '#000000'},
labelAttrs: config.label.attrs, labelAttrs: config.label.attrs,
boxLayer: env.maskLayer, boxLayer: env.maskLayer,
labelLayer: env.labelLayer, labelLayer: env.labelLayer,

View File

@ -44,7 +44,13 @@ defineDescribe('Sequence Integration', [
renderer.render(sequence); renderer.render(sequence);
expect(getSimplifiedContent(renderer)).toEqual( expect(getSimplifiedContent(renderer)).toEqual(
'<svg width="100%" height="100%" viewBox="-5 -5 10 10">' + '<svg width="100%" height="100%" viewBox="-5 -5 10 10">' +
'<defs></defs>' + '<defs>' +
'<mask id="lineMask" maskUnits="userSpaceOnUse">' +
'<rect fill="#FFFFFF" x="-5" y="-5" width="10" height="10">' +
'</rect>' +
'</mask>' +
'</defs>' +
'<g mask="url(#lineMask)"></g>' +
'</svg>' '</svg>'
); );
}); });
@ -56,7 +62,13 @@ defineDescribe('Sequence Integration', [
expect(getSimplifiedContent(renderer)).toEqual( expect(getSimplifiedContent(renderer)).toEqual(
'<svg width="100%" height="100%" viewBox="-11.5 -16 23 21">' + '<svg width="100%" height="100%" viewBox="-11.5 -16 23 21">' +
'<defs></defs>' + '<defs>' +
'<mask id="lineMask" maskUnits="userSpaceOnUse">' +
'<rect fill="#FFFFFF" x="-11.5" y="-16" width="23" height="21">' +
'</rect>' +
'</mask>' +
'</defs>' +
'<g mask="url(#lineMask)"></g>' +
'<text' + '<text' +
' x="0"' + ' x="0"' +
' font-family="sans-serif"' + ' font-family="sans-serif"' +

View File

@ -48,14 +48,8 @@ define(['core/ArrayUtilities', 'svg/SVGShapes'], (array, SVGShapes) => {
}, },
}, },
fade: { fade: {
width: 5,
height: 6, height: 6,
colVisible: '#000000',
colHidden: 'rgba(0, 0, 0, 0)',
attrs: {
'fill': 'none',
'stroke-width': 1,
'stroke-linecap': 'round',
},
}, },
none: { none: {
height: 10, height: 10,
@ -82,7 +76,6 @@ define(['core/ArrayUtilities', 'svg/SVGShapes'], (array, SVGShapes) => {
height: 10, height: 10,
attrs: { attrs: {
'fill': '#000000', 'fill': '#000000',
'stroke': 'none',
'stroke-width': 0, 'stroke-width': 0,
'stroke-linejoin': 'miter', 'stroke-linejoin': 'miter',
}, },
@ -109,9 +102,6 @@ define(['core/ArrayUtilities', 'svg/SVGShapes'], (array, SVGShapes) => {
right: 3, right: 3,
bottom: 1, bottom: 1,
}, },
maskAttrs: {
'fill': '#FFFFFF',
},
}, },
}, },
@ -161,9 +151,6 @@ define(['core/ArrayUtilities', 'svg/SVGShapes'], (array, SVGShapes) => {
right: 3, right: 3,
bottom: 0, bottom: 0,
}, },
maskAttrs: {
'fill': '#FFFFFF',
},
labelAttrs: { labelAttrs: {
'font-family': 'sans-serif', 'font-family': 'sans-serif',
'font-size': 8, 'font-size': 8,