🚧 Progress on workbench
This commit is contained in:
parent
158c19ae1d
commit
a888922968
31 changed files with 716 additions and 153 deletions
|
@ -38,6 +38,7 @@ plugin-svgattr: "A FreeSewing plugin to set SVG attributes"
|
|||
plugin-theme: "A FreeSewing plugin that provides a default theme"
|
||||
plugin-title: "A FreeSewing plugin to add a title to your pattern parts"
|
||||
plugin-validate: "A FreeSewing plugin that validates aspects of your code"
|
||||
rendertest: "A freesewing pattern to test (y)our render engine our CSS"
|
||||
shin: "A FreeSewing pattern for swim trunks"
|
||||
simon: "A FreeSewing pattern for a button down shirt"
|
||||
sven: "A FreeSewing pattern for a straightforward sweater"
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Circle = props => {
|
||||
return null;
|
||||
let foo = (
|
||||
const Circle = props => (
|
||||
<circle
|
||||
cx={props.point.x}
|
||||
cy={props.point.y}
|
||||
r={props.point.attributes.get("data-circle")}
|
||||
{...props.point.attributes.asPropsIfPrefixIs("data-circle-")}
|
||||
/>
|
||||
);
|
||||
};
|
||||
);
|
||||
|
||||
Circle.propTypes = {
|
||||
point: PropTypes.object.isRequired
|
||||
|
|
84
packages/components/src/Draft/Defs/Grid/index.js
Normal file
84
packages/components/src/Draft/Defs/Grid/index.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
import React from "react";
|
||||
|
||||
const Grid = props => {
|
||||
let style = {
|
||||
style: {
|
||||
fill: "none",
|
||||
stroke: "currentColor"
|
||||
}
|
||||
};
|
||||
if (props.units === "imperial")
|
||||
return (
|
||||
<pattern
|
||||
id="grid"
|
||||
height="25.4"
|
||||
width="25.4"
|
||||
patternUnits="userSpaceOnUse"
|
||||
key="grid"
|
||||
>
|
||||
<path
|
||||
className="gridline lg imperial"
|
||||
d="M 0 0 L 0 25.4 L 25.4 25.4"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline lg imperial"
|
||||
d="M 12.7 0 L 12.7 25.4 M 0 12.7 L 25.4 12.7"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline sm imperial"
|
||||
d="M 3.175 0 L 3.175 25.4 M 6.32 0 L 6.35 25.4 M 9.525 0 L 9.525 25.4 M 15.875 0 L 15.875 25.4 M 19.05 0 L 19.05 25.4 M 22.225 0 L 22.225 25.4"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline sm imperial"
|
||||
d="M 0 3.175 L 25.4 3.175 M 0 6.32 L 25.4 6.35 M 0 9.525 L 25.4 9.525 M 0 15.875 L 25.4 15.875 M 0 19.05 L 25.4 19.05 M 0 22.225 L 25.4 22.225"
|
||||
{...style}
|
||||
/>
|
||||
</pattern>
|
||||
);
|
||||
else
|
||||
return (
|
||||
<pattern
|
||||
id="grid"
|
||||
height="100"
|
||||
width="100"
|
||||
patternUnits="userSpaceOnUse"
|
||||
key="grid"
|
||||
>
|
||||
<path
|
||||
className="gridline lg metric"
|
||||
d="M 0 0 L 0 100 L 100 100"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline metric"
|
||||
d="M 50 0 L 50 100 M 0 50 L 100 50"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline sm metric"
|
||||
d="M 10 0 L 10 100 M 20 0 L 20 100 M 30 0 L 30 100 M 40 0 L 40 100 M 60 0 L 60 100 M 70 0 L 70 100 M 80 0 L 80 100 M 90 0 L 90 100"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline sm metric"
|
||||
d="M 0 10 L 100 10 M 0 20 L 100 20 M 0 30 L 100 30 M 0 40 L 100 40 M 0 60 L 100 60 M 0 70 L 100 70 M 0 80 L 100 80 M 0 90 L 100 90"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline xs metric"
|
||||
d="M 5 0 L 5 100 M 15 0 L 15 100 M 25 0 L 25 100 M 35 0 L 35 100 M 45 0 L 45 100 M 55 0 L 55 100 M 65 0 L 65 100 M 75 0 L 75 100 M 85 0 L 85 100 M 95 0 L 95 100"
|
||||
{...style}
|
||||
/>
|
||||
<path
|
||||
className="gridline xs metric"
|
||||
d="M 0 5 L 100 5 M 0 15 L 100 15 M 0 25 L 100 25 M 0 35 L 100 35 M 0 45 L 100 45 M 0 55 L 100 55 M 0 65 L 100 65 M 0 75 L 100 75 M 0 85 L 100 85 M 0 95 L 100 95"
|
||||
{...style}
|
||||
/>
|
||||
</pattern>
|
||||
);
|
||||
};
|
||||
|
||||
export default Grid;
|
1
packages/components/src/Draft/Defs/Grid/logo-path.js
Normal file
1
packages/components/src/Draft/Defs/Grid/logo-path.js
Normal file
File diff suppressed because one or more lines are too long
34
packages/components/src/Draft/Defs/Markers/index.js
Normal file
34
packages/components/src/Draft/Defs/Markers/index.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import React from "react";
|
||||
|
||||
const Markers = props => {
|
||||
const markerProps = {
|
||||
orient: "auto",
|
||||
refX: "0.0",
|
||||
refY: "0.0",
|
||||
style: { overflow: "visible" }
|
||||
};
|
||||
const from = { d: "M 0,0 L 12,-4 C 10,-2 10,2 12, 4 z" };
|
||||
const to = { d: "M 0,0 L -12,-4 C -10,-2 -10,2 -12, 4 z" };
|
||||
const types = {
|
||||
grainline: "note",
|
||||
cutonfold: "note",
|
||||
dimension: "mark"
|
||||
};
|
||||
let output = [];
|
||||
for (let type in types) {
|
||||
output.push(
|
||||
<marker id={type + "From"} key={type + "-from"} {...markerProps}>
|
||||
<path className={types[type] + " fill-" + types[type]} {...from} />
|
||||
</marker>
|
||||
);
|
||||
output.push(
|
||||
<marker id={type + "To"} key={type + "-to"} {...markerProps}>
|
||||
<path className={types[type] + " fill-" + types[type]} {...to} />
|
||||
</marker>
|
||||
);
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
export default Markers;
|
41
packages/components/src/Draft/Defs/Snippets/index.js
Normal file
41
packages/components/src/Draft/Defs/Snippets/index.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import React from "react";
|
||||
import logoPathString from "./logo-path";
|
||||
|
||||
const Snippets = props => {
|
||||
const fill = { fill: "currentColor", stroke: "none" };
|
||||
const stroke = { fill: "none", stroke: "currentColor" };
|
||||
return [
|
||||
<g id="notch" className="snippet notch" key="notch">
|
||||
<circle cy="0" cx="0" r="1.4" {...fill} />
|
||||
<circle cy="0" cx="0" r="2.8" {...stroke} />
|
||||
</g>,
|
||||
<g id="bnotch" className="snippet bnotch" key="bnotch">
|
||||
<path d="M -1.1 -1.1 L 1.1 1.1 M 1.1 -1.1 L -1.1 1.1" {...stroke} />
|
||||
<circle cy="0" cx="0" r="2.8" {...stroke} />
|
||||
</g>,
|
||||
<g id="button" className="snippet button" key="button">
|
||||
<circle cx="0" cy="0" r="3.4" {...stroke} /> />
|
||||
<circle cx="-1" cy="-1" r="0.5" {...fill} />
|
||||
<circle cx="1" cy="-1" r="0.5" {...fill} />
|
||||
<circle cx="1" cy="1" r="0.5" {...fill} />
|
||||
<circle cx="-1" cy="1" r="0.5" {...fill} />
|
||||
</g>,
|
||||
<g id="buttonhole" className="snippet buttonhole" key="buttonhole">
|
||||
<path d="M -1,-5 L 1,-5 L 1,5 L -1,5 z" {...stroke} />
|
||||
<path
|
||||
d="M -1,-5 L 1,-5 L 1,-4 L -1,-4 z M -1,5 L 1,5 L 1,4 L -1,4 z"
|
||||
{...fill}
|
||||
/>
|
||||
</g>,
|
||||
<g
|
||||
id="logo"
|
||||
className="snippet logo"
|
||||
transform="translate(-23 -36)"
|
||||
key="logo"
|
||||
>
|
||||
<path d={logoPathString} {...fill} />
|
||||
</g>
|
||||
];
|
||||
};
|
||||
|
||||
export default Snippets;
|
1
packages/components/src/Draft/Defs/Snippets/logo-path.js
Normal file
1
packages/components/src/Draft/Defs/Snippets/logo-path.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,9 +1,37 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import React from "react";
|
||||
import Markers from "./Markers";
|
||||
import Snippets from "./Snippets";
|
||||
import Grid from "./Grid";
|
||||
|
||||
const Defs = props => <defs>{props.defs}</defs>;
|
||||
|
||||
Defs.propTypes = { defs: PropTypes.string };
|
||||
Defs.defaultProps = { defs: "" };
|
||||
const Defs = props => {
|
||||
let paperlessGrids = null;
|
||||
if (props.paperless) {
|
||||
paperlessGrids = [];
|
||||
for (let p in props.parts) {
|
||||
let anchor = { x: 0, y: 0 };
|
||||
if (typeof props.parts[p].points.gridAnchor !== "undefined")
|
||||
anchor = props.parts[p].points.gridAnchor;
|
||||
else if (typeof props.parts[p].points.anchor !== "undefined")
|
||||
anchor = props.parts[p].points.anchor;
|
||||
paperlessGrids.push(
|
||||
<pattern
|
||||
id={"grid-" + p}
|
||||
key={"grid-" + p}
|
||||
xlinkHref="#grid"
|
||||
x={anchor.x}
|
||||
y={anchor.y}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<defs>
|
||||
<Markers />
|
||||
<Snippets />
|
||||
<Grid units={props.units} />
|
||||
{paperlessGrids}
|
||||
</defs>
|
||||
);
|
||||
};
|
||||
|
||||
export default Defs;
|
||||
|
|
|
@ -2,21 +2,45 @@ import React, { useState } from "react";
|
|||
import PropTypes from "prop-types";
|
||||
import Path from "../Path";
|
||||
import Point from "../Point";
|
||||
import Snippet from "../Snippet";
|
||||
import { getProps } from "../utils";
|
||||
|
||||
const Part = props => {
|
||||
console.log(props.part);
|
||||
let grid = props.paperless ? (
|
||||
<rect
|
||||
x={props.part.topLeft.x}
|
||||
y={props.part.topLeft.y}
|
||||
width={props.part.width}
|
||||
height={props.part.height}
|
||||
className="grid"
|
||||
fill={"url(#grid-" + props.name + ")"}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<g {...getProps(props.part)}>
|
||||
{grid}
|
||||
{Object.keys(props.part.points).map(name => (
|
||||
<Point
|
||||
key={name}
|
||||
name={name}
|
||||
part={props.name}
|
||||
language={props.language}
|
||||
point={props.part.points[name]}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.paths).map(name => (
|
||||
<Path key={name} name={name} path={props.part.paths[name]} />
|
||||
<Path
|
||||
key={name}
|
||||
name={name}
|
||||
part={props.name}
|
||||
language={props.language}
|
||||
path={props.part.paths[name]}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.snippets).map(name => (
|
||||
<Snippet key={name} name={name} snippet={props.part.snippets[name]} />
|
||||
))}
|
||||
</g>
|
||||
);
|
||||
|
@ -25,7 +49,9 @@ const Part = props => {
|
|||
Part.propTypes = {
|
||||
part: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired
|
||||
language: PropTypes.string.isRequired,
|
||||
paperless: PropTypes.bool.isRequired,
|
||||
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
||||
};
|
||||
|
||||
export default Part;
|
||||
|
|
|
@ -1,14 +1,36 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import TextOnPath from "../TextOnPath";
|
||||
import { getProps } from "../utils";
|
||||
|
||||
const Path = props => {
|
||||
if (!props.path.render) return null;
|
||||
return <path d={props.path.asPathstring()} {...getProps(props.path)} />;
|
||||
const output = [];
|
||||
const pathId = "path-" + props.part + "-" + props.name;
|
||||
output.push(
|
||||
<path
|
||||
id={pathId}
|
||||
key={"path-" + props.name}
|
||||
d={props.path.asPathstring()}
|
||||
{...getProps(props.path)}
|
||||
/>
|
||||
);
|
||||
if (props.path.attributes.get("data-text"))
|
||||
output.push(
|
||||
<TextOnPath
|
||||
key={"text-on-path-" + props.name}
|
||||
pathId={pathId}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
Path.propTypes = {
|
||||
path: PropTypes.object.isRequired
|
||||
path: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default Path;
|
||||
|
|
39
packages/components/src/Draft/Snippet/index.js
Normal file
39
packages/components/src/Draft/Snippet/index.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Text from "../Text";
|
||||
import Circle from "../Circle";
|
||||
|
||||
const Snippet = props => {
|
||||
const snippetProps = {
|
||||
xlinkHref: "#" + props.snippet.def,
|
||||
x: props.snippet.anchor.x,
|
||||
y: props.snippet.anchor.y
|
||||
};
|
||||
let scale = props.snippet.attributes.get("data-scale");
|
||||
let rotate = props.snippet.attributes.get("data-rotate");
|
||||
if (scale || rotate) {
|
||||
snippetProps.transform = "";
|
||||
if (scale) {
|
||||
snippetProps.transform += `translate(${snippetProps.x}, ${
|
||||
snippetProps.y
|
||||
}) `;
|
||||
snippetProps.transform += `scale(${scale}) `;
|
||||
snippetProps.transform += `translate(${snippetProps.x *
|
||||
-1}, ${snippetProps.y * -1}) `;
|
||||
}
|
||||
if (rotate) {
|
||||
snippetProps.transform += `rotate(${rotate}, ${snippetProps.x}, ${
|
||||
snippetProps.y
|
||||
}) `;
|
||||
}
|
||||
}
|
||||
|
||||
return <use {...snippetProps} />;
|
||||
};
|
||||
|
||||
Snippet.propTypes = {
|
||||
snippet: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default Snippet;
|
|
@ -30,7 +30,6 @@ const Text = props => {
|
|||
);
|
||||
}
|
||||
} else text.push(<tspan key="tspan-1">{translated}</tspan>);
|
||||
return null;
|
||||
return (
|
||||
<text
|
||||
x={props.point.x}
|
||||
|
@ -43,7 +42,8 @@ const Text = props => {
|
|||
};
|
||||
|
||||
Text.propTypes = {
|
||||
point: PropTypes.object.isRequired
|
||||
point: PropTypes.object.isRequired,
|
||||
language: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default Text;
|
||||
|
|
40
packages/components/src/Draft/TextOnPath/index.js
Normal file
40
packages/components/src/Draft/TextOnPath/index.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { strings } from "@freesewing/i18n";
|
||||
|
||||
const TextOnPath = props => {
|
||||
let text = [];
|
||||
// Handle translation
|
||||
let translated = "";
|
||||
for (let string of props.path.attributes.getAsArray("data-text")) {
|
||||
if (strings[props.language]["plugin." + string])
|
||||
translated += strings[props.language]["plugin." + string];
|
||||
else translated += string;
|
||||
translated += " ";
|
||||
}
|
||||
let textPathProps = {
|
||||
xlinkHref: "#" + props.pathId,
|
||||
startOffset: "0%"
|
||||
};
|
||||
let align = props.path.attributes.get("data-text-class");
|
||||
if (align && align.indexOf("center") > -1) textPathProps.startOffset = "50%";
|
||||
else if (align && align.indexOf("right") > -1)
|
||||
textPathProps.startOffset = "100%";
|
||||
|
||||
return (
|
||||
<text>
|
||||
<textPath {...textPathProps}>
|
||||
<tspan {...props.path.attributes.asPropsIfPrefixIs("data-text-")}>
|
||||
{translated}
|
||||
</tspan>
|
||||
</textPath>
|
||||
</text>
|
||||
);
|
||||
};
|
||||
|
||||
TextOnPath.propTypes = {
|
||||
path: PropTypes.object.isRequired,
|
||||
language: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default TextOnPath;
|
|
@ -1,93 +0,0 @@
|
|||
svg.freesewing {
|
||||
/* Reset */
|
||||
path,circle,rect{fill:none;stroke:none}
|
||||
|
||||
/* Defaults */
|
||||
path,circle{
|
||||
stroke:#000;
|
||||
stroke-opacity:1;
|
||||
stroke-width:.3;
|
||||
stroke-linecap:round;
|
||||
stroke-linejoin:round;
|
||||
}
|
||||
|
||||
/* Stroke classes */
|
||||
.fabric{
|
||||
stroke-width:.6;
|
||||
stroke:#212121
|
||||
}
|
||||
.lining{
|
||||
stroke-width:.6;
|
||||
stroke:#ff5b77;
|
||||
}
|
||||
.interfacing{
|
||||
stroke-width:.6;
|
||||
stroke:#64b5f6;
|
||||
}
|
||||
.canvas{
|
||||
stroke-width:.6;
|
||||
stroke:#ff9000;
|
||||
}
|
||||
.various{
|
||||
stroke-width:.6;
|
||||
stroke:#4caf50;
|
||||
}
|
||||
.note{
|
||||
stroke-width:.4;
|
||||
stroke:#dd60dd;
|
||||
}
|
||||
.mark{
|
||||
stroke-width:.4;
|
||||
stroke:blue;
|
||||
}
|
||||
.contrast{
|
||||
stroke-width:.8;
|
||||
stroke:red;
|
||||
}
|
||||
.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; }
|
||||
|
||||
.sa { stroke-dasharray:0.4,0.8; }
|
||||
.help {
|
||||
stroke-width:.2;
|
||||
stroke-dasharray:15,1.5,1,1.5;
|
||||
}
|
||||
.dotted { stroke-dasharray:0.4,0.8; }
|
||||
.dashed { stroke-dasharray:1,1.5; }
|
||||
.lashed { stroke-dasharray:6,6; }
|
||||
.hidden {
|
||||
stroke:none;
|
||||
fill:none;
|
||||
}
|
||||
|
||||
/* Fill classes */
|
||||
.fill-fabric{ fill:#212121; }
|
||||
.fill-lining{ fill:#ff5b77; }
|
||||
.fill-interfacing{ fill:#64b5f6; }
|
||||
.fill-canvas{ fill:#ff9000; }
|
||||
.fill-various{ fill:#4caf50; }
|
||||
.fill-note{ fill:#dd69dd; }
|
||||
.fill-mark{ fill:blue; }
|
||||
.fill-contrast{ fill:red; }
|
||||
|
||||
/* Text */
|
||||
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;
|
||||
dominant-baseline:ideographic;
|
||||
}
|
||||
.text-xs { font-size:3px; }
|
||||
.text-sm { font-size:4px; }
|
||||
.text-lg { font-size:7px; }
|
||||
.text-xl { font-size:9px; }
|
||||
.text-xxl{ font-size:12px; }
|
||||
|
||||
.center{ text-anchor:middle; }
|
||||
.right{ text-anchor:end; }
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Svg from "./Svg";
|
||||
//import Style from "./Style";
|
||||
//import Defs from "./Defs";
|
||||
import Defs from "./Defs";
|
||||
import Part from "./Part";
|
||||
|
||||
const Draft = props => {
|
||||
|
@ -14,11 +13,18 @@ const Draft = props => {
|
|||
language={props.settings.locale}
|
||||
id={props.settings.idPrefix + "svg"}
|
||||
>
|
||||
<Defs
|
||||
units={props.settings.units}
|
||||
parts={props.parts}
|
||||
paperless={props.settings.paperless}
|
||||
/>
|
||||
<g>
|
||||
{Object.keys(props.parts).map(name => (
|
||||
<Part
|
||||
part={props.parts[name]}
|
||||
language={props.settings.locale}
|
||||
paperless={props.settings.paperless}
|
||||
units={props.settings.units}
|
||||
key={name}
|
||||
name={name}
|
||||
/>
|
||||
|
|
|
@ -51,7 +51,7 @@ const OptionGroup = props => {
|
|||
return <Count {...option} {...extraProps} />;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupport option type: " + type);
|
||||
throw new Error("Unsupported option type: " + type);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ const Footer = props => {
|
|||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div key={l}>
|
||||
<h4>
|
||||
<FormattedMessage id={"app." + l} />
|
||||
</h4>
|
||||
|
|
|
@ -58,6 +58,7 @@ const Workbench = props => {
|
|||
};
|
||||
const measurementsMissing = () => {
|
||||
let required = props.config.measurements;
|
||||
if (required.length < 1) return false;
|
||||
if (measurements === null) return true;
|
||||
for (let m of required) {
|
||||
if (typeof measurements[m] === "undefined") return true;
|
||||
|
|
|
@ -595,7 +595,7 @@ Pattern.prototype.getRenderProps = function() {
|
|||
props.parts[p] = {
|
||||
paths: this.parts[p].paths,
|
||||
points: this.parts[p].points,
|
||||
snippets: this.parts[p].points,
|
||||
snippets: this.parts[p].snippets,
|
||||
attributes: this.parts[p].attributes,
|
||||
height: this.parts[p].height,
|
||||
width: this.parts[p].width,
|
||||
|
|
|
@ -11,14 +11,14 @@ $fc-accentbg-dark: $oc-teal-8;
|
|||
$fc-link-light: $oc-blue-6;
|
||||
$fc-link-dark: $oc-blue-3;
|
||||
|
||||
$fc-draft-lining-light: $oc-teal-6;
|
||||
$fc-draft-fabric-light: $oc-gray-9;
|
||||
$fc-draft-lining-light: $oc-lime-7;
|
||||
$fc-draft-interfacing-light: $oc-red-7;
|
||||
$fc-draft-canvas-light: $oc-yellow-7;
|
||||
$fc-draft-interfacing-light: $oc-gray-6;
|
||||
$fc-draft-various-light: $oc-pink-5;
|
||||
$fc-draft-mark-light: $oc-indigo-6;
|
||||
$fc-draft-various-light: $oc-grape-7;
|
||||
$fc-draft-mark-light: $oc-blue-4;
|
||||
$fc-draft-contrast-light: $oc-orange-7;
|
||||
$fc-draft-note-light: $oc-blue-7;
|
||||
$fc-draft-note-light: $oc-pink-7;
|
||||
|
||||
$fc-draft-lining-dark: $oc-teal-6;
|
||||
$fc-draft-fabric-dark: $oc-gray-9;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
svg.freesewing.draft {
|
||||
max-width: 100%;
|
||||
max-height: 90vh;
|
||||
/* Reset */
|
||||
path,circle,rect{fill:none;stroke:none}
|
||||
path,circle{fill:none;stroke:none}
|
||||
|
||||
/* Defaults */
|
||||
path,circle{
|
||||
|
@ -13,25 +12,22 @@ svg.freesewing.draft {
|
|||
}
|
||||
|
||||
/* Stroke classes */
|
||||
.note{ stroke-width:.8; }
|
||||
.mark{ stroke-width:.8; }
|
||||
.contrast{ stroke-width:1.2; }
|
||||
.stroke-xs{ stroke-width:.5; }
|
||||
.stroke-sm{ stroke-width:.5; }
|
||||
.stroke-xl{ stroke-width:1.4; }
|
||||
.stroke-xxl{ stroke-width:2.4; }
|
||||
.stroke-xs{ stroke-width:.1; }
|
||||
.stroke-sm{ stroke-width:.4; }
|
||||
.stroke-l{ stroke-width:1.3; }
|
||||
.stroke-xl{ stroke-width:2; }
|
||||
|
||||
.sa { stroke-dasharray:1,3; }
|
||||
.help {
|
||||
stroke-width:.6;
|
||||
stroke-dasharray:15,5,2,5;
|
||||
}
|
||||
.dotted { stroke-dasharray:2,3; }
|
||||
.dashed { stroke-dasharray:2,5; }
|
||||
.lashed { stroke-dasharray:8,8; }
|
||||
.dotted { stroke-dasharray:0.5,1; }
|
||||
.dashed { stroke-dasharray:2,2; }
|
||||
.lashed { stroke-dasharray:8,3; }
|
||||
.hidden {
|
||||
stroke:none;
|
||||
fill:none;
|
||||
stroke:none!important;
|
||||
fill:none!important;
|
||||
}
|
||||
|
||||
/* Sampling */
|
||||
|
@ -47,7 +43,7 @@ svg.freesewing.draft {
|
|||
}
|
||||
.text-xs { font-size:4px; }
|
||||
.text-sm { font-size:5px; }
|
||||
.text-lg { font-size:8px; }
|
||||
.text-l { font-size:8px; }
|
||||
.text-xl { font-size:10px; }
|
||||
.text-xxl{ font-size:13px; }
|
||||
|
||||
|
@ -106,3 +102,52 @@ svg.freesewing.draft {
|
|||
.fill-note{ fill: $fc-draft-note-dark; }
|
||||
}
|
||||
|
||||
/* SVG defs (snippets) are in the shadow DOM */
|
||||
g.snippet.notch > circle,
|
||||
g.snippet.bnotch > circle,
|
||||
g.snippet.bnotch > path,
|
||||
g.snippet.utton > circle,
|
||||
g.snippet.uttonhole > path {
|
||||
color: $fc-draft-mark-light;
|
||||
}
|
||||
/* Same for paperless grid, also in shadow DOM */
|
||||
rect.grid {
|
||||
stroke-width: 1;
|
||||
stroke: currentColor;
|
||||
}
|
||||
path.gridline {
|
||||
stroke-linecap: butt;
|
||||
stroke-width: 0.3!important;
|
||||
stroke-dasharray: none;
|
||||
}
|
||||
path.gridline.sm {
|
||||
stroke-width: 0.15!important;
|
||||
}
|
||||
path.gridline.xs {
|
||||
stroke-width: 0.1!important;
|
||||
}
|
||||
path.gridline.metric.sm {
|
||||
stroke-dasharray: 3 1;
|
||||
}
|
||||
path.gridline.metric.xs {
|
||||
stroke-dasharray: 1 1;
|
||||
}
|
||||
path.gridline.imperial {
|
||||
stroke-dasharray: 5 5;
|
||||
}
|
||||
path.gridline.imperial.sm {
|
||||
stroke-dasharray: 2 2;
|
||||
}
|
||||
.light {
|
||||
rect.grid,
|
||||
path.gridline {
|
||||
color: $oc-gray-5!important;
|
||||
}
|
||||
}
|
||||
.dark {
|
||||
rect.grid,
|
||||
path.gridline {
|
||||
color: $oc-gray-6!important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
freesewingIsMadeByJoostDeCockAndContributors: Freesewing wurde von Joost De Cock und den Mitwirkenden kreiert
|
||||
theBlackOutsideOfThisBoxShouldMeasure: Die (schwarze) Außenseite dieses Rechtecks sollte messen
|
||||
theWhiteInsideOfThisBoxShouldMeasure: Die (weiße) Innenseite dieses Rechtecks sollte messen
|
||||
theBlackOutsideOfThisBoxShouldMeasure: Die Außenseite dieses Rechtecks sollte messen
|
||||
theWhiteInsideOfThisBoxShouldMeasure: Die Innenseite dieses Rechtecks sollte messen
|
||||
withTheFinancialSupportOfOurPatrons: mit der finanziellen Unterstützung unserer Gönner
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
freesewingIsMadeByJoostDeCockAndContributors: Freesewing is made by Joost De Cock and contributors
|
||||
theBlackOutsideOfThisBoxShouldMeasure: The (black) outside of this box should measure
|
||||
theWhiteInsideOfThisBoxShouldMeasure: The (white) inside of this box should measure
|
||||
theBlackOutsideOfThisBoxShouldMeasure: The outside of this box should measure
|
||||
theWhiteInsideOfThisBoxShouldMeasure: The inside of this box should measure
|
||||
withTheFinancialSupportOfOurPatrons: with the financial support of our patrons
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
freesewingIsMadeByJoostDeCockAndContributors: Freesewing está hecho por Joost De Cock y colaboradores
|
||||
theBlackOutsideOfThisBoxShouldMeasure: El (negro) fuera de este cuadro debe medir
|
||||
theWhiteInsideOfThisBoxShouldMeasure: El (blanco) dentro de este cuadro debe medir
|
||||
theBlackOutsideOfThisBoxShouldMeasure: El fuera de este cuadro debe medir
|
||||
theWhiteInsideOfThisBoxShouldMeasure: El dentro de este cuadro debe medir
|
||||
withTheFinancialSupportOfOurPatrons: con el apoyo económico de nuestros patrocinadores
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
freesewingIsMadeByJoostDeCockAndContributors: Freesewing est la création de Joost De Cock et ses contributeurs
|
||||
theBlackOutsideOfThisBoxShouldMeasure: Le (noir) en dehors de cette case doit mesurer
|
||||
theWhiteInsideOfThisBoxShouldMeasure: L'intérieur (blanc) de cette case doit mesurer
|
||||
theBlackOutsideOfThisBoxShouldMeasure: L'extérieur de cette case doit mesurer
|
||||
theWhiteInsideOfThisBoxShouldMeasure: L'intérieur de cette case doit mesurer
|
||||
withTheFinancialSupportOfOurPatrons: avec le soutien financier de nos mécènes
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
freesewingIsMadeByJoostDeCockAndContributors: FreeSewing is een project van Joost De Cock en vrijwillige medewerkers
|
||||
theBlackOutsideOfThisBoxShouldMeasure: De (zwarte) buitenkant van dit kader meet
|
||||
theWhiteInsideOfThisBoxShouldMeasure: De (witte) binnenkant van dit kader meet
|
||||
theBlackOutsideOfThisBoxShouldMeasure: De buitenkant van dit kader meet
|
||||
theWhiteInsideOfThisBoxShouldMeasure: De binnenkant van dit kader meet
|
||||
withTheFinancialSupportOfOurPatrons: met de financiële steun van onze mecenassen
|
||||
|
|
|
@ -86,14 +86,14 @@ export default {
|
|||
.line(this.points.__scaleboxImperialBottomRight)
|
||||
.line(this.points.__scaleboxImperialTopRight)
|
||||
.close()
|
||||
.attr("style", "fill: #000; stroke: none;");
|
||||
.attr("class", "scalebox imperial");
|
||||
this.paths.__scaleboxMetric = new this.Path()
|
||||
.move(this.points.__scaleboxMetricTopLeft)
|
||||
.line(this.points.__scaleboxMetricBottomLeft)
|
||||
.line(this.points.__scaleboxMetricBottomRight)
|
||||
.line(this.points.__scaleboxMetricTopRight)
|
||||
.close()
|
||||
.attr("style", "fill: #FFF; stroke: none;");
|
||||
.attr("class", "scalebox metric");
|
||||
// Lead
|
||||
this.points.__scaleboxLead = this.points.__scaleboxLead
|
||||
.attr("data-text", so.lead || "freesewing")
|
||||
|
|
23
packages/rendertest/config/index.js
Normal file
23
packages/rendertest/config/index.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { version } from "../package.json";
|
||||
|
||||
export default {
|
||||
name: "rendertest",
|
||||
version,
|
||||
design: "Joost De Cock",
|
||||
code: "Joost De Cock",
|
||||
department: "menswear",
|
||||
type: "pattern",
|
||||
difficulty: 1,
|
||||
tags: ["test"],
|
||||
optionGroups: {
|
||||
fit: ["width"]
|
||||
},
|
||||
measurements: [],
|
||||
dependencies: {},
|
||||
parts: ["colors"],
|
||||
inject: {},
|
||||
hide: [],
|
||||
options: {
|
||||
width: { mm: 200, min: 50, max: 500 }
|
||||
}
|
||||
};
|
5
packages/rendertest/src/.eslintrc
Normal file
5
packages/rendertest/src/.eslintrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
249
packages/rendertest/src/colors.js
Normal file
249
packages/rendertest/src/colors.js
Normal file
|
@ -0,0 +1,249 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
options,
|
||||
Point,
|
||||
Path,
|
||||
points,
|
||||
paths,
|
||||
snippets,
|
||||
Snippet,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
|
||||
let colors = [
|
||||
"fabric",
|
||||
"lining",
|
||||
"interfacing",
|
||||
"canvas",
|
||||
"various",
|
||||
"mark",
|
||||
"contrast",
|
||||
"note"
|
||||
];
|
||||
let sizes = ["xs", "sm", "", "l", "xl"];
|
||||
let utility = ["dotted", "dashed", "lashed", "sa", "help", "hidden"];
|
||||
|
||||
let y = 0;
|
||||
let w = options.width;
|
||||
macro("hd", {
|
||||
from: new Point(0, y),
|
||||
to: new Point(w, y)
|
||||
});
|
||||
for (let i in colors) {
|
||||
y += 15;
|
||||
points["l" + i] = new Point(0, y);
|
||||
points["r" + i] = new Point(w, y);
|
||||
paths["heading" + i] = new Path()
|
||||
.move(points["l" + i])
|
||||
.line(points["r" + i])
|
||||
.attr("class", colors[i])
|
||||
.attr("data-text", colors[i]);
|
||||
for (let j in sizes) {
|
||||
y += 10;
|
||||
points["sl" + i + j] = new Point(0, y);
|
||||
points["sr" + i + j] = new Point(w, y);
|
||||
paths["size" + i + j] = new Path()
|
||||
.move(points["sl" + i + j])
|
||||
.line(points["sr" + i + j])
|
||||
.attr("class", colors[i])
|
||||
.attr("class", "stroke-" + sizes[j])
|
||||
.attr(
|
||||
"data-text",
|
||||
"path." + colors[i] + (sizes[j] === "" ? "" : ".stroke-" + sizes[j])
|
||||
)
|
||||
.attr("data-text-class", "center");
|
||||
}
|
||||
for (let j in utility) {
|
||||
y += 10;
|
||||
points["ul" + i + j] = new Point(0, y);
|
||||
points["ur" + i + j] = new Point(w, y);
|
||||
paths["util" + i + j] = new Path()
|
||||
.move(points["ul" + i + j])
|
||||
.line(points["ur" + i + j])
|
||||
.attr("class", colors[i])
|
||||
.attr("class", utility[j])
|
||||
.attr("data-text", "path." + colors[i] + "." + utility[j])
|
||||
.attr("data-text-class", "center");
|
||||
}
|
||||
}
|
||||
|
||||
y += 10;
|
||||
points.ftl = new Point(0, y);
|
||||
points.ftr = new Point(w, y);
|
||||
paths.snip = new Path()
|
||||
.move(points.ftl)
|
||||
.line(points.ftr)
|
||||
.attr("data-text", "fill");
|
||||
y += 15;
|
||||
for (let i of colors) {
|
||||
let h = 10;
|
||||
points["_bl" + i] = new Point(0, y);
|
||||
points["_br" + i] = new Point(w, y);
|
||||
points["_tr" + i] = new Point(w, y - h);
|
||||
points["_tl" + i] = new Point(0, y - h);
|
||||
paths["box" + i] = new Path()
|
||||
.move(points["_bl" + i])
|
||||
.line(points["_br" + i])
|
||||
.line(points["_tr" + i])
|
||||
.line(points["_tl" + i])
|
||||
.close()
|
||||
.attr("class", i)
|
||||
.attr("class", "fill-" + i)
|
||||
.attr("data-text", ".fill-" + i);
|
||||
if (i === "fabric") paths["box" + i].attr("data-text-class", "fill-canvas");
|
||||
y += h * 1.2;
|
||||
}
|
||||
|
||||
let text = ["xs", "sm", "", "l", "xl", "xxl"];
|
||||
y += 10;
|
||||
points.tl = new Point(0, y);
|
||||
points.tr = new Point(w, y);
|
||||
paths.text = new Path()
|
||||
.move(points.tl)
|
||||
.line(points.tr)
|
||||
.attr("data-text", "text");
|
||||
y += 10;
|
||||
points.tlc = new Point(0, y);
|
||||
points.trc = new Point(w, y);
|
||||
paths.textc = new Path()
|
||||
.move(points.tlc)
|
||||
.line(points.trc)
|
||||
.attr("data-text", "text.center")
|
||||
.attr("data-text-class", "center");
|
||||
y += 10;
|
||||
points.tlr = new Point(0, y);
|
||||
points.trr = new Point(w, y);
|
||||
paths.textr = new Path()
|
||||
.move(points.tlr)
|
||||
.line(points.trr)
|
||||
.attr("data-text", "text.right")
|
||||
.attr("data-text-class", "right");
|
||||
for (let i in text) {
|
||||
y += 15;
|
||||
points["t" + i] = new Point(0, y)
|
||||
.attr("data-text", "text" + text[i] === "" ? "" : ".text-" + text[i])
|
||||
.attr("data-text-class", "text-" + text[i]);
|
||||
}
|
||||
let snips = {
|
||||
logo: 25,
|
||||
notch: 15,
|
||||
bnotch: 15,
|
||||
button: 15,
|
||||
buttonhole: 15
|
||||
};
|
||||
y += 10;
|
||||
points.tl = new Point(0, y);
|
||||
points.tr = new Point(w, y);
|
||||
paths.texts = new Path()
|
||||
.move(points.tl)
|
||||
.line(points.tr)
|
||||
.attr("data-text", "snippets");
|
||||
y += 10;
|
||||
points["sl1"] = new Point(w * 0.25, y);
|
||||
points["sl2"] = new Point(w * 0.5, y);
|
||||
points["sl3"] = new Point(w * 0.75, y);
|
||||
points["sl1"]
|
||||
.attr("data-text", "data-scale: 1\ndata-rotate: 0")
|
||||
.attr("data-text-class", "center text-sm")
|
||||
.attr("data-text-lineheight", 5);
|
||||
points["sl2"]
|
||||
.attr("data-text", "data-scale: 1.25\ndata-rotate: 0")
|
||||
.attr("data-text-class", "center text-sm")
|
||||
.attr("data-text-lineheight", 5);
|
||||
points["sl3"]
|
||||
.attr("data-text", "data-scale: 0.75\ndata-rotate: 90")
|
||||
.attr("data-text-class", "center text-sm")
|
||||
.attr("data-text-lineheight", 5);
|
||||
y += 55;
|
||||
for (let i in snips) {
|
||||
points["snt" + i] = new Point(0, y);
|
||||
points["snt" + i].attr("data-text", i);
|
||||
points["sn1" + i] = new Point(w * 0.25, y);
|
||||
points["sn2" + i] = new Point(w * 0.5, y);
|
||||
points["sn3" + i] = new Point(w * 0.75, y);
|
||||
snippets["sn1" + i] = new Snippet(i, points["sn1" + i]);
|
||||
snippets["sn2" + i] = new Snippet(i, points["sn2" + i]);
|
||||
snippets["sn2" + i].attr("data-scale", 1.25);
|
||||
snippets["sn3" + i] = new Snippet(i, points["sn3" + i]);
|
||||
snippets["sn3" + i].attr("data-scale", 0.75).attr("data-rotate", 90);
|
||||
y += snips[i];
|
||||
}
|
||||
|
||||
y += 10;
|
||||
points.ml = new Point(0, y);
|
||||
points.mr = new Point(w, y);
|
||||
paths.macros = new Path()
|
||||
.move(points.ml)
|
||||
.line(points.mr)
|
||||
.attr("data-text", "macros");
|
||||
|
||||
y += 40;
|
||||
macro("title", {
|
||||
at: new Point(w / 2, y),
|
||||
nr: 5,
|
||||
title: "title"
|
||||
});
|
||||
|
||||
y += 40;
|
||||
macro("grainline", {
|
||||
from: new Point(0, y),
|
||||
to: new Point(w, y)
|
||||
});
|
||||
|
||||
y += 20;
|
||||
macro("cutonfold", {
|
||||
from: new Point(w, y),
|
||||
to: new Point(0, y)
|
||||
});
|
||||
|
||||
y += 70;
|
||||
points.dimf = new Point(20, y);
|
||||
points.dimt = new Point(w - 20, y + 120);
|
||||
points.dimv = new Point(20, y + 80);
|
||||
paths.dims = new Path().move(points.dimf)._curve(points.dimv, points.dimt);
|
||||
macro("hd", {
|
||||
from: points.dimf,
|
||||
to: points.dimt,
|
||||
text: "hd",
|
||||
y: y - 15
|
||||
});
|
||||
macro("vd", {
|
||||
from: points.dimt,
|
||||
to: points.dimf,
|
||||
text: "vd",
|
||||
x: 0
|
||||
});
|
||||
macro("ld", {
|
||||
from: points.dimf,
|
||||
to: points.dimt,
|
||||
text: "ld"
|
||||
});
|
||||
macro("pd", {
|
||||
path: paths.dims,
|
||||
text: "pd",
|
||||
d: 10
|
||||
});
|
||||
|
||||
y += 170;
|
||||
macro("scalebox", {
|
||||
at: new Point(w / 2, y)
|
||||
});
|
||||
|
||||
// Make sure nothing is cut off
|
||||
paths.box = new Path()
|
||||
.move(new Point(-10, -10))
|
||||
.line(new Point(w + 10, y + 10))
|
||||
.attr("class", "hidden");
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
13
packages/rendertest/src/index.js
Normal file
13
packages/rendertest/src/index.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
// Parts
|
||||
import draftColors from "./colors";
|
||||
|
||||
// Create design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
|
||||
// Attach draft methods to prototype
|
||||
Pattern.prototype.draftColors = part => draftColors(part);
|
||||
|
||||
export default Pattern;
|
Loading…
Add table
Add a link
Reference in a new issue