:wip: Working on design theme
This needs to be taken out of this repo later
This commit is contained in:
parent
659e57916c
commit
2160980ed4
9 changed files with 222 additions and 7 deletions
2
index.ts
2
index.ts
|
@ -1,6 +1,7 @@
|
|||
import { Pattern } from './lib/pattern'
|
||||
import { Point } from './lib/point'
|
||||
import { Path } from './lib/path'
|
||||
import { Snippet } from './lib/snippet'
|
||||
import themes from './lib/themes'
|
||||
import * as utils from './lib/utils'
|
||||
import bezier from 'bezier-js'
|
||||
|
@ -10,6 +11,7 @@ var Freesewing = {
|
|||
pattern: Pattern,
|
||||
point: Point,
|
||||
path: Path,
|
||||
snippet: Snippet,
|
||||
utils,
|
||||
bezier
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Point } from './point'
|
||||
import { Path } from './path'
|
||||
import { Snippet } from './snippet'
|
||||
import { Attributes } from './attributes'
|
||||
|
||||
export class Part {
|
||||
|
@ -9,6 +10,7 @@ export class Part {
|
|||
[index: string]: Point | boolean;
|
||||
}
|
||||
paths: { [index: string]: Path; } = {};
|
||||
snippets: { [index: string]: Snippet; } = {};
|
||||
attributes = new Attributes();
|
||||
[propName: string]: any;
|
||||
|
||||
|
@ -20,7 +22,6 @@ export class Part {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
// purge = {
|
||||
// points = function(prefix: string): void {}
|
||||
// paths = function(prefix: string): void {}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { round, rad2deg, deg2rad } from './utils';
|
||||
|
||||
import { Attributes } from './attributes'
|
||||
|
||||
export class Point {
|
||||
x: number;
|
||||
y: number;
|
||||
attributes: Attributes = new Attributes();
|
||||
|
||||
constructor(x: number, y: number) {
|
||||
this.x = round(x);
|
||||
|
|
17
lib/snippet.ts
Normal file
17
lib/snippet.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Point } from './point'
|
||||
import { Attributes } from './attributes'
|
||||
|
||||
export class Snippet {
|
||||
anchor: Point;
|
||||
def: string;
|
||||
attributes: Attributes = new Attributes();
|
||||
description: string | false;
|
||||
|
||||
constructor(anchor: Point, def: string, description: string | false = false) {
|
||||
this.anchor = anchor;
|
||||
this.def = def;
|
||||
this.description = description;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
36
lib/svg.ts
36
lib/svg.ts
|
@ -1,5 +1,6 @@
|
|||
import { Part } from './part'
|
||||
import { Path } from './path'
|
||||
import { Snippet } from './snippet'
|
||||
import { Pattern } from './pattern'
|
||||
import { Attributes } from './attributes'
|
||||
|
||||
|
@ -7,6 +8,7 @@ export class Svg {
|
|||
prefix: string;
|
||||
body: string = '';
|
||||
style: string = '';
|
||||
script: string = '';
|
||||
header: string = '';
|
||||
footer: string = '';
|
||||
defs: string = '';
|
||||
|
@ -33,6 +35,7 @@ export class Svg {
|
|||
svg += this.renderComments(this.header);
|
||||
svg += this.renderSvgTag(pattern);
|
||||
svg += this.renderStyle();
|
||||
svg += this.renderScript();
|
||||
svg += this.renderDefs();
|
||||
svg += this.openGroup('draftContainer');
|
||||
for (let partId in pattern.parts) {
|
||||
|
@ -72,6 +75,17 @@ export class Svg {
|
|||
return svg;
|
||||
}
|
||||
|
||||
/** Returns SVG code for the script block */
|
||||
renderScript() {
|
||||
let svg = '<script type="text/javascript"> <![CDATA[';
|
||||
this.indent();
|
||||
svg += this.nl()+this.script;
|
||||
this.outdent();
|
||||
svg += this.nl()+']]> >'+this.nl()+'</script>'+this.nl();
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
||||
/** Returns SVG code for the defs block */
|
||||
renderDefs() {
|
||||
let svg = '<defs id="defs">';
|
||||
|
@ -91,16 +105,19 @@ export class Svg {
|
|||
/** Returns SVG code for a Part object */
|
||||
renderPart(part: Part): string {
|
||||
let svg = '';
|
||||
for (let pathId in part.paths) {
|
||||
let path = part.paths[pathId];
|
||||
for (let key in part.paths) {
|
||||
let path = part.paths[key];
|
||||
if(path.render) svg += this.renderPath(path);
|
||||
}
|
||||
for (let key in part.snippets) {
|
||||
let snippet = part.snippets[key];
|
||||
svg += this.renderSnippet(snippet);
|
||||
}
|
||||
// includes
|
||||
// text on path
|
||||
// notes
|
||||
// dimensions
|
||||
// texts
|
||||
// snippets
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
@ -111,6 +128,19 @@ export class Svg {
|
|||
return `${this.nl()}<path ${path.attributes.render()} />`;
|
||||
}
|
||||
|
||||
/** Returns SVG code for a snippet */
|
||||
renderSnippet(snippet: Snippet): string {
|
||||
let svg = this.nl();
|
||||
svg += `<use x="${snippet.anchor.x}" y="${snippet.anchor.y}" `
|
||||
svg += `xlink:href="#${snippet.def}" ${snippet.attributes.render()}>`;
|
||||
if(snippet.description) {
|
||||
svg += `<title>${snippet.description}</title>`;
|
||||
}
|
||||
svg += '</use>';
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
||||
|
||||
/** Returns SVG code to open a group */
|
||||
openGroup(id: string, attributes?: Attributes): string {
|
||||
|
|
|
@ -2,10 +2,11 @@ import { Draft } from './themes/draft'
|
|||
import { Paperless } from './themes/paperless'
|
||||
import { Sample } from './themes/sample'
|
||||
import { Compare } from './themes/compare'
|
||||
import { Designer } from './themes/designer'
|
||||
|
||||
/** Standard themes that ship with freesewing */
|
||||
var themes = {
|
||||
draft: new Draft(),
|
||||
draft: new Designer(),
|
||||
paperless: new Paperless(),
|
||||
sample: new Sample(),
|
||||
compare: new Compare()
|
||||
|
|
149
lib/themes/designer.ts
Normal file
149
lib/themes/designer.ts
Normal file
|
@ -0,0 +1,149 @@
|
|||
import { Pattern } from '../pattern'
|
||||
import { Svg } from '../svg'
|
||||
import { Path } from '../path'
|
||||
import { Snippet } from '../snippet'
|
||||
import { Theme } from './theme';
|
||||
|
||||
export class Designer extends Theme {
|
||||
style: string = `
|
||||
path.curve-control{stroke:#f0ad4e;stroke-width: 0.2;}
|
||||
path.debug{stroke:#d9534f;stroke-opacity:0.4;stroke-width:2;}
|
||||
.point{fill:none;stroke-width:0.6;stroke:#f0ad4e;}
|
||||
text.tooltip{font-size:3px;}`;
|
||||
defs: string = `
|
||||
<g id="point">
|
||||
<circle cy="0" cx="0" r="2" class="stroke-hint stroke-sm" />
|
||||
<circle cy="0" cx="0" r="0.8" class="fill-hint" />
|
||||
</g>
|
||||
<g id="volatile-point">
|
||||
<circle cy="0" cx="0" r="1" class="stroke-canvas stroke-xs" />
|
||||
<path d="M -0.5,-0.5 L 0.5,0.5 M 0.5,-0.5 L -0.5,0.5" class="stroke-canvas stroke-sm" />
|
||||
</g>
|
||||
<g id="path-point">
|
||||
<circle cx="0" cy="0" r="2" class="stroke-note stroke-lg" />
|
||||
<circle cx="0" cy="0" r="0.8" class="fill-note" />
|
||||
</g>
|
||||
<g id="path-start-point">
|
||||
<circle cx="0" cy="0" r="2" class="stroke-canvas stroke-lg" />
|
||||
<circle cx="0" cy="0" r="0.8" class="fill-canvas" />
|
||||
</g>
|
||||
<g id="path-curvecontrol">
|
||||
<circle cy="0" cx="0" r="2" class="stroke-mark stroke-lg no-fill" />
|
||||
<circle cx="0" cy="0" r="0.8" class="fill-mark" />
|
||||
</g>
|
||||
<g id="focus-point">
|
||||
<circle cx="0" cy="0" r="2" class="stroke-mark stroke-lg" />
|
||||
<circle cx="0" cy="0" r="0.8" class="fill-fabric" />
|
||||
</g>
|
||||
<g id="marked-point">
|
||||
<circle cx="0" cy="0" r="3.6" class="stroke-hint stroke-sm" />
|
||||
<circle cx="0" cy="0" r="2.8" class="stroke-hint stroke-sm" />
|
||||
<circle cx="0" cy="0" r="2.0" class="stroke-hint stroke-sm" />
|
||||
<circle cx="0" cy="0" r="1.2" class="stroke-hint stroke-sm" />
|
||||
<circle cx="0" cy="0" r="0.8" class="stroke-hint stroke-sm" />
|
||||
<circle cx="0" cy="0" r="0.4" class="fill-hint" />
|
||||
</g>`;
|
||||
script:string = `
|
||||
function pointHover(evt) {
|
||||
var point = evt.target;
|
||||
var id = point.id;
|
||||
var cx = point.getAttribute('x');
|
||||
var cy = point.getAttribute('y');
|
||||
console.log('Point '+id+' ( '+cx+' , '+cy+' )');
|
||||
var scale = 2;
|
||||
cx = cx-scale*cx;
|
||||
cy = cy-scale*cy;
|
||||
point.setAttribute("transform", 'matrix('+scale+', 0, 0, '+scale+', '+cx+', '+cy+')');
|
||||
setTimeout(function(){
|
||||
var point = document.getElementById(evt.target.id);
|
||||
point.removeAttribute("transform", '');
|
||||
}, 1000);
|
||||
}`;
|
||||
|
||||
/** Pre-render method is called just prior to rendering */
|
||||
preRender(pattern: Pattern, svg: Svg): void {
|
||||
super.preRender(pattern, svg);
|
||||
svg.style += this.style;
|
||||
svg.defs += this.defs;
|
||||
svg.script += this.script;
|
||||
svg.attributes.add('freesewing:theme', 'designer');
|
||||
svg.attributes.add('viewBox', '-10 -10 300 500');
|
||||
//this.decoratePoints(pattern, svg);
|
||||
this.decoratePaths(pattern, svg);
|
||||
}
|
||||
|
||||
/** Decorares points with extra info */
|
||||
decoratePoints(pattern: Pattern, svg: Svg): void {
|
||||
for (let partId in pattern.parts) {
|
||||
let part = pattern.parts[partId];
|
||||
if (part.render) {
|
||||
for (let pointId in part.points) {
|
||||
this.decoratePoint(pointId, part, svg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Decorares a point with extra info */
|
||||
decoratePoint(pointId: string, part: Part, svg: Svg): void {
|
||||
let point = part.points[pointId];
|
||||
point.attributes.add('id', svg.getUid());
|
||||
point.attributes.add('data-point', id);
|
||||
}
|
||||
|
||||
/** Decorares paths with extra info */
|
||||
decoratePaths(pattern: Pattern, svg: Svg): void {
|
||||
for (let partId in pattern.parts) {
|
||||
let part = pattern.parts[partId];
|
||||
if (part.render) {
|
||||
for (let pathId in part.paths) {
|
||||
this.decoratePath(pathId, part, svg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Decorares a path with extra info */
|
||||
decoratePath(pathId: string, part: Part, svg: Svg): void {
|
||||
let path = part.paths[pathId];
|
||||
if (!path.render) return false;
|
||||
for (let op of path.ops) {
|
||||
switch(op.type) {
|
||||
case 'move':
|
||||
let id = svg.getUid();
|
||||
part.snippets[id] = new Snippet(op.to, 'path-start-point', `Startpoint of path ${pathId}`);
|
||||
part.snippets[id].attributes.add('onmouseover', 'pointHover(evt)');
|
||||
part.snippets[id].attributes.add('id', svg.getUid());
|
||||
break;
|
||||
case 'line':
|
||||
let id = svg.getUid();
|
||||
part.snippets[id] = new Snippet(op.to, 'path-point', `Line endpoint of path ${pathId}`);
|
||||
part.snippets[id].attributes.add('onmouseover', 'pointHover(evt)');
|
||||
part.snippets[id].attributes.add('id', svg.getUid());
|
||||
break;
|
||||
case 'curve':
|
||||
let id = svg.getUid();
|
||||
part.snippets[id] = new Snippet(op.to, 'path-point', `Curve endpoint of path ${pathId}`);
|
||||
part.snippets[id].attributes.add('onmouseover', 'pointHover(evt)');
|
||||
part.snippets[id].attributes.add('id', svg.getUid());
|
||||
id = svg.getUid();
|
||||
part.snippets[id] = new Snippet(op.cp1, 'path-curvecontrol', `Curve cp1 of path ${pathId}`);
|
||||
part.snippets[id].attributes.add('onmouseover', 'pointHover(evt)');
|
||||
part.snippets[id].attributes.add('id', svg.getUid());
|
||||
id = svg.getUid();
|
||||
part.snippets[id] = new Snippet(op.cp2, 'path-curvecontrol', `Curve cp2 of path ${pathId}`);
|
||||
part.snippets[id].attributes.add('onmouseover', 'pointHover(evt)');
|
||||
let cp1 = new Path().move(current).line(op.cp1);
|
||||
let cp2 = new Path().move(op.to).line(op.cp2);
|
||||
cp1.attributes.add('class', 'curve-control');
|
||||
cp1.attributes.add('id', svg.getUid());
|
||||
cp2.attributes.add('class', 'curve-control');
|
||||
cp2.attributes.add('id', svg.getUid());
|
||||
part.paths[svg.getUid()] = cp1;
|
||||
part.paths[svg.getUid()] = cp2;
|
||||
break;
|
||||
}
|
||||
let current = op.to;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,11 @@
|
|||
import { Pattern } from '../pattern'
|
||||
import { Svg } from '../svg'
|
||||
import { Theme } from './theme';
|
||||
|
||||
export class Draft extends Theme {}
|
||||
export class Draft extends Theme {
|
||||
/** Pre-render method is called just prior to rendering */
|
||||
preRender(pattern: Pattern, svg: Svg): void {
|
||||
super.preRender(pattern, svg);
|
||||
svg.attributes.add('freesewing:theme', 'draft');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export abstract class Theme {
|
|||
svg.header += this.loadHeader(pattern);
|
||||
svg.footer += this.loadFooter(pattern);
|
||||
svg.style += this.loadStyle(pattern);
|
||||
svg.script += this.loadScript(pattern);
|
||||
svg.defs += this.loadDefs(pattern);
|
||||
}
|
||||
|
||||
|
@ -116,6 +117,11 @@ export abstract class Theme {
|
|||
.fill-gray{fill:#999}`;
|
||||
}
|
||||
|
||||
/** Returns a string containing the SVG ECMA script */
|
||||
loadScript(pattern: Pattern) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/** Returns a string containing the SVG defs */
|
||||
loadDefs(pattern: Pattern) {
|
||||
return `
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue