diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 35595ae3f5b..d263835ef8e 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -369,29 +369,38 @@ export const generatePartTransform = (x, y, rotate, flipX, flipY, part) => { let scaleX = 1 let scaleY = 1 + // move the part an additional offset so it ends up in the correct spot after flipping. + // it will scale around the part's 0, 0, which isn't always the top left, so we need to move it over so that 0,0 lines up with topRight + topLeft if (flipX) { + xTotal += part.topLeft.x + xTotal += part.bottomRight.x + // reverse the x scale scaleX = -1 - xTotal += part.topLeft.x * 2 + part.width } if (flipY) { + yTotal += part.topLeft.y + yTotal += part.bottomRight.y scaleY = -1 - yTotal += part.topLeft.y * 2 + part.height } + // add the scaling to the transforms if (scaleX + scaleY < 2) { transforms.push(`scale(${scaleX} ${scaleY})`) } if (rotate) { + // we can put the center as the rotation origin, so get the center const center = { x: part.topLeft.x + part.width/2, y: part.topLeft.y + part.height/2, } + // add the rotation around the center to the transforms transforms.push(`rotate(${rotate} ${center.x} ${center.y})`) } - if (xTotal > 0 || yTotal > 0) transforms.unshift( + // put the translation before any other transforms to avoid having to make complex calculations once the matrix has been rotated or scaled + if (xTotal !== 0 || yTotal !== 0) transforms.unshift( `translate(${xTotal} ${yTotal})` ) diff --git a/packages/i18n/src/next.mjs b/packages/i18n/src/next.mjs index d50f2500eb6..3d42d9ab1c9 100644 --- a/packages/i18n/src/next.mjs +++ b/packages/i18n/src/next.mjs @@ -7,20 +7,17 @@ import enNamespaces from "./next/en/index.mjs" import esNamespaces from "./next/es/index.mjs" import frNamespaces from "./next/fr/index.mjs" import nlNamespaces from "./next/nl/index.mjs" -import ukNamespaces from "./next/uk/index.mjs" export const de = deNamespaces export const en = enNamespaces export const es = esNamespaces export const fr = frNamespaces export const nl = nlNamespaces -export const uk = ukNamespaces export const languages = { de: "Deutsch", en: "English", es: "Español", fr: "Français", - nl: "Nederlands", - uk: "undefined" + nl: "Nederlands" } diff --git a/packages/i18n/src/next/de/settings.mjs b/packages/i18n/src/next/de/settings.mjs index 2096696c4cb..58f243dbaaa 100644 --- a/packages/i18n/src/next/de/settings.mjs +++ b/packages/i18n/src/next/de/settings.mjs @@ -7,6 +7,8 @@ const settings = { "advanced.d": "Legt fest, ob erweiterte Einstellungen und Schnittmusteroptionen angezeigt werden sollen oder nicht", "paperless.t": "Papierlos", "paperless.d": "Zeichnet ein Schnittmuster mit allen benötigten Dimensionen, sodass es direkt auf den Stoff oder ein anderes Medium übertragen werden kann, ohne es auszudrucken", + "sabool.t": "Include seam allowance", + "sabool.d": "Controls whether or not to include seam allowance in your pattern", "sa.t": "Nahtzugabe", "sa.d": "Steuert die Breite der Nahtzugabe, die in deinem Schnittmuster enthalten ist", "locale.t": "Sprache", diff --git a/packages/i18n/src/next/en/settings.mjs b/packages/i18n/src/next/en/settings.mjs index 33a8c24fbe9..9023120766e 100644 --- a/packages/i18n/src/next/en/settings.mjs +++ b/packages/i18n/src/next/en/settings.mjs @@ -7,7 +7,9 @@ const settings = { "advanced.d": "Controls whether or not to display advanced settings and pattern options", "paperless.t": "Paperless", "paperless.d": "Drafts a pattern with all dimensions included so you can transfer it on fabric or another medium without the need to print", - "sa.t": "Seam allowance", + "sabool.t": "Include seam allowance", + "sabool.d": "Controls whether or not to include seam allowance in your pattern", + "sa.t": "Seam allowance size", "sa.d": "Controls the amount of seam allowance included in your pattern", "locale.t": "Language", "locale.d": "Determines the language used on your pattern", diff --git a/packages/i18n/src/next/es/settings.mjs b/packages/i18n/src/next/es/settings.mjs index 7ed04155375..dab413ca7b5 100644 --- a/packages/i18n/src/next/es/settings.mjs +++ b/packages/i18n/src/next/es/settings.mjs @@ -7,6 +7,8 @@ const settings = { "advanced.d": "Controla si mostrar o no la configuración avanzada y las opciones de patrón", "paperless.t": "Sin papel", "paperless.d": "Dibuja un patrón con todas las dimensiones incluidas para que puedas transferirlo sobre tela u otro medio sin la necesidad de imprimir", + "sabool.t": "Include seam allowance", + "sabool.d": "Controls whether or not to include seam allowance in your pattern", "sa.t": "Margen de costura", "sa.d": "Controla la cantidad de margen de costura incluido en tu patrón", "locale.t": "Idioma", diff --git a/packages/i18n/src/next/fr/settings.mjs b/packages/i18n/src/next/fr/settings.mjs index 598bc554577..a45c17dbb18 100644 --- a/packages/i18n/src/next/fr/settings.mjs +++ b/packages/i18n/src/next/fr/settings.mjs @@ -7,6 +7,8 @@ const settings = { "advanced.d": "Permet d'afficher ou non les paramètres avancés et les options de patron", "paperless.t": "Sans papier", "paperless.d": "Dessine un patron avec toutes les dimensions incluses afin que vous puissiez le transférer sur du tissu ou un autre support sans avoir à imprimer", + "sabool.t": "Include seam allowance", + "sabool.d": "Controls whether or not to include seam allowance in your pattern", "sa.t": "Marge de couture", "sa.d": "Contrôle la valeur de la marge de couture incluse dans votre patron", "locale.t": "Langue", diff --git a/packages/i18n/src/next/nl/settings.mjs b/packages/i18n/src/next/nl/settings.mjs index ac49d73aaa8..766afd549dc 100644 --- a/packages/i18n/src/next/nl/settings.mjs +++ b/packages/i18n/src/next/nl/settings.mjs @@ -7,6 +7,8 @@ const settings = { "advanced.d": "Bepaalt of de geavanceerde patroonopties wel of niet getoond worden", "paperless.t": "Papierloos", "paperless.d": "Hiermee tekent u een patroon met alle afmetingen zodat u het op stof of een ander medium kunt overbrengen zonder dat u het hoeft af te drukken", + "sabool.t": "Include seam allowance", + "sabool.d": "Controls whether or not to include seam allowance in your pattern", "sa.t": "Naadtoeslag", "sa.d": "Bepaalt de hoeveelheid naadtoeslag die is inbegrepen in uw patroon", "locale.t": "Taal", diff --git a/sites/shared/components/workbench/layout/draft/index.js b/sites/shared/components/workbench/layout/draft/index.js index 8cbe6efe4e6..f8892e30cd1 100644 --- a/sites/shared/components/workbench/layout/draft/index.js +++ b/sites/shared/components/workbench/layout/draft/index.js @@ -5,9 +5,15 @@ import Part from './part' import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch" const Draft = props => { - const { patternProps, gist, updateGist, app, bgProps={}, fitLayoutPart = false, layoutType="printLayout"} = props + const { draft, patternProps, gist, updateGist, app, bgProps={}, fitLayoutPart = false, layoutType="printingLayout"} = props + + // keep a fresh copy of the layout because we might manipulate it without saving to the gist + let layout = draft.settings.layout === true ? { + ...patternProps.autoLayout, + width: patternProps.width, + height: patternProps.height + } : {...draft.settings.layout} - let layout = {...props.layout} const svgRef = useRef(null); if (!patternProps) return null @@ -43,7 +49,7 @@ const Draft = props => { if (history) { updateGist(['layouts', layoutType], newLayout, history) } else { - // we don't put it in the gist if it shouldn't contribute to history because we need some the data calculated here for rendering purposes on the initial layout, but we don't want to actually save a layout until the user manipulates it + // we don't put it in the gist if it shouldn't contribute to history because we need some of the data calculated here for rendering purposes on the initial layout, but we don't want to actually save a layout until the user manipulates it. This is what allows the layout to respond appropriately to settings changes. Once the user has starting playing with the layout, all bets are off layout = newLayout } } diff --git a/sites/shared/components/workbench/layout/draft/part.js b/sites/shared/components/workbench/layout/draft/part.js index 4cbd76ad0a8..7be92990015 100644 --- a/sites/shared/components/workbench/layout/draft/part.js +++ b/sites/shared/components/workbench/layout/draft/part.js @@ -70,6 +70,7 @@ const Part = props => { // update the layout on mount useEffect(() => { + // only update if there's a rendered part and it's not the pages or fabric part if (partRef.current && !props.isLayoutPart) { updateLayout(false) } @@ -77,6 +78,7 @@ const Part = props => { // Initialize drag handler useEffect(() => { + // don't drag the pages if (props.isLayoutPart) return handleDrag(select(partRef.current)) }, [rotate, partRef, partLayout]) @@ -124,6 +126,7 @@ const Part = props => { if (rotate) { let newRotation = getRotation(event); + // shift key to snap the rotation if (event.sourceEvent.shiftKey) { newRotation = Math.ceil(newRotation/15) * 15 } @@ -138,41 +141,53 @@ const Part = props => { translateY = event.y } + // a drag happened, so we should update the layout when we're done didDrag = true; setTransforms() }) .on('end', function(event) { - // save to gist + // save to gist if anything actually changed if (didDrag) updateLayout() didDrag = false }) + /** reset the part's transforms */ const resetPart = (event) => { rotation = 0 flipX = 0 flipY = 0 updateLayout() } + + /** toggle between dragging and rotating */ const toggleDragRotate = () => { + // only respond if the part should be able to drag/rotate if (!partRef.current || props.isLayoutPart) {return} - updateLayout() + setRotate(!rotate) } + /** update the layout either locally or in the gist */ const updateLayout = (history=true) => { + /** don't mess with what we don't lay out */ if (!partRef.current || props.isLayoutPart) return + // set the transforms on the part in order to calculate from the latest position setTransforms() + + // get the bounding box and the svg's current transform matrix const partRect = innerRef.current.getBoundingClientRect(); const matrix = innerRef.current.ownerSVGElement.getScreenCTM().inverse(); + // a function to convert dom space to svg space const domToSvg = (point) => DOMPointReadOnly.fromPoint(point).matrixTransform(matrix) // include the new top left and bottom right to ease calculating the pattern width and height const tl = domToSvg({x: partRect.left, y: partRect.top}); const br = domToSvg({x: partRect.right, y: props.isLayoutPart ? 0 : partRect.bottom}); + // update it on the draft component props.updateLayout(partName, { move: { x: translateX, @@ -186,13 +201,14 @@ const Part = props => { }, history) } - // Method to flip (mirror) the part along the X or Y axis + /** Method to flip (mirror) the part along the X or Y axis */ const flip = axis => { if (axis === 'x') flipX = !flipX else flipY = !flipY updateLayout() } + /** method to rotate 90 degrees */ const rotate90 = (direction = 1) => { if (flipX) direction *= -1 if (flipY) direction *= -1 @@ -202,6 +218,7 @@ const Part = props => { updateLayout() } + // don't render if the part is empty if (Object.keys(part.snippets).length === 0 && Object.keys(part.paths).length === 0) return null; return ( diff --git a/sites/shared/components/workbench/layout/print/index.js b/sites/shared/components/workbench/layout/print/index.js index 069404604fa..e26dea3c79b 100644 --- a/sites/shared/components/workbench/layout/print/index.js +++ b/sites/shared/components/workbench/layout/print/index.js @@ -1,10 +1,11 @@ -import { useEffect, useRef } from 'react' +import { useEffect } from 'react' import { useTranslation } from 'next-i18next' import Settings from './settings' import Draft from '../draft/index' import pluginBuilder from './plugin' const PrintLayout = props => { + // disable xray useEffect(() => { if (props.gist?._state?.xray?.enabled) props.updateGist( ['_state', 'xray', 'enabled'], @@ -15,20 +16,18 @@ const PrintLayout = props => { const { t } = useTranslation(['workbench']) const draft = props.draft + // add the pages plugin to the draft draft.use(pluginBuilder( props.gist?._state?.layout?.forPrinting?.page?.size, props.gist?._state?.layout?.forPrinting?.page?.orientation, )) + let patternProps let layout try { + // draft the pattern draft.draft() patternProps = draft.getRenderProps() - layout = draft.settings.layout === true ? { - ...patternProps.autoLayout, - width: patternProps.width, - height: patternProps.height - } : draft.settings.layout } catch(err) { console.log(err, props.gist) } @@ -54,7 +53,6 @@ const PrintLayout = props => { bgProps={bgProps} gistReady={props.gistReady} layoutPart="pages" - layout={layout} /> ) diff --git a/sites/shared/components/workbench/layout/print/settings.js b/sites/shared/components/workbench/layout/print/settings.js index b58c03f9324..9fe7a6cc7a4 100644 --- a/sites/shared/components/workbench/layout/print/settings.js +++ b/sites/shared/components/workbench/layout/print/settings.js @@ -26,7 +26,7 @@ const PrintLayoutSettings = props => {