diff --git a/config/config.ts b/config/config.ts
deleted file mode 100644
index ffc07605908..00000000000
--- a/config/config.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export var config = {
- precision: 2
-}
diff --git a/index.ts b/index.ts
index 011eec6d081..421de55c03a 100644
--- a/index.ts
+++ b/index.ts
@@ -1,13 +1,12 @@
import { Pattern } from './lib/pattern'
import { Point } from './lib/point'
import { Path } from './lib/path'
-import { config } from './config/config'
+import themes from './lib/themes'
import * as utils from './lib/utils'
import bezier from 'bezier-js'
var Freesewing = {
version: '1.0.1',
- config,
pattern: Pattern,
point: Point,
path: Path,
diff --git a/lib/path.ts b/lib/path.ts
index cd01d67af24..bbe2bbabb65 100644
--- a/lib/path.ts
+++ b/lib/path.ts
@@ -3,10 +3,7 @@ import { Attributes } from './attributes'
export class Path {
- constructor() {
- return this;
- }
-
+ render: boolean = true;
ops: {
type: "move" | "line" | "curve" | "close";
to?: Point;
@@ -69,10 +66,4 @@ export class Path {
return d;
}
- /** Returns SVG code for this path */
- render(): string {
- this.attributes.add('d', this.asPathstring());
- return ``;
-
- }
}
diff --git a/lib/pattern.ts b/lib/pattern.ts
index fdc29a05734..9e39bb5345e 100644
--- a/lib/pattern.ts
+++ b/lib/pattern.ts
@@ -1,14 +1,18 @@
import { PatternConfig, PatternOption } from './types'
import { Part } from './part'
-import { Renderer } from './renderer'
+import { Svg } from './svg'
import { Option } from './option'
+import themes from './themes'
+import { Theme } from './themes/theme'
export class Pattern {
config: PatternConfig;
+ svg: Svg = new Svg();
parts: {
[index: string]: Part;
}
options: {[propName: string]: number};
+ themes: {[index:string]: Theme} = themes;
constructor(config: PatternConfig) {
this.config = config;
@@ -31,8 +35,8 @@ export class Pattern {
throw Error('You have to implement the draft() method in your Pattern instance.');
}
- render(pattern: Pattern): string {
- let r = new Renderer();
- return r.render(pattern);
+ render(): string {
+ let svg = new Svg();
+ return svg.render(this);
}
}
diff --git a/lib/point.ts b/lib/point.ts
index 008bbd6cb8e..1a70db9089e 100644
--- a/lib/point.ts
+++ b/lib/point.ts
@@ -1,11 +1,10 @@
import { round, rad2deg, deg2rad } from './utils';
-const PRECISION = 2;
export class Point {
x: number;
y: number;
-
+ readonly PRECISION = 2;
constructor(x: number, y: number) {
this.x = round(x);
@@ -19,7 +18,7 @@ export class Point {
let dx = this.x - that.x;
let dy = this.y - that.y;
- return round(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy,2)));
+ return round(Math.sqrt(Math.pow(dx, this.PRECISION) + Math.pow(dy, this.PRECISION)));
}
/** Returns slope of a line made by this point and that point */
diff --git a/lib/renderer.ts b/lib/svg.ts
similarity index 74%
rename from lib/renderer.ts
rename to lib/svg.ts
index 26e1519e5ad..ea9762d45be 100644
--- a/lib/renderer.ts
+++ b/lib/svg.ts
@@ -3,14 +3,27 @@ import { Path } from './path'
import { Pattern } from './pattern'
import { Attributes } from './attributes'
-export class Renderer {
- svg = '';
+export class Svg {
+ prefix: string;
+ body: string = '';
+ style: string = '';
+ header: string = '';
+ footer: string = '';
+ defs: string = '';
+ attributes: Attributes = new Attributes();
readonly TAB = ' ';
tabs: number = 0;
freeId: number = 1;
openGroups: string[] = [];
constructor() {
+ this.prefix = '';
+ this.attributes.add
+ this.attributes.add("xmlns", "http://www.w3.org/2000/svg");
+ this.attributes.add("xmlns:svg", "http://www.w3.org/2000/svg");
+ this.attributes.add("xmlns:xlink", "http://www.w3.org/1999/xlink");
+ this.attributes.add("xmlns:freesewing", "http://freesewing.org/namespaces/freesewing");
+
return this;
}
@@ -49,7 +62,8 @@ export class Renderer {
/** Returns SVG code for a Path object */
renderPath(path: Path): string {
- return `${this.nl()}`;
+ path.attributes.add('d', path.asPathstring());
+ return `${this.nl()}`;
}
diff --git a/lib/themes.ts b/lib/themes.ts
new file mode 100644
index 00000000000..9812b98c960
--- /dev/null
+++ b/lib/themes.ts
@@ -0,0 +1,14 @@
+import { Draft } from './themes/draft'
+import { Paperless } from './themes/paperless'
+import { Sample } from './themes/sample'
+import { Compare } from './themes/compare'
+
+/** Standard themes that ship with freesewing */
+var themes = {
+ draft: new Draft(),
+ paperless: new Paperless(),
+ sample: new Sample(),
+ compare: new Compare()
+}
+
+export default themes;
diff --git a/lib/themes/compare.ts b/lib/themes/compare.ts
new file mode 100644
index 00000000000..d11ed206a75
--- /dev/null
+++ b/lib/themes/compare.ts
@@ -0,0 +1,10 @@
+import { Sample } from './sample';
+
+export class Compare extends Sample {
+ constructor() {
+ super();
+ this.style += `
+ path.compare { fill: #000000; fill-opacity: 0.05; stroke: #000000; stroke-opacity:0.5; stroke-width: 1; stroke-linecap:round; stroke-linejoin:round; }
+ `;
+ }
+}
diff --git a/lib/themes/draft.ts b/lib/themes/draft.ts
new file mode 100644
index 00000000000..b88e72c9790
--- /dev/null
+++ b/lib/themes/draft.ts
@@ -0,0 +1,3 @@
+import { Theme } from './theme';
+
+export class Draft extends Theme {}
diff --git a/lib/themes/paperless.ts b/lib/themes/paperless.ts
new file mode 100644
index 00000000000..48c115b0177
--- /dev/null
+++ b/lib/themes/paperless.ts
@@ -0,0 +1,30 @@
+import { Sample } from './sample';
+
+export class Paperless extends Sample {
+ constructor() {
+ super();
+ this.style += `
+ rect.grid{fill:none;stroke:#555;stroke-width:0.3;fill:url(#grid);}
+ path.gridline{stroke:#555;stroke-width:0.2;}
+ path.gridline-lg{stroke:#777;stroke-width:0.2;stroke-dasharray:1.5,1.5;}
+ path.gridline-sm{stroke:#999;stroke-width:0.1;}
+ path.gridline-xs{stroke:#999;stroke-width:0.1;stroke-dasharray:0.5,0.5;}
+ `;
+ this.defs += `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+}
diff --git a/lib/themes/sample.ts b/lib/themes/sample.ts
new file mode 100644
index 00000000000..7fa3e29c4a2
--- /dev/null
+++ b/lib/themes/sample.ts
@@ -0,0 +1,11 @@
+import { Theme } from './theme';
+
+export class Sample extends Theme {
+ constructor() {
+ super();
+ this.style += `
+ path { fill: none; stroke: #000000; stroke-opacity:1; stroke-width: 0.5; stroke-miterlimit:4; stroke-dashoffset:0; stroke-linecap:round; stroke-linejoin:round; }
+ path.hidden { fill: none; stroke: none; }
+ `;
+ }
+}
diff --git a/lib/themes/theme.ts b/lib/themes/theme.ts
new file mode 100644
index 00000000000..5e8a63c4456
--- /dev/null
+++ b/lib/themes/theme.ts
@@ -0,0 +1,144 @@
+export abstract class Theme {
+ header: string = '';
+ footer: string = '';
+ defs: string = '';
+ style: string = '';
+
+ constructor() {
+ this.header = this.loadHeader();
+ this.footer = this.loadFooter();
+ this.style = this.loadStyle();
+ this.defs = this.loadDefs();
+ }
+
+ /** Returns a string containing the SVG header */
+ loadHeader() {
+
+ return `
+
+`;
+ }
+
+ /** Returns a string containing the SVG footer */
+ loadFooter() {
+ return '';
+ }
+
+ /** Returns a string containing the SVG style/CSS */
+ loadStyle() {
+ return `
+ path,circle,rect{fill:none;stroke:none}
+ path{fill:none;stroke:#000;stroke-opacity:1;stroke-width:.3;stroke-linecap:round;stroke-linejoin:round}
+ path.fabric{stroke-width:.6;stroke:#653f95}
+ path.lining{stroke-width:.6;stroke:#0275d8}
+ path.interfacing{stroke-width:.6;stroke:#d9534f}
+ path.canvas{stroke-width:.6;stroke:#5cb85c}
+ path.various{stroke-width:.6;stroke:#5bc0de}
+ path.sa{stroke-dasharray:0.4,0.8}
+ path.help{stroke-width:.2;stroke-dasharray:15,1.5,1,1.5}
+ path.hint{stroke-width:.2;stroke-dasharray:0.4,0.8}
+ path.note{stroke:#0275d8;stroke-width:.6;marker-start:url(#noteArrow)}
+ text{font-size:5px;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;fill:#000;
+ text-anchor:start;font-weight:200}
+ text.center{text-anchor:middle}
+ text.part-nr{font-size:28px;text-anchor:middle;fill:#000;font-weight:100}
+ text.part-nr.horizontal{text-anchor:start}
+ text.part-title{font-size:18px;text-anchor:middle;fill:#000}
+ text.part-title.horizontal{text-anchor:start}
+ text.pattern-title{font-size:8px;font-weight:bold;text-anchor:middle;fill:#000}
+ text.pattern-title.horizontal{text-anchor:start}
+ text.part-msg{font-size:10px;text-anchor:middle}
+ text.part-meta{font-size:7px;text-anchor:middle}
+ text.part-msg.horizontal,text.part-meta.horizontal,text.part-title.vertical,text.part-msg.vertical{text-anchor:start}
+ text.part-nr.small{font-size:14px}
+ text.part-title.small{font-size:9px}
+ text.pattern-title.small{font-size:4px}
+ text.part-msg.small{font-size:5px}
+ text.part-meta.small{font-size:5px}
+ text.part-nr.extrasmall{font-size:7px}
+ text.part-title.extrasmall{font-size:5px}
+ text.pattern-title.extrasmall{font-size:3px}
+ text.part-msg.extrasmall{font-size:4px}
+ text.part-meta.extrasmall{font-size:3px}
+ text.note,text.dimension-label{fill:#0275d8}
+ text.note tspan{alignment-baseline:middle}
+ text.note-5,text.note-6,text.note-7,text.note-11,text.note-12,text.note-0,text.note-1,text.dimension-label{text-anchor:middle}
+ text.note-8,text.note-9,text.note-10{text-anchor:end}
+ text.dimension-label{font-size:7px}
+ text.grainline{fill:#999}
+ path.arrow{stroke:#0275d8}
+ path.grainline{stroke:#999;stroke-width:.6;marker-start:url(#grainlineStart);marker-end:url(#grainlineEnd)}
+ path.dimension{stroke:#0275d8;stroke-width:.6;marker-start:url(#dimensionStart);marker-end:url(#dimensionEnd)}
+ path.dimension.dimension-sm{stroke-width:.3}
+ path.dimension-leader{stroke:#0275d8;stroke-width:.3}
+ path.single-arrow{marker-start:url(#dimensionStart)}
+ path.double-arrow{marker-start:url(#dimensionStart);marker-end:url(#dimensionEnd)}
+ .text-xs{font-size:3px}
+ .text-sm{font-size:4px}
+ .text-lg{font-size:7px}
+ .text-xl{font-size:9px}
+ .text-center{text-anchor:middle}
+ .stroke-xs{stroke-width:.1}
+ .stroke-sm{stroke-width:.2}
+ .stroke-lg{stroke-width:.6}
+ .stroke-xl{stroke-width:1}
+ .stroke-xxl{stroke-width:2}
+ .dashed{stroke-dasharray:1,1.5}
+ .lashed{stroke-dasharray:6,6}
+ .dotted{stroke-dasharray:0.4,0.8}
+ .hidden{stroke:none;file:none}
+ .stroke-fabric{stroke:#653f95}
+ .stroke-lining{stroke:#0275d8}
+ .stroke-interfacing{stroke:#d9534f}
+ .stroke-canvas{stroke:#5cb85c}
+ .stroke-note{stroke:#0275d8}
+ .stroke-mark{stroke:#f0ad4e}
+ .stroke-hint{stroke:#86739c}
+ .stroke-gray{stroke:#999}
+ .fill-fabric{fill:#653f95}
+ .fill-lining{fill:#0275d8}
+ .fill-interfacing{fill:#d9534f}
+ .fill-canvas{fill:#5cb85c}
+ .fill-note{fill:#0275d8}
+ .fill-mark{fill:#f0ad4e}
+ .fill-hint{fill:#86739c}
+ .fill-gray{fill:#999}`;
+ }
+
+ /** Returns a string containing the SVG defs */
+ loadDefs() {
+ return `
+
+
+
+
+
+
+
+
+
+
+ freesewing core v__VERSION__ __TITLE__ freesewing.org/drafts/__DRAFTHANDLE__ __SCALEBOX_METRIC__ __SCALEBOX_IMPERIAL__
+
+
+
+
+
+
+
+
+
+`;
+ }
+}