1
0
Fork 0

add cutting instructions to title. ensure translation on drafts

This commit is contained in:
Enoch Riese 2023-03-09 08:59:03 -06:00
parent 6f6b3a2b8a
commit bf51065cc8
11 changed files with 88 additions and 66 deletions

View file

@ -182,13 +182,6 @@ function draftCarltonCollar({
paths.seam = paths.saBase.clone().line(points.standTop).close().attr('class', 'fabric') paths.seam = paths.saBase.clone().line(points.standTop).close().attr('class', 'fabric')
if (complete) { if (complete) {
points.title = points.standTopCp.clone()
macro('title', {
at: points.title,
nr: 8,
title: 'collar',
})
// Remove grainline from collarstand part // Remove grainline from collarstand part
delete paths.grainline delete paths.grainline
macro('cutonfold', { macro('cutonfold', {
@ -204,6 +197,13 @@ function draftCarltonCollar({
addCut(2, 'lining') addCut(2, 'lining')
setCutOnFold(false, undefined, 'lining') setCutOnFold(false, undefined, 'lining')
setGrain(defaultGrain + 45, 'lining') setGrain(defaultGrain + 45, 'lining')
points.title = points.standTopCp.clone()
macro('title', {
at: points.title,
nr: 8,
title: 'collar',
})
if (sa) { if (sa) {
paths.sa = paths.saBase.offset(sa) paths.sa = paths.saBase.offset(sa)
paths.sa = paths.sa paths.sa = paths.sa

View file

@ -9,6 +9,7 @@ import cutonfold from './plugins/cutonfold.yaml'
import grainline from './plugins/grainline.yaml' import grainline from './plugins/grainline.yaml'
import scalebox from './plugins/scalebox.yaml' import scalebox from './plugins/scalebox.yaml'
import title from './plugins/title.yaml' import title from './plugins/title.yaml'
import cutlist from './plugins/cutlist/yaml'
const files = { const files = {
brian, brian,
@ -22,6 +23,7 @@ const files = {
grainline, grainline,
scalebox, scalebox,
title, title,
cutlist,
} }
const messages = {} const messages = {}

View file

@ -0,0 +1,7 @@
lmhCanvas: Light to Medium Hair Canvas
fabric: Main Fabric
lining: Lining
cut: Cut
paired: paired
onFoldLower: on the fold
onBias: on the bias

View file

@ -9,6 +9,7 @@ export const plugin = {
['removeCut', removeCut], ['removeCut', removeCut],
['setGrain', setGrain], ['setGrain', setGrain],
['setCutOnFold', setCutOnFold], ['setCutOnFold', setCutOnFold],
['getCutOnFold', getCutOnFold],
], ],
} }
@ -71,3 +72,10 @@ function setCutOnFold(store, partName, p1, p2, material = false) {
return store return store
} }
function getCutOnFold(store, partName, material = false) {
if (!material) return store.get(['cutlist', partName, 'cutOnFold'])
const matFold = store.get(['cutlist', partName, 'materials', material, 'cutOnFold'])
return matFold === undefined ? store.get(['cutlist', partName, 'cutOnFold']) : matFold
}

View file

@ -31,20 +31,17 @@ export const plugin = {
}, },
}, },
macros: { macros: {
title: function (so, { points, scale, locale, store }) { title: function (so, { points, scale, locale, store, part, getCutOnFold }) {
const prefix = so.prefix || '' const prefix = so.prefix || ''
let overwrite = !so.append
// Passing `false` will remove the title // Passing `false` will remove the title
if (so === false) { if (so === false || overwrite) {
for (const id of [ Object.keys(points).forEach((p) => {
`_${prefix}_titleNr`, if (p.startsWith(`_${prefix}_title`) || p === `_${prefix}_exportDate`) delete points[p]
`_${prefix}_titleName`, })
`_${prefix}_titlePattern`,
`_${prefix}_titleFor`, if (so === false) return true
`_${prefix}_exportDate`,
])
delete points[id]
return true
} }
const transform = function (anchor) { const transform = function (anchor) {
@ -53,44 +50,55 @@ export const plugin = {
return `matrix(${so.scale}, 0, 0, ${so.scale}, ${cx}, ${cy}) rotate(${so.rotation} ${anchor.x} ${anchor.y})` return `matrix(${so.scale}, 0, 0, ${so.scale}, ${cx}, ${cy}) rotate(${so.rotation} ${anchor.x} ${anchor.y})`
} }
let shift = 8
const nextPoint = (text, textClass, shiftAmt = shift) => {
const newPoint = so.at.shift(-90 - so.rotation, shiftAmt * so.scale)
newPoint.attr('data-text-transform', transform(newPoint)).addText(text, textClass)
return newPoint
}
const defaults = { const defaults = {
scale: 1, scale: 1,
rotation: 0, rotation: 0,
cutlist: true,
} }
so = { ...defaults, ...so } so = { ...defaults, ...so }
so.scale = so.scale * scale so.scale = so.scale * scale
let overwrite = true
if (so.append) overwrite = false
points[`_${prefix}_titleNr`] = so.at points[`_${prefix}_titleNr`] = so.at
.clone() .clone()
.attr('data-text', so.nr, overwrite) .attr('data-text', so.nr, overwrite)
.attr('data-text-class', 'text-4xl fill-note font-bold') .attr('data-text-class', 'text-4xl fill-note font-bold')
.attr('data-text-transform', transform(so.at)) .attr('data-text-transform', transform(so.at))
let shift = 8
if (so.title) { if (so.title) {
points[`_${prefix}_titleName`] = so.at points[`_${prefix}_titleName`] = nextPoint(so.title, 'text-lg fill-current font-bold')
.shift(-90 - so.rotation, shift * so.scale)
.attr('data-text', so.title)
.attr('data-text-class', 'text-lg fill-current font-bold')
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, 13 * so.scale)))
shift += 8 shift += 8
} }
const partCutlist = store.get(['cutlist', part.name])
if (so.cutlist && partCutlist?.materials) {
for (const material in partCutlist.materials) {
const matCut = partCutlist.materials[material]
const cutPoint = nextPoint('plugin:cut', 'text-md fill-current')
cutPoint.addText(matCut.cut)
if (!matCut.indentical && matCut.cut > 1) cutPoint.addText('plugin:paired')
if (typeof getCutOnFold(material) === 'number') cutPoint.addText('plugin:onFoldLower')
cutPoint.addText('plugin:from').addText('plugin:' + material)
points[`_${prefix}_titleCut_${material}`] = cutPoint
shift += 8
}
}
let name = store.data?.name || 'No Name' let name = store.data?.name || 'No Name'
name = name.replace('@freesewing/', '') name = name.replace('@freesewing/', '')
points[`_${prefix}_titlePattern`] = so.at name += 'v' + (store.data?.version || 'No Version')
.shift(-90 - so.rotation, shift * so.scale) points[`_${prefix}_titlePattern`] = nextPoint(name, 'fill-note')
.attr('data-text', name)
.attr('data-text', 'v' + (store.data?.version || 'No Version'))
.attr('data-text-class', 'fill-note')
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale)))
if (store.data.for) { if (store.data.for) {
shift += 8 shift += 8
points[`_${prefix}_titleFor`] = so.at points[`_${prefix}_titleFor`] = nextPoint(`( ${store.data.for} )`, 'fill-current font-bold')
.shift(-90 - so.rotation, shift * so.scale)
.attr('data-text', '( ' + store.data.for + ' )')
.attr('data-text-class', 'fill-current font-bold')
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale)))
} }
shift += 6 shift += 6
const now = new Date() const now = new Date()
@ -98,20 +106,13 @@ export const plugin = {
let mins = now.getMinutes() let mins = now.getMinutes()
if (hours < 10) hours = `0${hours}` if (hours < 10) hours = `0${hours}`
if (mins < 10) mins = `0${mins}` if (mins < 10) mins = `0${mins}`
points[`_${prefix}_exportDate`] = so.at const exportDate = now.toLocaleDateString(locale || 'en', {
.shift(-90 - so.rotation, shift * so.scale) weekday: 'long',
.attr( year: 'numeric',
'data-text', month: 'short',
now.toLocaleDateString(locale || 'en', { day: 'numeric',
weekday: 'long', })
year: 'numeric', points[`_${prefix}_exportDate`] = nextPoint(`${exportDate}@ ${hours}:${mins}`, 'text-sm')
month: 'short',
day: 'numeric',
})
)
.attr('data-text', `@ ${hours}:${mins}`)
.attr('data-text-class', 'text-sm')
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale)))
}, },
}, },
} }

