✨ Added new layout setting to bypass bin packing
This commit is contained in:
parent
33785b5311
commit
eee6c2814a
5 changed files with 82 additions and 171 deletions
|
@ -11,8 +11,8 @@ import Attributes from "./attributes";
|
|||
|
||||
export default function Pattern(config = { options: {} }) {
|
||||
this.config = config; // Pattern configuration
|
||||
this.width = false; // Will be set after render
|
||||
this.height = false; // Will be set after render
|
||||
this.width = 0; // Will be set after render
|
||||
this.height = 0; // Will be set after render
|
||||
this.is = ""; // Will be set when drafting/sampling
|
||||
|
||||
this.store = new Store(); // Store for sharing data across parts
|
||||
|
@ -31,6 +31,7 @@ export default function Pattern(config = { options: {} }) {
|
|||
locale: "en",
|
||||
units: "metric",
|
||||
margin: 2,
|
||||
layout: true,
|
||||
options: {}
|
||||
};
|
||||
|
||||
|
@ -383,24 +384,28 @@ Pattern.prototype.pack = function() {
|
|||
for (let key in this.parts) {
|
||||
let part = this.parts[key];
|
||||
// Avoid multiple render calls to cause stacking of transforms
|
||||
part.attributes.set("transform", "");
|
||||
part.attributes.remove("transform");
|
||||
if (part.render && this.needs(key)) {
|
||||
part.stack();
|
||||
bins.push({
|
||||
id: key,
|
||||
width: part.bottomRight.x - part.topLeft.x,
|
||||
height: part.bottomRight.y - part.topLeft.y
|
||||
});
|
||||
let width = part.bottomRight.x - part.topLeft.x;
|
||||
let height = part.bottomRight.y - part.topLeft.y;
|
||||
if (this.settings.layout) bins.push({ id: key, width, height });
|
||||
else {
|
||||
if (this.width < width) this.width = width;
|
||||
if (this.height < height) this.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
let size = pack(bins, { inPlace: true });
|
||||
for (let bin of bins) {
|
||||
let part = this.parts[bin.id];
|
||||
if (bin.x !== 0 || bin.y !== 0)
|
||||
part.attr("transform", `translate (${bin.x}, ${bin.y})`);
|
||||
if (this.settings.layout) {
|
||||
let size = pack(bins, { inPlace: true });
|
||||
for (let bin of bins) {
|
||||
let part = this.parts[bin.id];
|
||||
if (bin.x !== 0 || bin.y !== 0)
|
||||
part.attr("transform", `translate (${bin.x}, ${bin.y})`);
|
||||
}
|
||||
this.width = size.width;
|
||||
this.height = size.height;
|
||||
}
|
||||
this.width = size.width;
|
||||
this.height = size.height;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
56
src/svg.js
56
src/svg.js
|
@ -4,12 +4,11 @@ import { version } from "../package.json";
|
|||
|
||||
function Svg(pattern) {
|
||||
this.openGroups = [];
|
||||
this.layout = {};
|
||||
this.freeId = 0;
|
||||
this.body = "";
|
||||
this.style = "";
|
||||
this.script = "";
|
||||
this.header = "";
|
||||
this.footer = "";
|
||||
this.defs = "";
|
||||
this.pattern = pattern; // Needed to expose pattern to hooks
|
||||
this.prefix = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
|
||||
|
@ -52,39 +51,59 @@ Svg.prototype.debug = function() {};
|
|||
Svg.prototype.render = function(pattern) {
|
||||
this.idPrefix = pattern.settings.idPrefix;
|
||||
this.runHooks("preRender");
|
||||
//this.preRender();
|
||||
if (!pattern.settings.embed) {
|
||||
this.attributes.add("width", pattern.width + "mm");
|
||||
this.attributes.add("height", pattern.height + "mm");
|
||||
}
|
||||
this.attributes.add("viewBox", `0 0 ${pattern.width} ${pattern.height}`);
|
||||
this.svg = this.prefix;
|
||||
this.svg += this.renderComments(this.header);
|
||||
this.svg += this.renderSvgTag(pattern);
|
||||
this.svg += this.renderStyle();
|
||||
this.svg += this.renderScript();
|
||||
this.svg += this.renderDefs();
|
||||
this.svg += this.openGroup(this.idPrefix + "container");
|
||||
this.head = this.renderHead();
|
||||
this.tail = this.renderTail();
|
||||
this.svg = "";
|
||||
this.layout = {}; // Reset layout
|
||||
for (let partId in pattern.parts) {
|
||||
let part = pattern.parts[partId];
|
||||
if (part.render && pattern.needs(partId)) {
|
||||
let partSvg = this.renderPart(part);
|
||||
this.layout[partId] = {
|
||||
svg: partSvg,
|
||||
transform: part.attributes.getAsArray("transform")
|
||||
};
|
||||
this.svg += this.openGroup(
|
||||
`${this.idPrefix}part-${partId}`,
|
||||
part.attributes
|
||||
);
|
||||
this.svg += this.renderPart(part);
|
||||
this.svg += partSvg;
|
||||
this.svg += this.closeGroup();
|
||||
}
|
||||
}
|
||||
this.svg += this.closeGroup();
|
||||
this.svg += this.nl() + "</svg>";
|
||||
this.svg += this.renderComments(this.footer);
|
||||
this.svg =
|
||||
this.prefix + this.renderSvgTag() + this.head + this.svg + this.tail;
|
||||
this.runHooks("postRender");
|
||||
|
||||
return this.svg;
|
||||
};
|
||||
|
||||
/** Renders SVG head section */
|
||||
Svg.prototype.renderHead = function() {
|
||||
let svg = this.renderStyle();
|
||||
svg += this.renderScript();
|
||||
svg += this.renderDefs();
|
||||
svg += this.openGroup(this.idPrefix + "container");
|
||||
|
||||
return svg;
|
||||
};
|
||||
|
||||
/** Renders SVG closing section */
|
||||
Svg.prototype.renderTail = function() {
|
||||
let svg = "";
|
||||
svg += this.closeGroup();
|
||||
svg += this.nl() + "</svg>";
|
||||
|
||||
return svg;
|
||||
};
|
||||
|
||||
/** Returns SVG code for the opening SVG tag */
|
||||
Svg.prototype.renderSvgTag = function(pattern) {
|
||||
Svg.prototype.renderSvgTag = function() {
|
||||
let svg = "<svg";
|
||||
this.indent();
|
||||
svg += this.nl() + this.attributes.render();
|
||||
|
@ -126,13 +145,6 @@ Svg.prototype.renderDefs = function() {
|
|||
return svg;
|
||||
};
|
||||
|
||||
/** Returns SVG code for a comment block */
|
||||
Svg.prototype.renderComments = function(comments) {
|
||||
return (
|
||||
this.nl() + this.nl() + "<!--" + this.nl() + comments + this.nl() + "-->"
|
||||
);
|
||||
};
|
||||
|
||||
/** Returns SVG code for a Part object */
|
||||
Svg.prototype.renderPart = function(part) {
|
||||
let svg = "";
|
||||
|
|
156
tests/fixtures/render.js
vendored
156
tests/fixtures/render.js
vendored
|
@ -1,11 +1,7 @@
|
|||
var version = require("../../package.json").version;
|
||||
|
||||
var render = {
|
||||
boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -25,16 +21,8 @@ var render = {
|
|||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="nl" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -54,16 +42,8 @@ var render = {
|
|||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -83,16 +63,8 @@ var render = {
|
|||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
part: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
part: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -117,16 +89,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
path: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
path: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -152,16 +116,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
text: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
text: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -188,16 +144,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
circle: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
circle: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="104mm" height="104mm" viewBox="0 0 104 104"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -227,16 +175,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
multiText: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
multiText: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -263,16 +203,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
multiTextDflt: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
multiTextDflt: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -299,16 +231,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
textOnPath: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
textOnPath: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -336,16 +260,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
textOnPathCenter: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
textOnPathCenter: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -373,16 +289,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
textOnPathRight: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
textOnPathRight: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -410,16 +318,8 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`,
|
||||
snippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!--
|
||||
|
||||
--><svg
|
||||
</svg>`,
|
||||
snippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
@ -445,11 +345,7 @@ var render = {
|
|||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>
|
||||
|
||||
<!--
|
||||
|
||||
-->`
|
||||
</svg>`
|
||||
};
|
||||
|
||||
module.exports = render;
|
||||
|
|
|
@ -9,8 +9,8 @@ it("Pattern constructor should initialize object", () => {
|
|||
percentage: { pct: 30, min: 0, max: 100 }
|
||||
}
|
||||
});
|
||||
expect(pattern.width).to.equal(false);
|
||||
expect(pattern.height).to.equal(false);
|
||||
expect(pattern.width).to.equal(0);
|
||||
expect(pattern.height).to.equal(0);
|
||||
expect(pattern.settings.complete).to.equal(true);
|
||||
expect(pattern.parts).to.eql({});
|
||||
expect(pattern.settings.units).to.equal("metric");
|
||||
|
|
|
@ -15,9 +15,7 @@ it("Svg constructor should initialize object", () => {
|
|||
expect(svg.body).to.equal("");
|
||||
expect(svg.style).to.equal("");
|
||||
expect(svg.script).to.equal("");
|
||||
expect(svg.header).to.equal("");
|
||||
expect(svg.defs).to.equal("");
|
||||
expect(svg.footer).to.equal("");
|
||||
expect(svg.pattern).to.eql(pattern);
|
||||
expect(svg.prefix).to.equal(
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue