1
0
Fork 0

:wip: Working on design theme

This needs to be taken out of this repo later
This commit is contained in:
joostdecock 2018-07-16 13:42:26 +00:00
parent 659e57916c
commit 2160980ed4
9 changed files with 222 additions and 7 deletions

View file

@ -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
}

View file

@ -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 {}

View file

@ -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
View 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;
}
}

View file

@ -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 {

View file

@ -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
View 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;
}
}
}

View file

@ -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');
}
}

View file

@ -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 `