1
0
Fork 0

render pageless grid on pdf exports if pageless is on

This commit is contained in:
Enoch Riese 2022-12-13 11:55:50 -06:00
parent 4bdbddb3d6
commit e1f7de0209
9 changed files with 129 additions and 115 deletions

View file

@ -1,37 +1,41 @@
export const paperlessStyle = ` export const paperlessStyle = (stripped) => `
/* Paperless grid */ ${!stripped ? '/* Paperless grid */' : ''}
svg.freesewing path.grid { ${!stripped ? 'svg.freesewing ' : ''}path.grid {
fill: none;
stroke: #555; stroke: #555;
stroke-width: 0.3; stroke-width: 0.3;
} }
svg.freesewing path.gridline { ${!stripped ? 'svg.freesewing ' : ''}path.gridline {
stroke: #555; stroke: #555;
stroke-width: 0.2; stroke-width: 0.2;
fill: none;
} }
svg.freesewing path.gridline-lg { ${!stripped ? 'svg.freesewing ' : ''}path.gridline-lg {
stroke: #777; stroke: #777;
stroke-width: 0.2; stroke-width: 0.2;
stroke-dasharray: 1.5,1.5; stroke-dasharray: 1.5,1.5;
fill: none;
} }
svg.freesewing path.gridline-sm { ${!stripped ? 'svg.freesewing ' : ''}path.gridline-sm {
stroke: #999; stroke: #999;
stroke-width: 0.1; stroke-width: 0.1;
fill: none;
} }
svg.freesewing path.gridline-xs { ${!stripped ? 'svg.freesewing ' : ''}path.gridline-xs {
stroke: #999; stroke: #999;
stroke-width: 0.1; stroke-width: 0.1;
stroke-dasharray: 0.5,0.5; stroke-dasharray: 0.5,0.5;
fill: none;
} }
svg.freesewing path.gridbox { ${!stripped ? 'svg.freesewing ' : ''}path.gridbox {
fill: url(#grid); fill: url(#grid);
}` }`
export const sampleStyle = `
/* Sample classes */ export const sampleStyle = (stripped) => `
svg.freesewing path.sample { ${!stripped ? '/* Sample classes */' : ''}
${!stripped ? 'svg.freesewing ' : ''}path.sample {
stroke-width: 0.75 stroke-width: 0.75
} }
svg.freesewing path.sample-focus { ${!stripped ? 'svg.freesewing ' : ''}path.sample-focus {
stroke-width: 1.5; fill: rgba(0,0,0,0.1) stroke-width: 1.5; fill: rgba(0,0,0,0.1)
}` }`

View file

@ -28,8 +28,8 @@ export const plugin = {
const current = svg.attributes.get('class') const current = svg.attributes.get('class')
if (!current || current.indexOf('freesewing') !== -1) { if (!current || current.indexOf('freesewing') !== -1) {
svg.attributes.set('class', 'freesewing') svg.attributes.set('class', 'freesewing')
svg.style += sampleStyle svg.style += sampleStyle(data.stripped)
svg.style += paperlessStyle svg.style += paperlessStyle(data.stripped)
svg.style += buildStylesheet(svg.pattern.settings.scale, data.stripped) svg.style += buildStylesheet(svg.pattern.settings.scale, data.stripped)
let paperless = false let paperless = false
for (const set of svg.pattern.settings) { for (const set of svg.pattern.settings) {
@ -40,10 +40,10 @@ export const plugin = {
? (svg.defs += grid.imperial) ? (svg.defs += grid.imperial)
: (svg.defs += grid.metric) : (svg.defs += grid.metric)
const parts = svg.pattern.parts[svg.pattern.activeSet] const parts = svg.pattern.parts[svg.pattern.activeSet]
const skip = data.skipGrid || [] const skipGrid = data.skipGrid || []
for (const key in parts) { for (const key in parts) {
const part = parts[key] const part = parts[key]
if (!part.hidden && !data.skipGrid.includes(key) && svg.pattern.__needs(key)) { if (!part.hidden && !skipGrid.includes(key) && svg.pattern.__needs(key)) {
const { Path, paths, getId, Point, points } = part.shorthand() const { Path, paths, getId, Point, points } = part.shorthand()
let anchor = new Point(0, 0) let anchor = new Point(0, 0)
if (typeof points.gridAnchor !== 'undefined') anchor = part.points.gridAnchor if (typeof points.gridAnchor !== 'undefined') anchor = part.points.gridAnchor

View file

@ -1,4 +1,4 @@
import {forwardRef} from 'react' import { forwardRef } from 'react'
import Path from '../path' import Path from '../path'
import Point from '../point' import Point from '../point'
import Snippet from '../snippet' import Snippet from '../snippet'
@ -17,11 +17,11 @@ const partInfo = (props) => (
</Tr> </Tr>
<Tr> <Tr>
<KeyTd>Width</KeyTd> <KeyTd>Width</KeyTd>
<ValTd>{round(props.part.width,2)}mm</ValTd> <ValTd>{round(props.part.width, 2)}mm</ValTd>
</Tr> </Tr>
<Tr> <Tr>
<KeyTd>Height</KeyTd> <KeyTd>Height</KeyTd>
<ValTd>{round(props.part.height,2)}mm</ValTd> <ValTd>{round(props.part.height, 2)}mm</ValTd>
</Tr> </Tr>
<Tr> <Tr>
<KeyTd>Top Left</KeyTd> <KeyTd>Top Left</KeyTd>
@ -33,62 +33,67 @@ const partInfo = (props) => (
</Tr> </Tr>
<Tr> <Tr>
<KeyTd>Attributes</KeyTd> <KeyTd>Attributes</KeyTd>
<ValTd><Attributes list={props.part.attributes.list} /></ValTd> <ValTd>
<Attributes list={props.part.attributes.list} />
</ValTd>
</Tr> </Tr>
</tbody> </tbody>
</table> </table>
<div className="flex flex-row flex-wrap gap-2 mt-4"> <div className="flex flex-row flex-wrap gap-2 mt-4">
{props.gist?.only && props.gist.only.length > 0 {props.gist?.only && props.gist.only.length > 0 ? (
? ( <button className="btn btn-primary" onClick={() => props.unsetGist(['only'])}>
<button Show all parts
className="btn btn-primary" </button>
onClick={() => props.unsetGist(['only'])}
>Show all parts</button>
) : ( ) : (
<button <button
className="btn btn-primary" className="btn btn-primary"
onClick={() => props.updateGist(['only'], [props.partName])} onClick={() => props.updateGist(['only'], [props.partName])}
>Show only this part</button> >
Show only this part
</button>
)} )}
<button <button className="btn btn-success" onClick={() => console.log(props.part)}>
className="btn btn-success" console.log(part)
onClick={() => console.log(props.part)} </button>
>console.log(part)</button> <button className="btn btn-success" onClick={() => console.table(props.part.points)}>
<button console.table(part.points)
className="btn btn-success" </button>
onClick={() => console.table(props.part.points)} <button className="btn btn-success" onClick={() => console.table(props.part.paths)}>
>console.table(part.points)</button> console.table(part.paths)
<button </button>
className="btn btn-success"
onClick={() => console.table(props.part.paths)}
>console.table(part.paths)</button>
</div> </div>
</div> </div>
) )
const XrayPart = props => { const XrayPart = (props) => {
const { topLeft, bottomRight } = props.part const { topLeft, bottomRight } = props.part
return ( return (
<g> <g>
<path d={` <path
d={`
M ${topLeft.x} ${topLeft.y} M ${topLeft.x} ${topLeft.y}
L ${topLeft.x} ${bottomRight.y} L ${topLeft.x} ${bottomRight.y}
L ${bottomRight.x} ${bottomRight.y} L ${bottomRight.x} ${bottomRight.y}
L ${bottomRight.x} ${topLeft.y} L ${bottomRight.x} ${topLeft.y}
z z
`} className={`peer stroke-note lashed opacity-30 hover:opacity-90 fill-fabric hover:cursor-pointer hover:stroke-mark`} `}
style={{ fillOpacity: 0}} className={`peer stroke-note lashed opacity-30 hover:opacity-90 fill-fabric hover:cursor-pointer hover:stroke-mark`}
onClick={(evt) => { evt.stopPropagation(); props.showInfo(partInfo(props)) }} style={{ fillOpacity: 0 }}
onClick={(evt) => {
evt.stopPropagation()
props.showInfo(partInfo(props))
}}
/> />
</g> </g>
) )
} }
export const PartInner = forwardRef((props, ref) => { export const PartInner = forwardRef((props, ref) => {
const { partName, part, gist } = props const { partName, part, gist, skipGrid } = props
const Grid = gist.paperless ? ( const Grid =
gist.paperless && !skipGrid ? (
<rect <rect
x={part.topLeft.x} x={part.topLeft.x}
y={part.topLeft.y} y={part.topLeft.y}
@ -99,12 +104,10 @@ export const PartInner = forwardRef((props, ref) => {
/> />
) : null ) : null
return (<g ref={ref}> return (
<g ref={ref}>
{Grid} {Grid}
{ {gist._state?.xray?.enabled && <XrayPart {...props} />}
gist._state?.xray?.enabled &&
<XrayPart {...props} />
}
{Object.keys(part.paths).map((pathName) => ( {Object.keys(part.paths).map((pathName) => (
<Path <Path
key={pathName} key={pathName}
@ -133,15 +136,20 @@ export const PartInner = forwardRef((props, ref) => {
{...props} {...props}
/> />
))} ))}
</g>) </g>
)
}) })
const Part = props => { const Part = (props) => {
const { partName, part} = props const { partName, part } = props
return ( return (
<g {...getProps(part)} id={`${part.context.settings.idPrefix || ''}part-${partName}`} className={part.context.settings.idPrefix || ''}> <g
<PartInner {...props}/> {...getProps(part)}
id={`${part.context.settings.idPrefix || ''}part-${partName}`}
className={part.context.settings.idPrefix || ''}
>
<PartInner {...props} />
</g> </g>
) )
} }

View file

@ -74,7 +74,7 @@ export const handleExport = async (format, gist, design, t, app, onComplete, onE
let pattern = new design({ ...gist, layout }) let pattern = new design({ ...gist, layout })
// add the theme and translation to the pattern // add the theme and translation to the pattern
pattern.use(themePlugin, { stripped: format !== 'svg' }) pattern.use(themePlugin, { stripped: format !== 'svg', skipGrid: ['pages'] })
pattern.use( pattern.use(
{ {
hooks: { hooks: {
@ -115,13 +115,13 @@ export const handleExport = async (format, gist, design, t, app, onComplete, onE
// add the svg and pages data to the worker args // add the svg and pages data to the worker args
workerArgs.pages = pattern.setStores[pattern.activeSet].get('pages') workerArgs.pages = pattern.setStores[pattern.activeSet].get('pages')
// post a message to the worker with all needed data
worker.postMessage(workerArgs)
} catch (err) { } catch (err) {
console.log(err) console.log(err)
app.stopLoading() app.stopLoading()
onError && onError(err) onError && onError(err)
} }
} }
// post a message to the worker with all needed data
worker.postMessage(workerArgs)
} }

View file

@ -3,9 +3,9 @@ import SVGtoPDF from 'svg-to-pdfkit'
import { path as logoPath } from 'shared/components/icons/freesewing.js' import { path as logoPath } from 'shared/components/icons/freesewing.js'
/** an svg of the logo to put on the cover page */ /** an svg of the logo to put on the cover page */
const logoSvg = `<svg viewBox="-22 -36 46 50"> const logoSvg = `<svg viewBox="0 0 25 25">
<style> path {fill: none; stroke: #555555; stroke-width: 0.5} </style> <style> path {fill: none; stroke: #555555; stroke-width: 0.25} </style>
<path d=${logoPath} /> <path d="${logoPath}" />
</svg>` </svg>`
/** /**

View file

@ -69,7 +69,12 @@ const Draft = (props) => {
// Bottom in SVG means we need to draw it first // Bottom in SVG means we need to draw it first
const stacks = [ const stacks = [
<PartInner <PartInner
{...{ part: patternProps.parts[0][props.layoutPart], partName: props.layoutPart, gist }} {...{
part: patternProps.parts[0][props.layoutPart],
partName: props.layoutPart,
gist,
skipGrid: true,
}}
key={props.layoutPart} key={props.layoutPart}
/>, />,
] ]

View file

@ -121,7 +121,7 @@ const WorkbenchWrapper = ({ app, design, preload = false, from = false, layout =
//draft.__init() //draft.__init()
// add theme to svg renderer // add theme to svg renderer
if (gist.renderer === 'svg') draft.use(pluginTheme) if (gist.renderer === 'svg') draft.use(pluginTheme, { skipGrid: ['pages'] })
// draft it for draft and event views. Other views may add plugins, etc and we don't want to draft twice // draft it for draft and event views. Other views may add plugins, etc and we don't want to draft twice
try { try {

View file

@ -55,7 +55,7 @@
"remark-frontmatter": "^4.0.1", "remark-frontmatter": "^4.0.1",
"remark-smartypants": "^2.0.0", "remark-smartypants": "^2.0.0",
"sharp": "^0.31.1", "sharp": "^0.31.1",
"svg-to-pdfkit": "^0.1.8", "svg-to-pdfkit": "https://github.com/eriese/SVG-to-PDFKit",
"to-vfile": "^7.2.2", "to-vfile": "^7.2.2",
"unist-util-visit": "^4.1.0", "unist-util-visit": "^4.1.0",
"web-worker": "^1.2.0" "web-worker": "^1.2.0"

View file

@ -17814,7 +17814,7 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
sha.js "^2.4.8" sha.js "^2.4.8"
pdfkit@>=0.8.1, pdfkit@^0.13.0: pdfkit@^0.13.0:
version "0.13.0" version "0.13.0"
resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.13.0.tgz#da4c2becd63a129e3aae448fdaed4ee7be790f8f" resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.13.0.tgz#da4c2becd63a129e3aae448fdaed4ee7be790f8f"
integrity sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw== integrity sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw==
@ -22543,12 +22543,9 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
svg-to-pdfkit@^0.1.8: "svg-to-pdfkit@https://github.com/eriese/SVG-to-PDFKit":
version "0.1.8" version "0.1.10"
resolved "https://registry.yarnpkg.com/svg-to-pdfkit/-/svg-to-pdfkit-0.1.8.tgz#5921765922044843f0c1a5b25ec1ef8a4a33b8af" resolved "https://github.com/eriese/SVG-to-PDFKit#2702cbe6b225224c4b5ea25b6a1ee8936cd8cf61"
integrity sha512-QItiGZBy5TstGy+q8mjQTMGRlDDOARXLxH+sgVm1n/LYeo0zFcQlcCh8m4zi8QxctrxB9Kue/lStc/RD5iLadQ==
dependencies:
pdfkit ">=0.8.1"
svgo@^1.0.0: svgo@^1.0.0:
version "1.3.2" version "1.3.2"