Reduce repetition in themes slightly
This commit is contained in:
parent
73cc61d430
commit
5c35d7e894
|
@ -34,8 +34,24 @@
|
|||
}
|
||||
|
||||
class BaseTheme {
|
||||
constructor(svg) {
|
||||
constructor(svg, baseFontAttrs) {
|
||||
this.svg = svg;
|
||||
this.baseFontAttrs = baseFontAttrs;
|
||||
this.fontSize = this.baseFontAttrs['font-size'];
|
||||
this.connectLines = new Map();
|
||||
}
|
||||
|
||||
addConnectLine(type, {
|
||||
attrs = {},
|
||||
pattern = null,
|
||||
} = {}) {
|
||||
const base = this.connectLines.get('solid') || {attrs: {}};
|
||||
const fullAttrs = Object.assign({'fill': 'none'}, base.attrs, attrs);
|
||||
this.connectLines.set(type, {
|
||||
attrs: fullAttrs,
|
||||
renderFlat: this.renderFlatConnect.bind(this, pattern, fullAttrs),
|
||||
renderRev: this.renderRevConnect.bind(this, pattern, fullAttrs),
|
||||
});
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
|
@ -48,6 +64,18 @@
|
|||
// No-op
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign({}, this.baseFontAttrs, {
|
||||
'font-size': this.fontSize * 2.5,
|
||||
'text-anchor': 'middle',
|
||||
});
|
||||
}
|
||||
|
||||
getConnectLine(type) {
|
||||
const lines = this.connectLines;
|
||||
return lines.get(type) || lines.get('solid');
|
||||
}
|
||||
|
||||
getBlock(type) {
|
||||
return this.blocks[type] || this.blocks[''];
|
||||
}
|
||||
|
@ -355,8 +383,6 @@
|
|||
const FONT = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT = 1.3;
|
||||
|
||||
const WAVE = new WavePattern(6, 0.5);
|
||||
|
||||
const NOTE_ATTRS = {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
|
@ -372,7 +398,11 @@
|
|||
|
||||
class BasicTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -496,38 +526,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 2',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -593,14 +591,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -738,6 +728,21 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(6, 0.5),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -756,8 +761,6 @@
|
|||
const FONT$1 = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT$1 = 1.3;
|
||||
|
||||
const WAVE$1 = new WavePattern(10, 1);
|
||||
|
||||
const NOTE_ATTRS$1 = {
|
||||
'font-family': FONT$1,
|
||||
'font-size': 8,
|
||||
|
@ -773,7 +776,11 @@
|
|||
|
||||
class ChunkyTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$1,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$1,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -904,38 +911,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 8,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-dasharray': '10, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE$1),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE$1),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 10,
|
||||
|
@ -1005,15 +980,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT$1,
|
||||
'font-weight': 'bolder',
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$1,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -1156,6 +1122,27 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '10, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(10, 1),
|
||||
});
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign(super.getTitleAttrs(), {
|
||||
'font-weight': 'bolder',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2758,17 +2745,6 @@
|
|||
const FONT$2 = 'Courier New,Liberation Mono,monospace';
|
||||
const LINE_HEIGHT$2 = 1.3;
|
||||
|
||||
const WAVE$2 = new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]);
|
||||
|
||||
const NOTE_ATTRS$2 = {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 8,
|
||||
|
@ -2784,7 +2760,11 @@
|
|||
|
||||
class MonospaceTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$2,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -2908,36 +2888,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 4,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE$2),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE$2),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 4,
|
||||
|
@ -3003,14 +2953,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$2,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -3142,6 +3084,26 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
pattern: new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5691,13 +5653,13 @@
|
|||
return this.getConfig(theme).height;
|
||||
}
|
||||
|
||||
lineGap(theme, lineAttrs) {
|
||||
lineGap(theme, line) {
|
||||
const arrow = this.getConfig(theme);
|
||||
const short = this.short(theme);
|
||||
if(arrow.attrs.fill === 'none') {
|
||||
const h = arrow.height / 2;
|
||||
const w = arrow.width;
|
||||
const safe = short + (lineAttrs['stroke-width'] / 2) * (w / h);
|
||||
const safe = short + (line.attrs['stroke-width'] / 2) * (w / h);
|
||||
return (short + safe) / 2;
|
||||
} else {
|
||||
return short + arrow.width / 2;
|
||||
|
@ -5815,15 +5777,14 @@
|
|||
}
|
||||
|
||||
renderRevArrowLine({x1, y1, x2, y2, xR}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
const dx1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const dx2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const rendered = line.renderRev(line.attrs, {
|
||||
rad: config.loopbackRadius,
|
||||
const dx1 = lArrow.lineGap(env.theme, line);
|
||||
const dx2 = rArrow.lineGap(env.theme, line);
|
||||
const rendered = line.renderRev({
|
||||
rad: env.theme.connect.loopbackRadius,
|
||||
x1: x1 + dx1,
|
||||
x2: x2 + dx2,
|
||||
xR,
|
||||
|
@ -5914,8 +5875,7 @@
|
|||
}
|
||||
|
||||
renderArrowLine({x1, y1, x2, y2}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
|
@ -5923,12 +5883,12 @@
|
|||
(x2 - x1) * (x2 - x1) +
|
||||
(y2 - y1) * (y2 - y1)
|
||||
);
|
||||
const d1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const d2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const d1 = lArrow.lineGap(env.theme, line);
|
||||
const d2 = rArrow.lineGap(env.theme, line);
|
||||
const dx = (x2 - x1) / len;
|
||||
const dy = (y2 - y1) / len;
|
||||
|
||||
const rendered = line.renderFlat(line.attrs, {
|
||||
const rendered = line.renderFlat({
|
||||
x1: x1 + d1 * dx,
|
||||
x2: x2 - d2 * dx,
|
||||
y1: y1 + d1 * dy,
|
||||
|
@ -8103,7 +8063,9 @@
|
|||
this.theme.addDefs(this.addThemeDef);
|
||||
|
||||
this.title.set({
|
||||
attrs: this.theme.titleAttrs,
|
||||
attrs: Object.assign({
|
||||
'class': 'title',
|
||||
}, this.theme.getTitleAttrs()),
|
||||
formatted: sequence.meta.title,
|
||||
});
|
||||
this.svg.textSizer.expectMeasure(this.title);
|
||||
|
@ -8722,11 +8684,15 @@
|
|||
|
||||
class SketchTheme extends BaseTheme {
|
||||
constructor(svg, handedness = RIGHT) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$3,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$3,
|
||||
});
|
||||
|
||||
this.handedness = (handedness === RIGHT) ? 1 : -1;
|
||||
this.random = new Random();
|
||||
this.wave = new SketchWavePattern(4, handedness);
|
||||
const wave = new SketchWavePattern(4, handedness);
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -8830,32 +8796,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'dash': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-dasharray': '4, 2',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'wave': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnectWave.bind(this),
|
||||
renderRev: this.renderRevConnectWave.bind(this),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -8912,14 +8852,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT_FAMILY,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$3,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': Object.assign({
|
||||
'fill': 'none',
|
||||
|
@ -9006,12 +8938,24 @@
|
|||
render: this.renderTearDivider.bind(this, {
|
||||
fadeBegin: 5,
|
||||
fadeSize: 10,
|
||||
pattern: this.wave,
|
||||
pattern: wave,
|
||||
lineAttrs: PENCIL.normal,
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: PENCIL.normal});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: wave,
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
@ -9216,85 +9160,85 @@
|
|||
return {shape};
|
||||
}
|
||||
|
||||
renderFlatConnect(attrs, {x1, y1, x2, y2}) {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
renderFlatConnect(pattern, attrs, {x1, y1, x2, y2}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderRevConnect(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
renderRevConnect(pattern, attrs, {x1, y1, x2, y2, xR}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
|
||||
renderFlatConnectWave(attrs, {x1, y1, x2, y2}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
}
|
||||
|
||||
renderRevConnectWave(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderArrowHead(attrs, {x, y, width, height, dir}) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -34,8 +34,24 @@
|
|||
}
|
||||
|
||||
class BaseTheme {
|
||||
constructor(svg) {
|
||||
constructor(svg, baseFontAttrs) {
|
||||
this.svg = svg;
|
||||
this.baseFontAttrs = baseFontAttrs;
|
||||
this.fontSize = this.baseFontAttrs['font-size'];
|
||||
this.connectLines = new Map();
|
||||
}
|
||||
|
||||
addConnectLine(type, {
|
||||
attrs = {},
|
||||
pattern = null,
|
||||
} = {}) {
|
||||
const base = this.connectLines.get('solid') || {attrs: {}};
|
||||
const fullAttrs = Object.assign({'fill': 'none'}, base.attrs, attrs);
|
||||
this.connectLines.set(type, {
|
||||
attrs: fullAttrs,
|
||||
renderFlat: this.renderFlatConnect.bind(this, pattern, fullAttrs),
|
||||
renderRev: this.renderRevConnect.bind(this, pattern, fullAttrs),
|
||||
});
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
|
@ -48,6 +64,18 @@
|
|||
// No-op
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign({}, this.baseFontAttrs, {
|
||||
'font-size': this.fontSize * 2.5,
|
||||
'text-anchor': 'middle',
|
||||
});
|
||||
}
|
||||
|
||||
getConnectLine(type) {
|
||||
const lines = this.connectLines;
|
||||
return lines.get(type) || lines.get('solid');
|
||||
}
|
||||
|
||||
getBlock(type) {
|
||||
return this.blocks[type] || this.blocks[''];
|
||||
}
|
||||
|
@ -355,8 +383,6 @@
|
|||
const FONT = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT = 1.3;
|
||||
|
||||
const WAVE = new WavePattern(6, 0.5);
|
||||
|
||||
const NOTE_ATTRS = {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
|
@ -372,7 +398,11 @@
|
|||
|
||||
class BasicTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -496,38 +526,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 2',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -593,14 +591,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -738,6 +728,21 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(6, 0.5),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -756,8 +761,6 @@
|
|||
const FONT$1 = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT$1 = 1.3;
|
||||
|
||||
const WAVE$1 = new WavePattern(10, 1);
|
||||
|
||||
const NOTE_ATTRS$1 = {
|
||||
'font-family': FONT$1,
|
||||
'font-size': 8,
|
||||
|
@ -773,7 +776,11 @@
|
|||
|
||||
class ChunkyTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$1,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$1,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -904,38 +911,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 8,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-dasharray': '10, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE$1),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE$1),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 10,
|
||||
|
@ -1005,15 +980,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT$1,
|
||||
'font-weight': 'bolder',
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$1,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -1156,6 +1122,27 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '10, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(10, 1),
|
||||
});
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign(super.getTitleAttrs(), {
|
||||
'font-weight': 'bolder',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2758,17 +2745,6 @@
|
|||
const FONT$2 = 'Courier New,Liberation Mono,monospace';
|
||||
const LINE_HEIGHT$2 = 1.3;
|
||||
|
||||
const WAVE$2 = new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]);
|
||||
|
||||
const NOTE_ATTRS$2 = {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 8,
|
||||
|
@ -2784,7 +2760,11 @@
|
|||
|
||||
class MonospaceTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$2,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -2908,36 +2888,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 4,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE$2),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE$2),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 4,
|
||||
|
@ -3003,14 +2953,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT$2,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$2,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -3142,6 +3084,26 @@
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
pattern: new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5691,13 +5653,13 @@
|
|||
return this.getConfig(theme).height;
|
||||
}
|
||||
|
||||
lineGap(theme, lineAttrs) {
|
||||
lineGap(theme, line) {
|
||||
const arrow = this.getConfig(theme);
|
||||
const short = this.short(theme);
|
||||
if(arrow.attrs.fill === 'none') {
|
||||
const h = arrow.height / 2;
|
||||
const w = arrow.width;
|
||||
const safe = short + (lineAttrs['stroke-width'] / 2) * (w / h);
|
||||
const safe = short + (line.attrs['stroke-width'] / 2) * (w / h);
|
||||
return (short + safe) / 2;
|
||||
} else {
|
||||
return short + arrow.width / 2;
|
||||
|
@ -5815,15 +5777,14 @@
|
|||
}
|
||||
|
||||
renderRevArrowLine({x1, y1, x2, y2, xR}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
const dx1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const dx2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const rendered = line.renderRev(line.attrs, {
|
||||
rad: config.loopbackRadius,
|
||||
const dx1 = lArrow.lineGap(env.theme, line);
|
||||
const dx2 = rArrow.lineGap(env.theme, line);
|
||||
const rendered = line.renderRev({
|
||||
rad: env.theme.connect.loopbackRadius,
|
||||
x1: x1 + dx1,
|
||||
x2: x2 + dx2,
|
||||
xR,
|
||||
|
@ -5914,8 +5875,7 @@
|
|||
}
|
||||
|
||||
renderArrowLine({x1, y1, x2, y2}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
|
@ -5923,12 +5883,12 @@
|
|||
(x2 - x1) * (x2 - x1) +
|
||||
(y2 - y1) * (y2 - y1)
|
||||
);
|
||||
const d1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const d2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const d1 = lArrow.lineGap(env.theme, line);
|
||||
const d2 = rArrow.lineGap(env.theme, line);
|
||||
const dx = (x2 - x1) / len;
|
||||
const dy = (y2 - y1) / len;
|
||||
|
||||
const rendered = line.renderFlat(line.attrs, {
|
||||
const rendered = line.renderFlat({
|
||||
x1: x1 + d1 * dx,
|
||||
x2: x2 - d2 * dx,
|
||||
y1: y1 + d1 * dy,
|
||||
|
@ -8103,7 +8063,9 @@
|
|||
this.theme.addDefs(this.addThemeDef);
|
||||
|
||||
this.title.set({
|
||||
attrs: this.theme.titleAttrs,
|
||||
attrs: Object.assign({
|
||||
'class': 'title',
|
||||
}, this.theme.getTitleAttrs()),
|
||||
formatted: sequence.meta.title,
|
||||
});
|
||||
this.svg.textSizer.expectMeasure(this.title);
|
||||
|
@ -8722,11 +8684,15 @@
|
|||
|
||||
class SketchTheme extends BaseTheme {
|
||||
constructor(svg, handedness = RIGHT) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT$3,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT$3,
|
||||
});
|
||||
|
||||
this.handedness = (handedness === RIGHT) ? 1 : -1;
|
||||
this.random = new Random();
|
||||
this.wave = new SketchWavePattern(4, handedness);
|
||||
const wave = new SketchWavePattern(4, handedness);
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -8830,32 +8796,6 @@
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'dash': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-dasharray': '4, 2',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'wave': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnectWave.bind(this),
|
||||
renderRev: this.renderRevConnectWave.bind(this),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -8912,14 +8852,6 @@
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT_FAMILY,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT$3,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': Object.assign({
|
||||
'fill': 'none',
|
||||
|
@ -9006,12 +8938,24 @@
|
|||
render: this.renderTearDivider.bind(this, {
|
||||
fadeBegin: 5,
|
||||
fadeSize: 10,
|
||||
pattern: this.wave,
|
||||
pattern: wave,
|
||||
lineAttrs: PENCIL.normal,
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: PENCIL.normal});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: wave,
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
@ -9216,85 +9160,85 @@
|
|||
return {shape};
|
||||
}
|
||||
|
||||
renderFlatConnect(attrs, {x1, y1, x2, y2}) {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
renderFlatConnect(pattern, attrs, {x1, y1, x2, y2}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderRevConnect(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
renderRevConnect(pattern, attrs, {x1, y1, x2, y2, xR}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
|
||||
renderFlatConnectWave(attrs, {x1, y1, x2, y2}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
}
|
||||
|
||||
renderRevConnectWave(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderArrowHead(attrs, {x, y, width, height, dir}) {
|
||||
|
|
|
@ -75,11 +75,11 @@ describe('SequenceDiagram', () => {
|
|||
'<g>' +
|
||||
'<text' +
|
||||
' x="0"' +
|
||||
' class="title"' +
|
||||
' font-family="Helvetica,Arial,Liberation Sans,sans-serif"' +
|
||||
' font-size="20"' +
|
||||
' line-height="1.3"' +
|
||||
' text-anchor="middle"' +
|
||||
' class="title"' +
|
||||
' y="-10">My title here</text>' +
|
||||
'</g>' +
|
||||
'<g mask="url(#FullMask)">' +
|
||||
|
|
|
@ -631,7 +631,9 @@ export default class Renderer extends EventObject {
|
|||
this.theme.addDefs(this.addThemeDef);
|
||||
|
||||
this.title.set({
|
||||
attrs: this.theme.titleAttrs,
|
||||
attrs: Object.assign({
|
||||
'class': 'title',
|
||||
}, this.theme.getTitleAttrs()),
|
||||
formatted: sequence.meta.title,
|
||||
});
|
||||
this.svg.textSizer.expectMeasure(this.title);
|
||||
|
|
|
@ -50,13 +50,13 @@ class Arrowhead {
|
|||
return this.getConfig(theme).height;
|
||||
}
|
||||
|
||||
lineGap(theme, lineAttrs) {
|
||||
lineGap(theme, line) {
|
||||
const arrow = this.getConfig(theme);
|
||||
const short = this.short(theme);
|
||||
if(arrow.attrs.fill === 'none') {
|
||||
const h = arrow.height / 2;
|
||||
const w = arrow.width;
|
||||
const safe = short + (lineAttrs['stroke-width'] / 2) * (w / h);
|
||||
const safe = short + (line.attrs['stroke-width'] / 2) * (w / h);
|
||||
return (short + safe) / 2;
|
||||
} else {
|
||||
return short + arrow.width / 2;
|
||||
|
@ -174,15 +174,14 @@ export class Connect extends BaseComponent {
|
|||
}
|
||||
|
||||
renderRevArrowLine({x1, y1, x2, y2, xR}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
const dx1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const dx2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const rendered = line.renderRev(line.attrs, {
|
||||
rad: config.loopbackRadius,
|
||||
const dx1 = lArrow.lineGap(env.theme, line);
|
||||
const dx2 = rArrow.lineGap(env.theme, line);
|
||||
const rendered = line.renderRev({
|
||||
rad: env.theme.connect.loopbackRadius,
|
||||
x1: x1 + dx1,
|
||||
x2: x2 + dx2,
|
||||
xR,
|
||||
|
@ -273,8 +272,7 @@ export class Connect extends BaseComponent {
|
|||
}
|
||||
|
||||
renderArrowLine({x1, y1, x2, y2}, options, env, clickable) {
|
||||
const config = env.theme.connect;
|
||||
const line = config.line[options.line];
|
||||
const line = env.theme.getConnectLine(options.line);
|
||||
const lArrow = ARROWHEADS[options.left];
|
||||
const rArrow = ARROWHEADS[options.right];
|
||||
|
||||
|
@ -282,12 +280,12 @@ export class Connect extends BaseComponent {
|
|||
(x2 - x1) * (x2 - x1) +
|
||||
(y2 - y1) * (y2 - y1)
|
||||
);
|
||||
const d1 = lArrow.lineGap(env.theme, line.attrs);
|
||||
const d2 = rArrow.lineGap(env.theme, line.attrs);
|
||||
const d1 = lArrow.lineGap(env.theme, line);
|
||||
const d2 = rArrow.lineGap(env.theme, line);
|
||||
const dx = (x2 - x1) / len;
|
||||
const dy = (y2 - y1) / len;
|
||||
|
||||
const rendered = line.renderFlat(line.attrs, {
|
||||
const rendered = line.renderFlat({
|
||||
x1: x1 + d1 * dx,
|
||||
x2: x2 - d2 * dx,
|
||||
y1: y1 + d1 * dy,
|
||||
|
|
|
@ -31,8 +31,24 @@ export class WavePattern {
|
|||
}
|
||||
|
||||
export default class BaseTheme {
|
||||
constructor(svg) {
|
||||
constructor(svg, baseFontAttrs) {
|
||||
this.svg = svg;
|
||||
this.baseFontAttrs = baseFontAttrs;
|
||||
this.fontSize = this.baseFontAttrs['font-size'];
|
||||
this.connectLines = new Map();
|
||||
}
|
||||
|
||||
addConnectLine(type, {
|
||||
attrs = {},
|
||||
pattern = null,
|
||||
} = {}) {
|
||||
const base = this.connectLines.get('solid') || {attrs: {}};
|
||||
const fullAttrs = Object.assign({'fill': 'none'}, base.attrs, attrs);
|
||||
this.connectLines.set(type, {
|
||||
attrs: fullAttrs,
|
||||
renderFlat: this.renderFlatConnect.bind(this, pattern, fullAttrs),
|
||||
renderRev: this.renderRevConnect.bind(this, pattern, fullAttrs),
|
||||
});
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
|
@ -45,6 +61,18 @@ export default class BaseTheme {
|
|||
// No-op
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign({}, this.baseFontAttrs, {
|
||||
'font-size': this.fontSize * 2.5,
|
||||
'text-anchor': 'middle',
|
||||
});
|
||||
}
|
||||
|
||||
getConnectLine(type) {
|
||||
const lines = this.connectLines;
|
||||
return lines.get(type) || lines.get('solid');
|
||||
}
|
||||
|
||||
getBlock(type) {
|
||||
return this.blocks[type] || this.blocks[''];
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import BaseTheme, {WavePattern} from './BaseTheme.mjs';
|
|||
const FONT = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT = 1.3;
|
||||
|
||||
const WAVE = new WavePattern(6, 0.5);
|
||||
|
||||
const NOTE_ATTRS = {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
|
@ -22,7 +20,11 @@ const DIVIDER_LABEL_ATTRS = {
|
|||
|
||||
export default class BasicTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -146,38 +148,6 @@ export default class BasicTheme extends BaseTheme {
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 2',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -243,14 +213,6 @@ export default class BasicTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -388,6 +350,21 @@ export default class BasicTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(6, 0.5),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ import BaseTheme, {WavePattern} from './BaseTheme.mjs';
|
|||
const FONT = 'Helvetica,Arial,Liberation Sans,sans-serif';
|
||||
const LINE_HEIGHT = 1.3;
|
||||
|
||||
const WAVE = new WavePattern(10, 1);
|
||||
|
||||
const NOTE_ATTRS = {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
|
@ -22,7 +20,11 @@ const DIVIDER_LABEL_ATTRS = {
|
|||
|
||||
export default class ChunkyTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -153,38 +155,6 @@ export default class ChunkyTheme extends BaseTheme {
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 8,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-dasharray': '10, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 10,
|
||||
|
@ -254,15 +224,6 @@ export default class ChunkyTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT,
|
||||
'font-weight': 'bolder',
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -405,6 +366,27 @@ export default class ChunkyTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 3,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '10, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: new WavePattern(10, 1),
|
||||
});
|
||||
}
|
||||
|
||||
getTitleAttrs() {
|
||||
return Object.assign(super.getTitleAttrs(), {
|
||||
'font-weight': 'bolder',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,6 @@ import BaseTheme, {WavePattern} from './BaseTheme.mjs';
|
|||
const FONT = 'Courier New,Liberation Mono,monospace';
|
||||
const LINE_HEIGHT = 1.3;
|
||||
|
||||
const WAVE = new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]);
|
||||
|
||||
const NOTE_ATTRS = {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
|
@ -31,7 +20,11 @@ const DIVIDER_LABEL_ATTRS = {
|
|||
|
||||
export default class MonospaceTheme extends BaseTheme {
|
||||
constructor(svg) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -155,36 +148,6 @@ export default class MonospaceTheme extends BaseTheme {
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 4,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'dash': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
'stroke-dasharray': '4, 4',
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, null),
|
||||
renderRev: this.renderRevConnect.bind(this, null),
|
||||
},
|
||||
'wave': {
|
||||
attrs: {
|
||||
'fill': 'none',
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
},
|
||||
renderFlat: this.renderFlatConnect.bind(this, WAVE),
|
||||
renderRev: this.renderRevConnect.bind(this, WAVE),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 4,
|
||||
|
@ -250,14 +213,6 @@ export default class MonospaceTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': {
|
||||
'fill': 'none',
|
||||
|
@ -389,6 +344,26 @@ export default class MonospaceTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: {
|
||||
'stroke': '#000000',
|
||||
'stroke-width': 1,
|
||||
}});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 4',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
pattern: new WavePattern(6, [
|
||||
+0,
|
||||
-0.25,
|
||||
-0.5,
|
||||
-0.25,
|
||||
+0,
|
||||
+0.25,
|
||||
+0.5,
|
||||
+0.25,
|
||||
]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,11 +72,15 @@ function clamp(v, low, high) {
|
|||
|
||||
export default class SketchTheme extends BaseTheme {
|
||||
constructor(svg, handedness = RIGHT) {
|
||||
super(svg);
|
||||
super(svg, {
|
||||
'font-family': FONT,
|
||||
'font-size': 8,
|
||||
'line-height': LINE_HEIGHT,
|
||||
});
|
||||
|
||||
this.handedness = (handedness === RIGHT) ? 1 : -1;
|
||||
this.random = new Random();
|
||||
this.wave = new SketchWavePattern(4, handedness);
|
||||
const wave = new SketchWavePattern(4, handedness);
|
||||
|
||||
const sharedBlockSection = {
|
||||
padding: {
|
||||
|
@ -180,32 +184,6 @@ export default class SketchTheme extends BaseTheme {
|
|||
|
||||
connect: {
|
||||
loopbackRadius: 6,
|
||||
line: {
|
||||
'solid': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'dash': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-dasharray': '4, 2',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnect.bind(this),
|
||||
renderRev: this.renderRevConnect.bind(this),
|
||||
},
|
||||
'wave': {
|
||||
attrs: Object.assign({
|
||||
'fill': 'none',
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
}, PENCIL.normal),
|
||||
renderFlat: this.renderFlatConnectWave.bind(this),
|
||||
renderRev: this.renderRevConnectWave.bind(this),
|
||||
},
|
||||
},
|
||||
arrow: {
|
||||
'single': {
|
||||
width: 5,
|
||||
|
@ -262,14 +240,6 @@ export default class SketchTheme extends BaseTheme {
|
|||
},
|
||||
},
|
||||
|
||||
titleAttrs: {
|
||||
'font-family': FONT_FAMILY,
|
||||
'font-size': 20,
|
||||
'line-height': LINE_HEIGHT,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'title',
|
||||
},
|
||||
|
||||
agentLineAttrs: {
|
||||
'': Object.assign({
|
||||
'fill': 'none',
|
||||
|
@ -356,12 +326,24 @@ export default class SketchTheme extends BaseTheme {
|
|||
render: this.renderTearDivider.bind(this, {
|
||||
fadeBegin: 5,
|
||||
fadeSize: 10,
|
||||
pattern: this.wave,
|
||||
pattern: wave,
|
||||
lineAttrs: PENCIL.normal,
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.addConnectLine('solid', {attrs: PENCIL.normal});
|
||||
this.addConnectLine('dash', {attrs: {
|
||||
'stroke-dasharray': '4, 2',
|
||||
}});
|
||||
this.addConnectLine('wave', {
|
||||
attrs: {
|
||||
'stroke-linejoin': 'round',
|
||||
'stroke-linecap': 'round',
|
||||
},
|
||||
pattern: wave,
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
@ -566,85 +548,85 @@ export default class SketchTheme extends BaseTheme {
|
|||
return {shape};
|
||||
}
|
||||
|
||||
renderFlatConnect(attrs, {x1, y1, x2, y2}) {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
renderFlatConnect(pattern, attrs, {x1, y1, x2, y2}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const ln = this.lineNodes(
|
||||
{x: x1, y: y1},
|
||||
{x: x2, y: y2},
|
||||
{varX: 0.3}
|
||||
);
|
||||
return {
|
||||
shape: this.svg.el('path').attr('d', ln.nodes).attrs(attrs),
|
||||
p1: ln.p1,
|
||||
p2: ln.p2,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderRevConnect(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
renderRevConnect(pattern, attrs, {x1, y1, x2, y2, xR}) {
|
||||
if(pattern) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(pattern)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
} else {
|
||||
const variance = Math.min((xR - x1) * 0.06, 3);
|
||||
const overshoot = Math.min((xR - x1) * 0.5, 6);
|
||||
const p1x = x1 + this.vary(variance, -1);
|
||||
const p1y = y1 + this.vary(variance, -1);
|
||||
const b1x = xR - overshoot * this.vary(0.2, 1);
|
||||
const b1y = y1 - this.vary(1, 2);
|
||||
const p2x = xR;
|
||||
const p2y = y1 + this.vary(1, 1);
|
||||
const b2x = xR;
|
||||
const b2y = y2 + this.vary(2);
|
||||
const p3x = x2 + this.vary(variance, -1);
|
||||
const p3y = y2 + this.vary(variance, -1);
|
||||
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
|
||||
renderFlatConnectWave(attrs, {x1, y1, x2, y2}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
}
|
||||
|
||||
renderRevConnectWave(attrs, {x1, y1, x2, y2, xR}) {
|
||||
const x1v = x1 + this.vary(0.3);
|
||||
const x2v = x2 + this.vary(0.3);
|
||||
const y1v = y1 + this.vary(1);
|
||||
const y2v = y2 + this.vary(1);
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', this.svg.patternedLine(this.wave)
|
||||
.move(x1v, y1v)
|
||||
.line(xR, y1)
|
||||
.arc(xR, (y1 + y2) / 2, Math.PI)
|
||||
.line(x2v, y2v)
|
||||
.cap()
|
||||
.asPath())
|
||||
.attrs(attrs),
|
||||
p1: {x: x1v, y: y1v},
|
||||
p2: {x: x2v, y: y2v},
|
||||
};
|
||||
return {
|
||||
shape: this.svg.el('path')
|
||||
.attr('d', (
|
||||
'M' + p1x + ' ' + p1y +
|
||||
'C' + p1x + ' ' + p1y +
|
||||
',' + b1x + ' ' + b1y +
|
||||
',' + p2x + ' ' + p2y +
|
||||
'S' + b2x + ' ' + b2y +
|
||||
',' + p3x + ' ' + p3y
|
||||
))
|
||||
.attrs(attrs),
|
||||
p1: {x: p1x, y: p1y},
|
||||
p2: {x: p3x, y: p3y},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
renderArrowHead(attrs, {x, y, width, height, dir}) {
|
||||
|
|
Loading…
Reference in New Issue