View file

@ -53,7 +53,7 @@ const XrayText = (props) => (
) )
const TextSpans = ({ point, className = '', style = {}, onClick = null }) => { const TextSpans = ({ point, className = '', style = {}, onClick = null }) => {
const { t } = useTranslation(['app']) const { t } = useTranslation(['plugin'])
let text = [] let text = []
// Handle translation // Handle translation
let translated = '' let translated = ''
@ -117,7 +117,7 @@ const XrayTextOnPath = (props) => (
) )
export const TextOnPath = (props) => { export const TextOnPath = (props) => {
const { t } = useTranslation(['app']) const { t } = useTranslation(['plugin'])
// Handle translation (and spaces) // Handle translation (and spaces)
let translated = '' let translated = ''
for (let string of props.path.attributes.getAsArray('data-text')) { for (let string of props.path.attributes.getAsArray('data-text')) {

View file

@ -1,6 +1,7 @@
import Worker from 'web-worker' import Worker from 'web-worker'
import fileSaver from 'file-saver' import fileSaver from 'file-saver'
import { themePlugin } from '@freesewing/plugin-theme' import { themePlugin } from '@freesewing/plugin-theme'
import { pluginI18n } from '@freesewing/plugin-i18n'
import { pagesPlugin } from '../layout/plugin-layout-part.mjs' import { pagesPlugin } from '../layout/plugin-layout-part.mjs'
import { capitalize } from 'shared/utils.mjs' import { capitalize } from 'shared/utils.mjs'
@ -75,14 +76,7 @@ export const handleExport = async (format, gist, design, t, app, onComplete, onE
// add the theme and translation to the pattern // add the theme and translation to the pattern
pattern.use(themePlugin, { stripped: format !== 'svg', skipGrid: ['pages'] }) pattern.use(themePlugin, { stripped: format !== 'svg', skipGrid: ['pages'] })
pattern.use( pattern.use(pluginI18n, { t })
{
hooks: {
insertText: (locale, text, { t }) => t(text),
},
},
{ t }
)
// a specified size should override the gist one // a specified size should override the gist one
if (format !== 'pdf') { if (format !== 'pdf') {

View file

@ -9,7 +9,7 @@ export const ExportDraft = ({ gist, design, app }) => {
const [error, setError] = useState(false) const [error, setError] = useState(false)
const [format, setFormat] = useState(false) const [format, setFormat] = useState(false)
const { t } = useTranslation(['app']) const { t } = useTranslation(['app', , 'plugin'])
const doExport = (format) => { const doExport = (format) => {
setLink(false) setLink(false)
setError(false) setError(false)

View file

@ -5,6 +5,7 @@ import { fabricPlugin } from '../plugin-layout-part.mjs'
import { cutLayoutPlugin } from './plugin-cut-layout.mjs' import { cutLayoutPlugin } from './plugin-cut-layout.mjs'
import { pluginCutlist } from '@freesewing/plugin-cutlist' import { pluginCutlist } from '@freesewing/plugin-cutlist'
import { pluginFlip } from '@freesewing/plugin-flip' import { pluginFlip } from '@freesewing/plugin-flip'
import { pluginI18n } from '@freesewing/plugin-i18n'
import { measurementAsMm } from 'shared/utils.mjs' import { measurementAsMm } from 'shared/utils.mjs'
import { useEffect } from 'react' import { useEffect } from 'react'
import get from 'lodash.get' import get from 'lodash.get'
@ -22,7 +23,7 @@ const useFabricSettings = (gist) => {
return { activeFabric, sheetWidth, grainDirection, sheetHeight } return { activeFabric, sheetWidth, grainDirection, sheetHeight }
} }
const useFabricDraft = (gist, design, fabricSettings) => { const useFabricDraft = (gist, design, fabricSettings, t) => {
// get the appropriate layout for the view // get the appropriate layout for the view
const layout = const layout =
get(gist, ['layouts', gist._state.view, fabricSettings.activeFabric]) || gist.layout || true get(gist, ['layouts', gist._state.view, fabricSettings.activeFabric]) || gist.layout || true
@ -43,6 +44,8 @@ const useFabricDraft = (gist, design, fabricSettings) => {
// also, pluginCutlist and pluginFlip are needed // also, pluginCutlist and pluginFlip are needed
draft.use(pluginCutlist) draft.use(pluginCutlist)
draft.use(pluginFlip) draft.use(pluginFlip)
// add translation
draft.use(pluginI18n, { t })
// draft the pattern // draft the pattern
draft.draft() draft.draft()
@ -77,7 +80,7 @@ export const CutLayout = (props) => {
}) })
const fabricSettings = useFabricSettings(gist) const fabricSettings = useFabricSettings(gist)
const { draft, patternProps } = useFabricDraft(gist, design, fabricSettings) const { draft, patternProps } = useFabricDraft(gist, design, fabricSettings, t)
const fabricList = useFabricList(draft) const fabricList = useFabricList(draft)
const setCutFabric = (newFabric) => { const setCutFabric = (newFabric) => {

View file

@ -15,7 +15,7 @@ export const PrintLayout = (props) => {
if (props.gist?._state?.xray?.enabled) props.updateGist(['_state', 'xray', 'enabled'], false) if (props.gist?._state?.xray?.enabled) props.updateGist(['_state', 'xray', 'enabled'], false)
}) })
const { t } = useTranslation(['workbench']) const { t } = useTranslation(['workbench', 'plugin'])
const [error, setError] = useState(false) const [error, setError] = useState(false)
const draft = props.draft const draft = props.draft

View file

@ -1,8 +1,10 @@
// Hooks // Hooks
import { useEffect, useState, useMemo } from 'react' import { useEffect, useState, useMemo } from 'react'
import { useGist } from 'shared/hooks/useGist' import { useGist } from 'shared/hooks/useGist'
import { useTranslation } from 'next-i18next'
// Dependencies // Dependencies
import { pluginTheme } from '@freesewing/plugin-theme' import { pluginTheme } from '@freesewing/plugin-theme'
import { pluginI18n } from '@freeSewing/plugin-i18n'
import { preloaders } from 'shared/components/workbench/preloaders.mjs' import { preloaders } from 'shared/components/workbench/preloaders.mjs'
// Components // Components
import { WorkbenchMenu } from 'shared/components/workbench/menu/index.mjs' import { WorkbenchMenu } from 'shared/components/workbench/menu/index.mjs'
@ -70,6 +72,8 @@ export const WorkbenchWrapper = ({
const [messages, setMessages] = useState([]) const [messages, setMessages] = useState([])
const [popup, setPopup] = useState(false) const [popup, setPopup] = useState(false)
const [preloaded, setPreloaded] = useState(false) const [preloaded, setPreloaded] = useState(false)
// we'll only use this if the renderer is svg, but we can't call hooks conditionally
const { t } = useTranslation(['plugin'])
// We'll use this in more than one location // We'll use this in more than one location
const hasRequiredMeasurements = hasRequiredMeasurementsMethod(design, gist) const hasRequiredMeasurements = hasRequiredMeasurementsMethod(design, gist)
@ -128,7 +132,10 @@ export const WorkbenchWrapper = ({
//draft.__init() //draft.__init()
// add theme to svg renderer // add theme to svg renderer
if (gist.renderer === 'svg') draft.use(pluginTheme, { skipGrid: ['pages'] }) if (gist.renderer === 'svg') {
draft.use(pluginI18n, { t })
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 {