1
0
Fork 0

🚧 Progress on workbench and CFP

This commit is contained in:
Joost De Cock 2019-05-09 15:24:26 +02:00
parent c2628a0a52
commit c9afc0edd0
26 changed files with 962 additions and 25 deletions

View file

@ -40,6 +40,7 @@ components:
"@material-ui/core": "^3.9.3"
"@material-ui/icons": "^3.0.2"
"@material-ui/lab": "^3.0.0-alpha.30"
"prismjs": "1.16.0"
core:
_:
"bezier-js": "^2.2.13"

View file

@ -0,0 +1,64 @@
import React from "react";
const DesignPath = props => {
let output = [];
let i = 0;
let from = null;
for (let op of props.path.ops) {
if (op.type === "curve") {
output.push(
<path
key={i}
d={`M ${from.x},${from.y} L ${op.cp1.x},${op.cp1.y}`}
className="design path cp"
/>
);
i++;
output.push(
<path
key={i}
d={`M ${op.to.x},${op.to.y} L ${op.cp2.x},${op.cp2.y}`}
className="design path cp"
/>
);
i++;
output.push(
<circle
key={i}
cx={op.cp1.x}
cy={op.cp1.y}
r={3.5}
className="design path cp"
/>
);
i++;
output.push(
<circle
key={i}
cx={op.cp2.x}
cy={op.cp2.y}
r={3.5}
className="design path cp"
/>
);
from = op.to;
} else if (op.type !== "close") from = op.to;
}
output.push(
<path
key={"dpath-" + props.name}
d={props.path.asPathstring()}
onClick={() =>
props.raiseEvent("path", {
path: props.path,
name: props.name,
part: props.part
})
}
className="design hovertrap"
/>
);
return output;
};
export default DesignPath;

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,22 @@
import React from "react";
const DesignPoint = props => (
<g className={props.className}>
<circle cx={props.point.x} cy={props.point.y} r="2" className="center" />
<circle
cx={props.point.x}
cy={props.point.y}
r="7.5"
className="hovertrap"
onClick={() =>
props.raiseEvent("point", {
point: props.point,
name: props.name,
part: props.part
})
}
/>
</g>
);
export default DesignPoint;

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,60 @@ import Snippet from "../Snippet";
import { getProps } from "../utils";
const Part = props => {
console.log(props.part);
const focusPoint = (point, i) => {
let p = props.part.points[point];
let pathString = `M ${p.x} ${props.part.topLeft.y} `;
pathString += `L ${p.x} ${props.part.bottomRight.y} `;
pathString += `M ${props.part.topLeft.x} ${p.y} `;
pathString += `L ${props.part.bottomRight.x} ${p.y} `;
let classes = "focus point c" + (i % 4); // Cycle through 4 CSS classes
return (
<React.Fragment key={"fp" + point}>
<path d={pathString} className={classes} />
<circle
cx={p.x}
cy={p.y}
r="5"
className={classes}
onClick={() =>
props.raiseEvent("clearFocus", {
part: props.name,
type: "points",
name: point
})
}
/>
</React.Fragment>
);
};
const focusCoords = (p, i) => {
console.log("focus coords", p, i);
let pathString = `M ${p.x} ${props.part.topLeft.y} `;
pathString += `L ${p.x} ${props.part.bottomRight.y} `;
pathString += `M ${props.part.topLeft.x} ${p.y} `;
pathString += `L ${props.part.bottomRight.x} ${p.y} `;
let classes = "focus coords c" + (i % 4); // Cycle through 4 CSS classes
return (
<React.Fragment key={"cp" + i}>
<path d={pathString} className={classes} />
<circle
cx={p.x}
cy={p.y}
r="5"
className={classes}
onClick={() =>
props.raiseEvent("clearFocus", {
part: props.name,
type: "coords",
data: p
})
}
/>
</React.Fragment>
);
};
let grid = props.paperless ? (
<rect
x={props.part.topLeft.x}
@ -18,6 +71,38 @@ const Part = props => {
/>
) : null;
let focus = [];
if (props.design) {
let designProps = {
...props,
key: "dp-" + props.name,
className: "design point"
};
if (props.focus && typeof props.focus[props.name] !== "undefined") {
for (let i in props.focus[props.name].points)
focus.push(focusPoint(props.focus[props.name].points[i], i));
for (let i in props.focus[props.name].paths) {
let name = props.focus[props.name].paths[i];
focus.push(
<path
key={"fpa-" + name}
d={props.part.paths[name].asPathstring()}
className={"focus path c" + (i % 4)}
onClick={() =>
props.raiseEvent("clearFocus", {
part: props.name,
type: "paths",
name
})
}
/>
);
}
for (let i in props.focus[props.name].coords)
focus.push(focusCoords(props.focus[props.name].coords[i], i));
}
}
return (
<g {...getProps(props.part)}>
{grid}
@ -28,6 +113,11 @@ const Part = props => {
part={props.name}
language={props.language}
path={props.part.paths[name]}
focus={props.focus}
topLeft={props.part.topLeft}
bottomRight={props.part.bottomRight}
design={props.design}
raiseEvent={props.raiseEvent}
/>
))}
{Object.keys(props.part.points).map(name => (
@ -37,11 +127,17 @@ const Part = props => {
part={props.name}
language={props.language}
point={props.part.points[name]}
focus={props.focus}
topLeft={props.part.topLeft}
bottomRight={props.part.bottomRight}
design={props.design}
raiseEvent={props.raiseEvent}
/>
))}
{Object.keys(props.part.snippets).map(name => (
<Snippet key={name} name={name} snippet={props.part.snippets[name]} />
))}
{focus}
</g>
);
};
@ -51,6 +147,7 @@ Part.propTypes = {
name: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
paperless: PropTypes.bool.isRequired,
design: PropTypes.bool.isRequired,
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
};

