Extracting code to layout elements vertically

This commit is contained in:
Jeff Avallone 2014-12-09 20:08:34 -05:00
parent 0f97afd880
commit 7082a670d6
3 changed files with 76 additions and 62 deletions

View File

@ -82,5 +82,35 @@ export default {
.add(element.transform().localMatrix)
.translate(0, verticalCenter - item.getBBox().cy));
});
},
spaceVertically(items, options) {
var horizontalCenter = 0;
_.defaults(options, {
padding: 0
});
_.reduce(items, (offset, item) => {
var element = item.container || item,
box;
element.transform(Snap.matrix()
.translate(0, offset));
box = item.getBBox();
horizontalCenter = Math.max(horizontalCenter, box.cx);
return offset + options.padding + box.height;
}, 0);
_.each(items, item => {
var element = item.container || item;
element.transform(Snap.matrix()
.add(element.transform().localMatrix)
.translate(horizontalCenter - item.getBBox().cx, 0));
});
}
};

View File

@ -29,31 +29,16 @@ export default _.extend({}, Base, {
},
position() {
var box, offset = 0;
var box;
_.each(this.parts.elements, (part => {
var box;
_.invoke(this.parts.elements, 'position');
part.position();
part.container.transform(Snap.matrix()
.translate(0, offset));
box = part.getBBox();
offset += box.height + 5;
}).bind(this));
this.spaceVertically(this.parts.elements, {
padding: 5
});
box = this.partContainer.getBBox();
_.each(this.parts.elements, (part => {
var partBox = part.getBBox();
part.container.transform(Snap.matrix()
.add(part.container.transform().localMatrix)
.translate(box.cx - partBox.cx, 0));
}).bind(this));
this.box.attr({
width: box.width + 10,
height: box.height + 10

View File

@ -7,66 +7,65 @@ export default _.extend({}, Base, {
render() {
var self = this;
this.matchContainer = this.container.group();
_.each(this.matches(), match => {
match.container = self.container.group();
match.container = self.matchContainer.group();
match.render();
return match.container;
});
},
position() {
var self = this,
center,
positions,
totalHeight,
verticalCenter,
matches = this.matches(),
var matches = this.matches(),
includeLines = (matches.length > 1),
paths = [];
containerBox,
paths;
_.invoke(matches, 'position');
positions = _.chain(matches)
.map(match => {
return {
match,
box: match.getBBox()
};
});
center = positions.reduce((center, pos) => {
return Math.max(center, pos.box.cx);
}, 0).value();
totalHeight = positions.reduce((offset, pos) => {
pos.match.container.transform(Snap.matrix()
.translate(center - pos.box.cx + (includeLines ? 20 : 0), offset));
return offset + pos.box.height + 5;
}, 0).value() - 5;
verticalCenter = totalHeight / 2
this.spaceVertically(matches, {
padding: 5
});
if (includeLines) {
positions.each(pos => {
var box = pos.match.getBBox(),
direction = box.cy > verticalCenter ? 1 : -1,
this.matchContainer.transform(Snap.matrix()
.translate(20, 0));
containerBox = this.getBBox();
paths = _.map(matches, match => {
var box = match.getBBox(),
direction = box.cy > containerBox.cy ? 1 : -1,
distance = Math.abs(box.cy - containerBox.cy),
pathStr;
pathStr = (verticalCenter === box.cy) ?
'M0,{center}H{side}' :
'M0,{center}q10,0 10,{d}V{target}q0,{d} 10,{d}H{side}';
if (distance >= 15) {
pathStr = 'M10,{box.cy}m0,{shift}q0,{curve} 10,{curve}h{box.x}';
} else {
pathStr = 'M0,{containerBox.cy}c20,0 20,{anchor.y} {anchor.x},{anchor.y}';
}
paths.push(Snap.format(pathStr, {
center: verticalCenter,
target: box.cy - 10 * direction,
side: box.x,
d: 10 * direction
}));
return Snap.format(pathStr, {
containerBox,
box,
shift: -10 * direction,
curve: 10 * direction,
anchor: {
x: box.x + 20,
y: box.cy - containerBox.cy
}
});
});
this.container.path(paths.join(''))
.clone().transform(Snap.matrix()
.scale(-1, 1, center + 20, 0));
paths.push(Snap.format('M0,{box.cy}q10,0 10,-10V{top}M0,{box.cy}q10,0 10,10V{bottom}', {
box: containerBox,
top: _.first(matches).getBBox().cy + 10,
bottom: _.last(matches).getBBox().cy - 10
}));
this.container.prepend(this.container.path(paths.join('')));
this.container.prepend(this.container.path(paths.join(''))
.transform(Snap.matrix().scale(-1, 1, containerBox.cx, 0)));
}
},