View file

@ -1,12 +1,15 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import TextOnPath from "../TextOnPath";
import DesignPath from "../DesignPath";
import { getProps } from "../utils";
const Path = props => {
if (!props.path.render) return null;
const output = [];
const pathId = "path-" + props.part + "-" + props.name;
if (props.design)
output.push(<DesignPath {...props} key={"dpa-" + props.name} />);
output.push(
<path
id={pathId}

View file

@ -1,10 +1,19 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import DesignPoint from "../DesignPoint";
import Text from "../Text";
import Circle from "../Circle";
const Point = props => {
const output = [];
if (props.design)
output.push(
<DesignPoint
{...props}
key={"dp-" + props.name}
className="design point"
/>
);
if (props.point.attributes.get("data-text"))
output.push(<Text {...props} key={"point-" + props.name} />);
if (props.point.attributes.get("data-circle"))

View file

@ -17,6 +17,7 @@ const Draft = props => {
units={props.settings.units}
parts={props.parts}
paperless={props.settings.paperless}
design={props.design}
/>
<g>
{Object.keys(props.parts).map(name => (
@ -27,6 +28,9 @@ const Draft = props => {
units={props.settings.units}
key={name}
name={name}
focus={props.focus}
design={props.design}
raiseEvent={props.raiseEvent}
/>
))}
</g>
@ -41,7 +45,8 @@ Draft.propTypes = {
};
Draft.defaultProps = {
design: false
design: false,
focus: false
};
export default Draft;

View file

@ -0,0 +1,219 @@
import React from "react";
import PropTypes from "prop-types";
import { FormattedMessage, FormattedHTMLMessage } from "react-intl";
const Design = props => {
// Methods
const renderAttributes = attr => {
let list = [];
for (let a in attr.list)
list.push(
<li key={a}>
<b>{a}</b>: {renderAttributeValue(attr.list[a])}
</li>
);
return <ul className="links">{list}</ul>;
};
const renderAttributeValue = val => {
if (Array.isArray(val)) {
if (val.length === 1) return val.pop();
let list = [];
for (let v of val) list.push(<li key={v}>{v}</li>);
return <ul>{list}</ul>;
}
return val;
};
const idPathPoint = (part, a) => {
for (let p in props.parts[part].points) {
let b = props.parts[part].points[p];
if (a.x === b.x && a.y === b.y) return p;
}
return false;
};
const renderPathOps = (path, part) => {
let list = [];
for (let i in path.ops) list.push(renderPathOp(path.ops[i], i, part));
return <ul className="links">{list}</ul>;
};
const renderPathOp = (op, key, part) => {
let list = [];
let focus = {
part,
coords: {
x: null,
y: null
}
};
if (op.type === "move" || op.type === "line") {
focus.coords.x = op.to.x;
focus.coords.y = op.to.y;
let text = <span>(op.to.x,op.to.y)</span>;
let click = () => props.raiseEvent("coords", focus);
let pname = idPathPoint(part, op.to);
if (pname) {
text = pname;
click = () =>
props.raiseEvent("point", {
point: props.parts[part].points[pname],
name: pname,
part: part
});
}
return (
<li key={key}>
<b>{op.type}</b>
&nbsp;&raquo;&nbsp;
<a href="#logo" role="button" onClick={click}>
{text}
</a>
</li>
);
} else if (op.type === "curve") {
let texts = {};
let clicks = {};
let types = ["to", "cp1", "cp2"];
for (let t of types) {
let pname = idPathPoint(part, op[t]);
if (pname) {
texts[t] = pname;
clicks[t] = () =>
props.raiseEvent("point", {
point: props.parts[part].points[pname],
name: pname,
part
});
} else {
texts[t] = (
<span>
({op[t].x},{op[t].y})
</span>
);
clicks[t] = () =>
props.raiseEvent("coords", {
...focus,
coords: {
x: op[t].x,
y: op[t].y
}
});
}
}
return (
<li key={key}>
<b>{op.type}</b>
{types.map(t => (
<React.Fragment key={t}>
<span>&ensp;&raquo;&ensp;</span>
<a href="#logo" role="button" onClick={clicks[t]}>
{texts[t]}
</a>
</React.Fragment>
))}
</li>
);
} else if (op.type === "close")
return (
<li key={key}>
<b>close</b>
</li>
);
return null;
};
// Variables
const styles = {
container: {
padding: "0 1rem"
},
h3: {
margin: "0.5rem 0"
},
h4: {
margin: "0.25rem 0 0 0.5rem"
},
ul: {
marginTop: "0.25rem"
}
};
if (
!props.design ||
props.focus === null ||
Object.keys(props.focus).length < 1
)
return null;
let info = [];
for (let part of Object.keys(props.focus)) {
info.push(
<h3 key={"part-" + part} style={styles.h3}>
parts.<b>{part}</b>
</h3>
);
for (let i in props.focus[part].paths) {
let name = props.focus[part].paths[i];
let path = props.parts[part].paths[name];
info.push(
<h4
key={"patitle-" + name}
style={styles.h4}
className={"path c" + (i % 4)}
>
path.<b>{name}</b>
</h4>
);
info.push(
<ul className="links" key={"ops-" + name} style={styles.ul}>
<li>
<b>attributes</b>: {renderAttributes(path.attributes)}
</li>
<li>
<b>ops</b>: {renderPathOps(path, part)}
</li>
</ul>
);
}
for (let i in props.focus[part].points) {
let name = props.focus[part].points[i];
let point = props.parts[part].points[name];
info.push(
<h4
key={"potitle-" + name}
style={styles.h4}
className={"point c" + (i % 4)}
>
point.<b>{name}</b>
</h4>
);
info.push(
<ul className="links" key={"pdata-" + name} style={styles.ul}>
<li>
<b>x</b>: {point.x}
</li>
<li>
<b>y</b>: {point.y}
</li>
<li>
<b>attributes</b>: {renderAttributes(point.attributes)}
</li>
</ul>
);
}
}
return (
<div style={styles.container} className="design">
{info}
</div>
);
};
export default Design;

View file

@ -1,27 +1,119 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import { defaultGist } from "@freesewing/utils";
import Draft from "../../Draft";
import Design from "../Design";
import DraftConfigurator from "../../DraftConfigurator";
import { strings } from "@freesewing/i18n";
import { FormattedMessage } from "react-intl";
import Prism from "prismjs";
const DraftPattern = props => {
const [design, setDesign] = useState(true);
const [focus, setFocus] = useState(null);
const raiseEvent = (type, data) => {
if (type === "clearFocusAll") return setFocus(null);
let f = {};
if (focus !== null) f = { ...focus };
if (typeof f[data.part] === "undefined")
f[data.part] = { paths: [], points: [], coords: [] };
if (type === "point") f[data.part].points.push(data.name);
else if (type === "path") f[data.part].paths.push(data.name);
else if (type === "coords") f[data.part].coords.push(data.coords);
else if (type === "clearFocus") {
let i = focus[data.part][data.type].indexOf(data.name);
f[data.part][data.type].splice(i, 1);
}
setFocus(f);
};
const styles = {
paragraph: {
padding: "0 1rem"
}
};
let pattern = new props.Pattern(props.gist.settings);
pattern.draft();
let patternProps = pattern.getRenderProps();
let focusCount = 0;
if (focus !== null) {
for (let p of Object.keys(focus)) {
for (let i in focus[p].points) focusCount++;
for (let i in focus[p].paths) focusCount++;
for (let i in focus[p].coords) focusCount++;
}
}
let gist = Prism.highlight(
JSON.stringify(props.gist, null, 2),
Prism.languages.javascript,
"javascript"
);
return (
<div className="fs-sa">
<section>
<h2>
<FormattedMessage id="app.pattern" />
</h2>
<Draft {...pattern.getRenderProps()} />
<Draft
{...patternProps}
design={design}
focus={focus}
raiseEvent={raiseEvent}
/>
<h2>gist</h2>
<pre>{JSON.stringify(props.gist, null, 2)}</pre>
<div className="gatsby-highlight" dataLanguage="json">
<pre
className="language-json"
dangerouslySetInnerHTML={{ __html: gist }}
/>
</div>
</section>
<aside>
<div className="sticky">
{design ? (
<React.Fragment>
<p style={styles.paragraph}>
<FormattedMessage id="cfp.designModeIsOn" />
&nbsp;(
<a href="#logo" onClick={() => setDesign(false)}>
<FormattedMessage id="cfp.turnOff" />
</a>
)
{focusCount > 0 ? (
<React.Fragment>
&ensp;(
<a
href="#logo"
onClick={() => raiseEvent("clearFocusAll", null)}
>
<FormattedMessage id="app.reset" />
</a>
)
</React.Fragment>
) : null}
</p>
<Design
focus={focus}
design={design}
raiseEvent={raiseEvent}
parts={patternProps.parts}
/>
</React.Fragment>
) : (
<p style={styles.paragraph}>
<FormattedMessage id="cfp.designModeIsOff" />
&nbsp;(
<a href="#logo" onClick={() => setDesign(true)}>
<FormattedMessage id="cfp.turnOn" />
</a>
)
</p>
)}
<DraftConfigurator
config={props.config}
gist={props.gist}

View file

@ -82,9 +82,7 @@ const Workbench = props => {
if (theme === "light") setTheme("dark");
else setTheme("light");
};
const raiseEvent = (type = null, data = null) => {
console.log("FIXME: Event raised", type, data);
};
const raiseEvent = (type = null, data = null) => {};
const navs = {
left: {

View file

@ -0,0 +1,10 @@
{
"plugins": [
["prismjs", {
"languages": ["javascript", "css", "markup"],
"plugins": ["line-numbers"],
"theme": "twilight",
"css": true
}]
]
}

View file

@ -0,0 +1,55 @@
{
"name": "{{name}}-example",
"version": "0.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"babel-plugin-prismjs": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/babel-plugin-prismjs/-/babel-plugin-prismjs-1.0.2.tgz",
"integrity": "sha512-WbUE86Aih6h6daLpyavuikEXECrkon21oWh4MOHa5stMfY/IK1e/Sr79qEGhl7KrL16fMChB3tdbVR82ubnzOg==",
"dev": true
},
"clipboard": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
"integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"requires": {
"delegate": "^3.1.2"
}
},
"prismjs": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz",
"integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==",
"requires": {
"clipboard": "^2.0.0"
}
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
}
}
}

View file

@ -4,29 +4,30 @@
"version": "0.0.0",
"private": true,
"dependencies": {
"react": "^16.8",
"react-dom": "^16.8",
"react-scripts": "^3.0.0",
"@freesewing/core": "alpha",
"@freesewing/plugin-debug": "alpha",
"@freesewing/plugin-theme": "alpha",
"@freesewing/plugin-designer": "alpha",
"@freesewing/plugin-svgattr": "alpha",
"@freesewing/plugin-i18n": "alpha",
"@freesewing/plugin-validate": "alpha",
"@freesewing/plugin-react": "alpha",
"@freesewing/i18n": "alpha",
"@freesewing/utils": "alpha",
"@freesewing/models": "alpha",
"@freesewing/components": "alpha",
"@freesewing/core": "alpha",
"@freesewing/css-theme": "alpha",
"@freesewing/i18n": "alpha",
"@freesewing/models": "alpha",
"@freesewing/mui-theme": "alpha",
"@freesewing/pattern-info": "alpha",
"@freesewing/plugin-debug": "alpha",
"@freesewing/plugin-designer": "alpha",
"@freesewing/plugin-i18n": "alpha",
"@freesewing/plugin-react": "alpha",
"@freesewing/plugin-svgattr": "alpha",
"@freesewing/plugin-theme": "alpha",
"@freesewing/plugin-validate": "alpha",
"@freesewing/utils": "alpha",
"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"@material-ui/lab": "^3.0.0-alpha.30",
"typeface-roboto-condensed": "latest",
"pattern": "{{#if yarn}}link:..{{else}}file:..{{/if}}"
"pattern": "{{#if yarn}}link:..{{else}}file:..{{/if}}",
"prismjs": "1.16.0",
"react": "^16.8",
"react-dom": "^16.8",
"react-scripts": "^3.0.0",
"typeface-roboto-condensed": "latest"
},
"scripts": {
"start": "react-scripts start",
@ -42,5 +43,8 @@
"not dead",
"not ie <= 11",
"not op_mini all"
]
],
"devDependencies": {
"babel-plugin-prismjs": "1.0.2"
}
}

View file

@ -2,3 +2,4 @@
@import "components/navbar";
@import "components/draft";
@import "components/draft-configurator";
@import "components/draft-design";

View file

@ -1,3 +1,4 @@
@import "elements/a";
@import "elements/footer";
@import "elements/ul";
@import "elements/code";

View file

@ -0,0 +1,147 @@
/**
* atom-dark theme for `prism.js`
* Based on Atom's `atom-dark` theme: https://github.com/atom/atom-dark-syntax
* @author Joe Gibson (@gibsjose)
*/
code[class*="language-"],
pre[class*="language-"] {
color: #c5c8c6;
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: 0.3em;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #1d1f21;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #7C7C7C;
}
.token.punctuation {
color: #c5c8c6;
}
.namespace {
opacity: .7;
}
.token.property,
.token.keyword,
.token.tag {
color: #96CBFE;
}
.token.class-name {
color: #FFFFB6;
text-decoration: underline;
}
.token.boolean,
.token.constant {
color: #99CC99;
}
.token.symbol,
.token.deleted {
color: #f92672;
}
.token.number {
color: #FF73FD;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #A8FF60;
}
.token.variable {
color: #C6C5FE;
}
.token.operator {
color: #EDEDED;
}
.token.entity {
color: #FFFFB6;
/* text-decoration: underline; */
}
.token.url {
color: #96CBFE;
}
.language-css .token.string,
.style .token.string {
color: #87C38A;
}
.token.atrule,
.token.attr-value {
color: #F9EE98;
}
.token.function {
color: #DAD085;
}
.token.regex {
color: #E9C062;
}
.token.important {
color: #fd971f;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View file

@ -0,0 +1,129 @@
svg.freesewing.draft {
g.design.point {
circle {
stroke: none;
fill-opacity: 0.5;
}
circle.hovertrap {
opacity: 0;
transition: opacity 0.1s ease-in;
}
circle.hovertrap:hover {
cursor: pointer;
opacity: 0.3;
}
}
path.design.hovertrap {
stroke-width: 5;
stroke-opacity: 0;
transition: stroke-opacity 0.1s ease-in;
}
path.design.hovertrap:hover {
cursor: pointer;
stroke-opacity: 0.2;
}
path.focus.point,
path.focus.coords {
stroke-width: 0.2;
stroke: $oc-red-6;
}
circle.focus.point,
circle.focus.coords {
fill: white;
fill-opacity: 0.01;
stroke: $oc-red-6;
stroke-width: 0.2;
}
circle.focus.point:hover,
circle.focus.coords:hover {
cursor: pointer;
}
path.focus.path {
stroke-width: 5;
stroke-opacity: 0.3;
stroke-dasharray: 4 5.5;
}
path.focus.path:hover {
cursor: pointer;
}
path.focus.point.c0,
circle.focus.point.c0,
path.focus.coords.c0,
circle.focus.coords.c0 {
stroke: $oc-red-6;
}
path.focus.point.c1,
circle.focus.point.c1,
path.focus.coords.c1,
circle.focus.coords.c01{
stroke: $oc-green-6;
}
path.focus.point.c2,
circle.focus.point.c2,
path.focus.coords.c2,
circle.focus.coords.c02{
stroke: $oc-blue-6;
}
path.focus.point.c3,
circle.focus.point.c3,
path.focus.coords.c3,
circle.focus.coords.c03{
stroke: $oc-grape-6;
}
path.focus.coords,
circle.focus.coords {
stroke-dasharray: 3 3;
}
path.design.path.cp {
stroke: $oc-orange-5;
stroke-width: 0.5;
}
circle.design.path.cp {
stroke: $oc-orange-5;
stroke-width: 1;
}
path.focus.path.c0 { stroke: $oc-red-6 }
path.focus.path.c1 { stroke: $oc-green-6 }
path.focus.path.c2 { stroke: $oc-blue-6 }
path.focus.path.c3 { stroke: $oc-grape-6 }
}
div.design {
h4.point.c0 { border-bottom: 1px solid $oc-red-6; }
h4.point.c1 { border-bottom: 1px solid $oc-green-6; }
h4.point.c2 { border-bottom: 1px solid $oc-blue-6; }
h4.point.c3 { border-bottom: 1px solid $oc-grape-6; }
}
.theme-wrapper.light svg.freesewing.draft {
g.design.point {
circle { fill: $fc-link-light; }
circle.hovertrap { stroke: $fc-link-light; }
}
path.design.hovertrap { stroke: $fc-link-light; }
circle.design.path.cp { fill: $fc-bg-light; }
}
.theme-wrapper.light div.design {
h4.path.c0 { background-color: rgba($oc-red-6, 0.3) }
h4.path.c1 { background-color: rgba($oc-green-6, 0.3) }
h4.path.c2 { background-color: rgba($oc-blue-6, 0.3) }
h4.path.c3 { background-color: rgba($oc-grape-6, 0.3) }
}
.theme-wrapper.dark svg.freesewing.draft {
g.design.point {
circle { fill: $fc-link-dark; }
circle.hovertrap { stroke: $fc-link-dark; }
}
path.design.hovertrap { stroke: $fc-link-dark; }
circle.design.path.cp { fill: $fc-bg-dark; }
path.focus.path { stroke-opacity: 0.5; }
}
.theme-wrapper.dark div.design {
h4.path.c0 { background-color: rgba($oc-red-6, 0.5) }
h4.path.c1 { background-color: rgba($oc-green-6, 0.5) }
h4.path.c2 { background-color: rgba($oc-blue-6, 0.5) }
h4.path.c3 { background-color: rgba($oc-grape-6, 0.5) }
}

View file

@ -0,0 +1,54 @@
.theme-wrapper.light :not(pre) > code[class*="language-"] {
padding: 0.125rem 0.5rem;
background: $oc-gray-6;
border: 1px $oc-gray-5 solid;
color: $oc-gray-9;
}
.theme-wrapper.dark :not(pre) > code[class*="language-"] {
padding: 0.125rem 0.5rem;
background: $oc-gray-6;
border: 1px $oc-gray-5 solid;
color: $oc-gray-9;
}
div.gatsby-highlight {
position: relative;
}
div.gatsby-highlight pre.language-js {
padding-top: 1rem;
}
pre.language-js:before,
pre.language-json:before,
pre.language-svg:before,
pre.language-bash:before {
border-top: 2px dashed $oc-gray-9;
display: block;
position: absolute;
top: 0;
right: 20px;
color: black;
padding: 1px 4px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
font-weight: bold;
text-shadow: none;
}
pre.language-js:before {
content: "js";
background: rgba(255, 255, 0, 0.9);
}
pre.language-json:before {
content: "json";
background: rgba(255, 255, 0, 0.9);
}
pre.language-bash:before {
content: "bash";
background: rgba(29, 227, 0, 0.9);
}
pre.language-svg:before {
content: "svg";
background: rgba(129, 197, 255, 0.9);
}

View file

@ -2,6 +2,7 @@
@import '../../../node_modules/open-color/open-color.scss';
@import "variables";
@import "mixins";
@import "prism";
@import "theme-wrapper";
@import "layout";
@import "scroll";

View file

@ -21,4 +21,8 @@ size: Größe
noRequiredMeasurements: Dieses Muster hat keine erforderlichen Messungen.
howtoAddMeasurements: Um Messungen anzufordern, fügen Sie sie dem <b>measurements</b> der Konfigurationsdatei des Musters hinzu.
seeDocsAt: Dokumentation zu diesem Thema finden Sie unter
designModeIsOn: Der Designmodus ist aktiviert
designModeIsOff: Entwurfsmodus ist deaktiviert
turnOn: Aktivieren
turnOff: Deaktivieren

View file

@ -20,3 +20,7 @@ size: Size
noRequiredMeasurements: This pattern has no required measurements
howtoAddMeasurements: To require measurements, add them to the <b>measurements</b> section of the pattern's configuration file.
seeDocsAt: Documentation on this topic is available at
designModeIsOn: Design mode is on
designModeIsOff: Design mode is off
turnOn: Turn on
turnOff: Turn off

View file

@ -21,3 +21,8 @@ size: Tamaño
noRequiredMeasurements: Este patrón no tiene medidas requeridas.
howtoAddMeasurements: Para requerir mediciones, agréguelas a la sección de <b>measurements</b> del archivo de configuración del patrón.
seeDocsAt: La documentación sobre este tema está disponible en
designModeIsOn: El modo de diseño está activado
designModeIsOff: El modo de diseño esta apagado
turnOn: Encender
turnOff: Apagar

View file

@ -21,3 +21,8 @@ size: Taille
noRequiredMeasurements: Ce patron n'a pas de mesures requises.
howtoAddMeasurements: Pour exiger des mesures, ajoutez-les à la section <b>measurements</b> du fichier de configuration du patron.
seeDocsAt: Documentation sur ce sujet est disponible à l'adresse
designModeIsOn: Le mode de conception est activé
designModeIsOff: Le mode de conception est désactivé
turnOn: Activer
turnOff: Désactiver

View file

@ -21,3 +21,8 @@ size: Maat
noRequiredMeasurements: Dit patroon vereist geen lichaamsmaten.
howtoAddMeasurements: Om lichaamsmaten te vereisen, voegt u ze toe aan de <b>measurements</b> sectie van het configuratiebestand van het patroon.
seeDocsAt: Documentatie over dit onderwerp is beschikbaar op
designModeIsOn: Ontwerpmodus is ingeschakeld
designModeIsOff: Ontwerpmodus is uitgeschakeld
turnOn: Inschakelen
turnOff: Uitschakelen